Linux CXL
 help / color / mirror / Atom feed
* Fix infinite loop when draining a stuck event log
@ 2026-08-26 18:43 Anisa Su
  2026-08-26 18:43 ` [PATCH 1/1] cxl/events: Bound the event log drain loop Anisa Su
  0 siblings, 1 reply; 5+ messages in thread
From: Anisa Su @ 2026-08-26 18:43 UTC (permalink / raw)
  To: linux-cxl
  Cc: Davidlohr Bueso, Jonathan Cameron, Gregory Price, Dave Jiang,
	Alison Schofield, Vishal Verma, Anisa Su

Based on the 7.2 tag.

While testing the DCD patchset on a real device, I encountered a scenario where
bit 4 of the Event Status Register, corresponding to the DC Event Log
(CXL r4.0 8.2.9.3.1 Table 8-203) is not cleared by the device after a DC event is
handled and the Clear Event Records (0x0101) command is sent.

This causes cxl_event_thread() to spin in an infinite loop because cxl_event_thread()
drains every log in the Event Status register and repeats until that register reads zero.
So the thread ends up resending infinite Get Event Records (0x0100) as fast as
the mailbox completes, even though the event log remains empty.

Although I encountered this specifically while testing DCD, this would apply
equally to other types of events (Informational, Warning, Failure, Fatal).

This patch bounds the loop on there being > 0 event records in the event
log. cxl_mem_get_records_log() and cxl_mem_get_event_records() now report failures
and which logs returned records; the thread stops on the first error and
drops any log whose status bit was set while it returned nothing. Every pass
either drains a record or clears a bit from a five-bit mask, so exiting the loop
no longer depends only on the status bit reported by the device. 
Logs are drained best effort so a broken one cannot suppress reporting from the rest.


Testing:

ndctl's cxl suite (pmem/ndctl pending, 02754b5) against cxl_test on
v7.2 plus this patch, 15 passed / 2 skipped / 0 failed.  

On HW:
Without the fix, we see an infinite loop:

[  452.430234] cxl_pci 0000:0b:00.0: DBG drain_mask: native_cxl_error=0 dcd_supported=1 mask=0x10
[  452.430248] cxl_pci 0000:0b:00.0: DBG event_thread: enter irq=236 mask=0x10
[  452.430254] cxl_pci 0000:0b:00.0: DBG event_thread: status=0x10 masked=0x10
^ Host receives DC interrupt

[  452.430258] cxl_pci 0000:0b:00.0: DBG get_event_records: status=0x10 dcd_supported=1
[  452.430262] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 size_out=1024
[  452.430268] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x100 size_in=1 doorbell_busy=0
[  452.430274] cxl_pci 0000:0b:00.0: Sending command: 0x0100
[  452.430309] cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
[  452.430313] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x100 doorbell cleared, dev rc=0
[  452.430345] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 nr_rec=1 flags=0x0
^ Get Event Record retrieves DC Add Event from event log

[  452.430355] cxl_pci 0000:0b:00.0: DCD event add : DPA:0x0 LEN:0x80000000
[  452.430363] cxl_pci 0000:0b:00.0: DC extent DPA [range 0x0000000000000000-0x000000007fffffff] (DCR:[range 0x0000000000000000-0x0000001fffffffff])(e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430374] cxl_pci 0000:0b:00.0: DC extent DPA [range 0x0000000000000000-0x000000007fffffff] (DCR:[range 0x0000000000000000-0x0000001fffffffff])(e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430381] cxl_pci 0000:0b:00.0: DC extent DPA [range 0x0000000000000000-0x000000007fffffff] (DCR:[range 0x0000000000000000-0x0000001fffffffff])(e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430390] cxl decoder9.0: dpa:0x0 mapped in region:region0
[  452.430397] cxl decoder9.0: Add extent [range 0x0000000000000000-0x000000007fffffff] (e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430403] cxl_dax_region dax_region0: Alloc new tag group
[  452.430437]  extent0.1: dc_extent HPA [range 0x0000000000000000-0x000000007fffffff] (e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430444] cxl_dax_region dax_region0: Trying notify: type 0 tag e5407b12-9a68-4c31-8d5e-2f0916bd73a4
[  452.430449] cxl_dax_region dax_region0: Notify: type 0 tag e5407b12-9a68-4c31-8d5e-2f0916bd73a4
^ DC Add Event handled

[  452.430473] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x4802 size_in=32 doorbell_busy=0
[  452.430482] cxl_pci 0000:0b:00.0: Sending command: 0x4802
[  452.430658] cxl_pci 0000:0b:00.0: Doorbell wait took 1ms
[  452.430662] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x4802 doorbell cleared, dev rc=0
^ DC Add Response sent

[  452.430669] cxl_pci 0000:0b:00.0: Event log '4': Clearing 1
[  452.430674] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x101 size_in=8 doorbell_busy=0
[  452.430679] cxl_pci 0000:0b:00.0: Sending command: 0x0101
[  452.430705] cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
[  452.430708] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x101 doorbell cleared, dev rc=0
[  452.430712] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 cleared 1 recs rc=0
[  452.430717] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 size_out=1024
^ Clear Event Records succeeds

Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Reading event logs: 10
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Sending command: 0x0100
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: DCD event add : DPA:0x0 LEN:0x80000000
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: DC extent DPA [range 0x0000000000000000-0x000000007fffffff] (DCR:[range 0x0000000000000000-0x0000001fffffffff])(e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: DC extent DPA [range 0x0000000000000000-0x000000007fffffff] (DCR:[range 0x0000000000000000-0x0000001fffffffff])(e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: DC extent DPA [range 0x0000000000000000-0x000000007fffffff] (DCR:[range 0x0000000000000000-0x0000001fffffffff])(e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
Aug 26 06:30:56 cxlqual kernel: cxl decoder9.0: dpa:0x0 mapped in region:region0
Aug 26 06:30:56 cxlqual kernel: cxl decoder9.0: Add extent [range 0x0000000000000000-0x000000007fffffff] (e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
Aug 26 06:30:56 cxlqual kernel: cxl_dax_region dax_region0: Alloc new tag group
Aug 26 06:30:56 cxlqual kernel:  extent0.1: dc_extent HPA [range 0x0000000000000000-0x000000007fffffff] (e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
Aug 26 06:30:56 cxlqual kernel: cxl_dax_region dax_region0: Trying notify: type 0 tag e5407b12-9a68-4c31-8d5e-2f0916bd73a4
Aug 26 06:30:56 cxlqual kernel: cxl_dax_region dax_region0: Notify: type 0 tag e5407b12-9a68-4c31-8d5e-2f0916bd73a4
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Sending command: 0x4802
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
^ DC Add Response succeeds

Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Event log '4': Clearing 1
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Sending command: 0x0101
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Doorbell wait took 1ms
^ Clear Event Records succeeds

Then loops infinitely:
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Sending command: 0x0100
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Reading event logs: 10
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Sending command: 0x0100
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Reading event logs: 10
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Sending command: 0x0100
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Reading event logs: 10
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Sending command: 0x0100
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Reading event logs: 10
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Sending command: 0x0100
Aug 26 06:30:56 cxlqual kernel: cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
...

To determine the cause, I added print statements to check the status bit and saw:

[  452.430753] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x100 doorbell cleared, dev rc=0
[  452.430764] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 nr_rec=0 flags=0x0
^ ---
nr_rec = 0, so the event log is empty

[  452.430768] cxl_pci 0000:0b:00.0: DBG get_event_records: status=0x10 drained=1 ret=0
^ ---
But the status bit = 0x10, which is the lower 4th bit of the Event Status Register,
corresponding to the Dynamic Capacity Event Log

With the patch (the extra dbg messages are not in this patch, they're just for verifying
the fix):

[  452.430234] cxl_pci 0000:0b:00.0: DBG drain_mask: native_cxl_error=0 dcd_supported=1 mask=0x10
[  452.430248] cxl_pci 0000:0b:00.0: DBG event_thread: enter irq=236 mask=0x10
[  452.430254] cxl_pci 0000:0b:00.0: DBG event_thread: status=0x10 masked=0x10
[  452.430258] cxl_pci 0000:0b:00.0: DBG get_event_records: status=0x10 dcd_supported=1
[  452.430262] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 size_out=1024
[  452.430268] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x100 size_in=1 doorbell_busy=0
[  452.430274] cxl_pci 0000:0b:00.0: Sending command: 0x0100
[  452.430309] cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
[  452.430313] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x100 doorbell cleared, dev rc=0
[  452.430345] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 nr_rec=1 flags=0x0
[  452.430355] cxl_pci 0000:0b:00.0: DCD event add : DPA:0x0 LEN:0x80000000
[  452.430363] cxl_pci 0000:0b:00.0: DC extent DPA [range 0x0000000000000000-0x000000007fffffff] (DCR:[range 0x0000000000000000-0x0000001fffffffff])(e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430374] cxl_pci 0000:0b:00.0: DC extent DPA [range 0x0000000000000000-0x000000007fffffff] (DCR:[range 0x0000000000000000-0x0000001fffffffff])(e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430381] cxl_pci 0000:0b:00.0: DC extent DPA [range 0x0000000000000000-0x000000007fffffff] (DCR:[range 0x0000000000000000-0x0000001fffffffff])(e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430390] cxl decoder9.0: dpa:0x0 mapped in region:region0
[  452.430397] cxl decoder9.0: Add extent [range 0x0000000000000000-0x000000007fffffff] (e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430403] cxl_dax_region dax_region0: Alloc new tag group
[  452.430437]  extent0.1: dc_extent HPA [range 0x0000000000000000-0x000000007fffffff] (e5407b12-9a68-4c31-8d5e-2f0916bd73a4)
[  452.430444] cxl_dax_region dax_region0: Trying notify: type 0 tag e5407b12-9a68-4c31-8d5e-2f0916bd73a4
[  452.430449] cxl_dax_region dax_region0: Notify: type 0 tag e5407b12-9a68-4c31-8d5e-2f0916bd73a4
[  452.430473] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x4802 size_in=32 doorbell_busy=0
[  452.430482] cxl_pci 0000:0b:00.0: Sending command: 0x4802
[  452.430658] cxl_pci 0000:0b:00.0: Doorbell wait took 1ms
[  452.430662] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x4802 doorbell cleared, dev rc=0
[  452.430669] cxl_pci 0000:0b:00.0: Event log '4': Clearing 1
[  452.430674] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x101 size_in=8 doorbell_busy=0
[  452.430679] cxl_pci 0000:0b:00.0: Sending command: 0x0101
[  452.430705] cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
[  452.430708] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x101 doorbell cleared, dev rc=0
[  452.430712] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 cleared 1 recs rc=0
[  452.430717] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 size_out=1024
[  452.430721] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x100 size_in=1 doorbell_busy=0
[  452.430725] cxl_pci 0000:0b:00.0: Sending command: 0x0100
[  452.430749] cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
[  452.430753] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x100 doorbell cleared, dev rc=0
[  452.430764] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 nr_rec=0 flags=0x0
[  452.430768] cxl_pci 0000:0b:00.0: DBG get_event_records: status=0x10 drained=1 ret=0
[  452.430772] cxl_pci 0000:0b:00.0: DBG event_thread: drain status=0x10 drained=1 rc=0
[  452.430777] cxl_pci 0000:0b:00.0: DBG event_thread: status=0x10 masked=0x10
[  452.430781] cxl_pci 0000:0b:00.0: DBG get_event_records: status=0x10 dcd_supported=1
[  452.430784] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 size_out=1024
[  452.430788] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x100 size_in=1 doorbell_busy=0
[  452.430794] cxl_pci 0000:0b:00.0: Sending command: 0x0100
[  452.430820] cxl_pci 0000:0b:00.0: Doorbell wait took 0ms
[  452.430823] cxl_pci 0000:0b:00.0: DBG mbox: opcode=0x100 doorbell cleared, dev rc=0
[  452.430833] cxl_pci 0000:0b:00.0: DBG get_records_log: type=4 nr_rec=0 flags=0x0
[  452.430837] cxl_pci 0000:0b:00.0: DBG get_event_records: status=0x10 drained=0 ret=0
[  452.430840] cxl_pci 0000:0b:00.0: DBG event_thread: drain status=0x10 drained=0 rc=0
[  452.430844] cxl_pci 0000:0b:00.0: Event status 0x10 set with no records to read

^ --- detected that the status bit was set but the event log is empty and stops here


Anisa Su (1):
  cxl/events: Bound the event log drain loop

 drivers/cxl/core/mbox.c      | 58 ++++++++++++++++++++++++++++--------
 drivers/cxl/cxlmem.h         |  3 +-
 drivers/cxl/pci.c            | 39 +++++++++++++++++++-----
 tools/testing/cxl/test/mem.c |  4 +--
 4 files changed, 81 insertions(+), 23 deletions(-)


base-commit: 8d3ae59288f1e7d58d76558a6ee96d533bc5019f
-- 
2.43.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-08-27  3:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-26 18:43 Fix infinite loop when draining a stuck event log Anisa Su
2026-08-26 18:43 ` [PATCH 1/1] cxl/events: Bound the event log drain loop Anisa Su
2026-08-26 18:57   ` sashiko-bot
2026-08-26 21:28   ` Cheatham, Benjamin
2026-08-27  3:01   ` Richard Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox