]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
nvme-pci: derive and better document max segments limits
authorChristoph Hellwig <hch@lst.de>
Tue, 13 May 2025 07:06:49 +0000 (09:06 +0200)
committerChristoph Hellwig <hch@lst.de>
Tue, 20 May 2025 03:34:27 +0000 (05:34 +0200)
Redefine the max segments and max integrity limits based on the limiting
factors.  This keeps exactly the same values for 4k PAGE_SIZE systems,
but increases the number of segments for larger page size as it properly
derives the scatterlist allocation based limit for them instead of
assuming a 4k PAGE_SIZE.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/host/pci.c

index 1098eb17890b26e6c00f03ba86010afe5f08b6ca..94ed13903b1b6c6a52a7fe3a8b28dbe483b98282 100644 (file)
@@ -35,8 +35,6 @@
 #define SQ_SIZE(q)     ((q)->q_depth << (q)->sqes)
 #define CQ_SIZE(q)     ((q)->q_depth * sizeof(struct nvme_completion))
 
-#define SGES_PER_PAGE  (NVME_CTRL_PAGE_SIZE / sizeof(struct nvme_sgl_desc))
-
 /* Optimisation for I/Os between 4k and 128k */
 #define NVME_SMALL_POOL_SIZE   256
 
  * require an sg allocation that needs more than a page of data.
  */
 #define NVME_MAX_KB_SZ 8192
-#define NVME_MAX_SEGS  128
-#define NVME_MAX_META_SEGS 15
 #define NVME_MAX_NR_DESCRIPTORS        5
 
+/*
+ * For data SGLs we support a single descriptors worth of SGL entries, but for
+ * now we also limit it to avoid an allocation larger than PAGE_SIZE for the
+ * scatterlist.
+ */
+#define NVME_MAX_SEGS \
+       min(NVME_CTRL_PAGE_SIZE / sizeof(struct nvme_sgl_desc), \
+           (PAGE_SIZE / sizeof(struct scatterlist)))
+
+/*
+ * For metadata SGLs, only the small descriptor is supported, and the first
+ * entry is the segment descriptor, which for the data pointer sits in the SQE.
+ */
+#define NVME_MAX_META_SEGS \
+       ((NVME_SMALL_POOL_SIZE / sizeof(struct nvme_sgl_desc)) - 1)
+
 static int use_threaded_interrupts;
 module_param(use_threaded_interrupts, int, 0444);
 
@@ -3829,8 +3841,6 @@ static int __init nvme_init(void)
        BUILD_BUG_ON(sizeof(struct nvme_create_sq) != 64);
        BUILD_BUG_ON(sizeof(struct nvme_delete_queue) != 64);
        BUILD_BUG_ON(IRQ_AFFINITY_MAX_SETS < 2);
-       BUILD_BUG_ON(NVME_MAX_SEGS > SGES_PER_PAGE);
-       BUILD_BUG_ON(sizeof(struct scatterlist) * NVME_MAX_SEGS > PAGE_SIZE);
        BUILD_BUG_ON(nvme_pci_npages_prp() > NVME_MAX_NR_DESCRIPTORS);
 
        return pci_register_driver(&nvme_driver);