Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F170073457
D59155.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D59155.diff
View Options
diff --git a/share/man/man4/nvme.4 b/share/man/man4/nvme.4
--- a/share/man/man4/nvme.4
+++ b/share/man/man4/nvme.4
@@ -31,7 +31,7 @@
.\"
.\" Author: Jim Harris <jimharris@FreeBSD.org>
.\"
-.Dd August 27, 2026
+.Dd September 1, 2026
.Dt NVME 4
.Os
.Sh NAME
@@ -48,6 +48,7 @@
.Cd hw.nvme.min_cpus_per_ioq= Ns Aq Ar X
.Cd hw.nvme.force_intx= Ns Ar 1
.Cd hw.nvme.hmb_max
+.Cd hw.nvme.arb_burst= Ns Aq Ar X
.Cd hw.nvme.apst_enable= Ns Ar 1
.Cd hw.nvme.apst_data
.Cd hw.nvme.use_nvd= Ns Ar 0
@@ -166,6 +167,12 @@
Control maximum amount of system RAM in bytes
to use as Host Memory Buffer for capable devices.
The default value is 5% of physical memory size per device.
+.It Va hw.nvme.arb_burst=X
+Override the arbitration burst,
+which is otherwise programmed from the controller's recommendation
+when it publishes one.
+Values 0 through 6 request a burst of 2^X commands and 7 requests no
+limit; -1, the default, follows the controller's recommendation.
.It Va hw.nvme.apst_enable=1
Enable Autonomous Power State Transition
.Pq APST .
diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h
--- a/sys/dev/nvme/nvme.h
+++ b/sys/dev/nvme/nvme.h
@@ -249,6 +249,17 @@
#define NVME_QPRIO_MEDIUM (2)
#define NVME_QPRIO_LOW (3)
+/* Arbitration feature, cdw11 */
+#define NVME_ARB_AB_SHIFT (0)
+#define NVME_ARB_AB_MASK (0x7)
+#define NVME_ARB_AB_NO_LIMIT (0x7)
+#define NVME_ARB_LPW_SHIFT (8)
+#define NVME_ARB_LPW_MASK (0xFF)
+#define NVME_ARB_MPW_SHIFT (16)
+#define NVME_ARB_MPW_MASK (0xFF)
+#define NVME_ARB_HPW_SHIFT (24)
+#define NVME_ARB_HPW_MASK (0xFF)
+
#define NVME_STATUS_P_SHIFT (0)
#define NVME_STATUS_P_MASK (0x1)
#define NVME_STATUS_SC_SHIFT (1)
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -876,6 +876,43 @@
free(data, M_NVME);
}
+static void
+nvme_ctrlr_arbitration_done(void *arg, const struct nvme_completion *cpl)
+{
+ struct nvme_controller *ctrlr = arg;
+
+ if (nvme_completion_is_error(cpl))
+ nvme_printf(ctrlr, "setting arbitration burst failed\n");
+}
+
+static void
+nvme_ctrlr_configure_arbitration(struct nvme_controller *ctrlr)
+{
+ int burst;
+
+ burst = -1;
+ TUNABLE_INT_FETCH("hw.nvme.arb_burst", &burst);
+ if (burst < -1 || burst > NVME_ARB_AB_NO_LIMIT) {
+ nvme_printf(ctrlr, "invalid hw.nvme.arb_burst=%d specified\n",
+ burst);
+ burst = -1;
+ }
+
+ if (burst == -1) {
+ if (ctrlr->cdata.rab == 0 ||
+ (ctrlr->quirks & QUIRK_IGNORE_RAB) != 0)
+ return;
+ burst = min(ctrlr->cdata.rab, NVME_ARB_AB_NO_LIMIT);
+ } else if ((ctrlr->quirks & QUIRK_IGNORE_RAB) != 0) {
+ nvme_printf(ctrlr,
+ "forcing arbitration burst %d despite controller quirk\n",
+ burst);
+ }
+
+ nvme_ctrlr_cmd_set_arbitration(ctrlr, NVMEF(NVME_ARB_AB, burst),
+ nvme_ctrlr_arbitration_done, ctrlr);
+}
+
static void
nvme_ctrlr_configure_int_coalescing(struct nvme_controller *ctrlr)
{
@@ -1143,6 +1180,7 @@
nvme_ctrlr_configure_aer(ctrlr);
nvme_ctrlr_configure_apst(ctrlr);
+ nvme_ctrlr_configure_arbitration(ctrlr);
nvme_ctrlr_configure_int_coalescing(ctrlr);
for (i = 0; i < ctrlr->num_io_queues; i++)
diff --git a/sys/dev/nvme/nvme_ctrlr_cmd.c b/sys/dev/nvme/nvme_ctrlr_cmd.c
--- a/sys/dev/nvme/nvme_ctrlr_cmd.c
+++ b/sys/dev/nvme/nvme_ctrlr_cmd.c
@@ -260,6 +260,15 @@
0, 0, 0, 0, NULL, 0, cb_fn, cb_arg);
}
+void
+nvme_ctrlr_cmd_set_arbitration(struct nvme_controller *ctrlr,
+ uint32_t cdw11, nvme_cb_fn_t cb_fn, void *cb_arg)
+{
+
+ nvme_ctrlr_cmd_set_feature(ctrlr, NVME_FEAT_ARBITRATION, cdw11,
+ 0, 0, 0, 0, NULL, 0, cb_fn, cb_arg);
+}
+
void
nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr, uint8_t log_page,
uint32_t nsid, void *payload, uint32_t payload_size, nvme_cb_fn_t cb_fn,
diff --git a/sys/dev/nvme/nvme_pci.c b/sys/dev/nvme/nvme_pci.c
--- a/sys/dev/nvme/nvme_pci.c
+++ b/sys/dev/nvme/nvme_pci.c
@@ -99,11 +99,12 @@
{ 0x07f015ad, 0, 0, "VMware NVMe Controller" },
{ 0x2003106b, 0, 0, "Apple S3X NVMe Controller",
QUIRK_APPLE_NO_ASYNC_EVENT | QUIRK_APPLE_S3X_NS1_ONLY |
- QUIRK_PCIE_FLR_ON_FATAL | QUIRK_APPLE_S3X_SERIALIZE },
+ QUIRK_PCIE_FLR_ON_FATAL | QUIRK_APPLE_S3X_SERIALIZE |
+ QUIRK_IGNORE_RAB },
{ 0x2005106b, 0, 0, "Apple ANS2 NVMe Controller (T2)",
QUIRK_APPLE_IDENTIFY_CNS_BROKEN | QUIRK_APPLE_SHARED_CID_SPACE |
QUIRK_APPLE_NO_ASYNC_EVENT | QUIRK_APPLE_SINGLE_VECTOR |
- QUIRK_APPLE_128_BYTE_SQES },
+ QUIRK_APPLE_128_BYTE_SQES | QUIRK_IGNORE_RAB },
{ 0x80611d0f, 0, 0, "Amazon EBS NVMe Controller",
QUIRK_EMPTY_NAMESPACE_CHANGED_LOG },
{ 0x00000000, 0, 0, NULL }
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
@@ -238,6 +238,7 @@
#define QUIRK_APPLE_128_BYTE_SQES 0x400 /* T2 uses 128-byte I/O SQEs */
#define QUIRK_PCIE_FLR_ON_FATAL 0x800 /* Use FLR for a fatal controller */
#define QUIRK_APPLE_S3X_SERIALIZE 0x1000 /* One S3X I/O at a time */
+#define QUIRK_IGNORE_RAB 0x2000 /* Don't configure AB from RAB */
/* Values programmed into CC.IOSQES (log2 of the SQE size in bytes). */
#define NVME_IOSQES_64 6
@@ -396,6 +397,8 @@
uint32_t threshold,
nvme_cb_fn_t cb_fn,
void *cb_arg);
+void nvme_ctrlr_cmd_set_arbitration(struct nvme_controller *ctrlr,
+ uint32_t cdw11, nvme_cb_fn_t cb_fn, void *cb_arg);
void nvme_ctrlr_cmd_get_error_page(struct nvme_controller *ctrlr,
struct nvme_error_information_entry *payload,
uint32_t num_entries, /* 0 = max */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Sep 4, 10:47 AM (19 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38029680
Default Alt Text
D59155.diff (5 KB)
Attached To
Mode
D59155: nvme: program the arbitration burst from Identify RAB
Attached
Detach File
Event Timeline
Log In to Comment