Page MenuHomeFreeBSD

D32259.id96105.diff
No OneTemporary

D32259.id96105.diff

Index: sys/dev/nvme/nvme_ctrlr.c
===================================================================
--- sys/dev/nvme/nvme_ctrlr.c
+++ sys/dev/nvme/nvme_ctrlr.c
@@ -263,6 +263,7 @@
static int
nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr, int desired_val)
{
+ int sanity2 = TICKS_2_USEC(1);
int timeout = ticks + MSEC_2_TICKS(ctrlr->ready_timeout_in_ms);
uint32_t csts;
@@ -278,7 +279,18 @@
"within %d ms\n", desired_val, ctrlr->ready_timeout_in_ms);
return (ENXIO);
}
- pause("nvmerdy", 1);
+
+ /*
+ * Adatively spin for the first tick. Many cards will be ready
+ * in less than a tick, especially when hz == 100, as is common
+ * for VMs.
+ */
+ if (sanity2 == 0) {
+ pause("nvmerdy", 1);
+ } else {
+ sanity2--;
+ DELAY(1);
+ }
}
return (0);
Index: sys/dev/nvme/nvme_private.h
===================================================================
--- sys/dev/nvme/nvme_private.h
+++ sys/dev/nvme/nvme_private.h
@@ -455,21 +455,28 @@
int nvme_detach(device_t dev);
/*
- * Wait for a command to complete using the nvme_completion_poll_cb.
- * Used in limited contexts where the caller knows it's OK to block
- * briefly while the command runs. The ISR will run the callback which
- * will set status->done to true, usually within microseconds. If not,
- * then after one second timeout handler should reset the controller
- * and abort all outstanding requests including this polled one. If
- * still not after ten seconds, then something is wrong with the driver,
- * and panic is the only way to recover.
+ * Wait for a command to complete using the nvme_completion_poll_cb. Used in
+ * limited contexts where the caller knows it's OK to block briefly while the
+ * command runs. The ISR will run the callback which will set status->done to
+ * true, usually within microseconds. If not, then after one second timeout
+ * handler should reset the controller and abort all outstanding requests
+ * including this polled one. If still not after ten seconds, then something is
+ * wrong with the driver, and panic is the only way to recover.
+ *
+ * Most commands using this interface aren't actual I/O to the drive's media so
+ * complete within a few microseconds. Adaptively spin for one tick to catch the
+ * vast majority of these without waiting for a tick plus scheduling delays. Since
+ * these are on startup, this drastically reduces startup time.
*/
static __inline
void
nvme_completion_poll(struct nvme_completion_poll_status *status)
{
int sanity = hz * 10;
+ int sanity2 = TICKS_2_USEC(1);
+ while (!atomic_load_acq_int(&status->done) && --sanity2 > 0)
+ DELAY(1);
while (!atomic_load_acq_int(&status->done) && --sanity > 0)
pause("nvme", 1);
if (sanity <= 0)

File Metadata

Mime Type
text/plain
Expires
Mon, Jun 15, 6:06 AM (20 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33964588
Default Alt Text
D32259.id96105.diff (2 KB)

Event Timeline