Page MenuHomeFreeBSD

D36924.diff
No OneTemporary

D36924.diff

diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h
--- a/sys/dev/nvme/nvme_private.h
+++ b/sys/dev/nvme/nvme_private.h
@@ -168,6 +168,7 @@
sbintime_t deadline;
bool timer_armed;
enum nvme_recovery recovery_state;
+ uint32_t in_isr;
uint32_t num_entries;
uint32_t num_trackers;
diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c
--- a/sys/dev/nvme/nvme_qpair.c
+++ b/sys/dev/nvme/nvme_qpair.c
@@ -538,6 +538,19 @@
int done = 0;
bool in_panic = dumping || SCHEDULER_STOPPED();
+ /*
+ * If we're not panicing, make sure we're the only one here. If we are
+ * panicing, then we need to poll and we know we're the only thread
+ * that's running, so its safe since we cope with re-entering this
+ * routine in that case already (since the other thread in that routine
+ * won't be scheduled again). This protects the hardware completion
+ * queue to ensure that there's only one reader of it at any given time.
+ */
+ if (__predict_true(!in_panic)) {
+ if (!atomic_cmpset_32(&qpair->in_isr, 0, 1))
+ return (false);
+ }
+
/*
* qpair is not enabled, likely because a controller reset is in
* progress. Ignore the interrupt - any I/O that was associated with
@@ -548,6 +561,7 @@
*/
if (qpair->recovery_state != RECOVERY_NONE) {
qpair->num_ignored++;
+ atomic_store_32(&qpair->in_isr, 0);
return (false);
}
@@ -673,6 +687,7 @@
qpair->cq_hdbl_off, qpair->cq_head);
}
+ atomic_store_32(&qpair->in_isr, 0);
return (done != 0);
}

File Metadata

Mime Type
text/plain
Expires
Thu, May 1, 8:09 PM (15 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17890038
Default Alt Text
D36924.diff (1 KB)

Event Timeline