linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/8] Add support for segments smaller than one page
@ 2022-11-23 20:57 Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 1/8] block: Introduce CONFIG_BLK_SUB_PAGE_SEGMENTS and QUEUE_FLAG_SUB_PAGE_SEGMENTS Bart Van Assche
                   ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: Bart Van Assche @ 2022-11-23 20:57 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Bart Van Assche

Hi Jens,

Several embedded storage controllers need support for DMA segments that are
smaller than the size of one virtual memory page. Hence this patch series.
Please consider this patch series for the next merge window.

Thanks,

Bart.

Changes compared to v1:
- Added a CONFIG variable that controls whether or not small segment support
  is enabled.
- Improved patch descriptions.

Bart Van Assche (8):
  block: Introduce CONFIG_BLK_SUB_PAGE_SEGMENTS and
    QUEUE_FLAG_SUB_PAGE_SEGMENTS
  block: Support configuring limits below the page size
  block: Support submitting passthrough requests with small segments
  block: Add support for filesystem requests and small segments
  block: Add support for small segments in blk_rq_map_user_iov()
  scsi: core: Set the SUB_PAGE_SEGMENTS request queue flag
  scsi_debug: Support configuring the maximum segment size
  null_blk: Support configuring the maximum segment size

 block/Kconfig                     |  9 +++++++
 block/blk-map.c                   | 43 ++++++++++++++++++++++++++-----
 block/blk-merge.c                 |  6 +++--
 block/blk-mq.c                    |  2 ++
 block/blk-settings.c              | 20 ++++++++------
 block/blk.h                       | 14 +++++++++-
 drivers/block/null_blk/main.c     | 20 +++++++++++---
 drivers/block/null_blk/null_blk.h |  1 +
 drivers/scsi/scsi_debug.c         |  3 +++
 drivers/scsi/scsi_lib.c           |  2 ++
 include/linux/blkdev.h            |  7 +++++
 11 files changed, 107 insertions(+), 20 deletions(-)


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

* [PATCH v2 1/8] block: Introduce CONFIG_BLK_SUB_PAGE_SEGMENTS and QUEUE_FLAG_SUB_PAGE_SEGMENTS
  2022-11-23 20:57 [PATCH v2 0/8] Add support for segments smaller than one page Bart Van Assche
@ 2022-11-23 20:57 ` Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 2/8] block: Support configuring limits below the page size Bart Van Assche
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Bart Van Assche @ 2022-11-23 20:57 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Bart Van Assche, Ming Lei, Keith Busch

Prepare for introducing support for segments smaller than the page size
by introducing the request queue flag QUEUE_FLAG_SUB_PAGE_SEGMENTS.
Introduce CONFIG_BLK_SUB_PAGE_SEGMENTS to prevent that performance of
block drivers that support segments >= PAGE_SIZE would be affected.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Keith Busch <kbusch@kernel.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 block/Kconfig          | 9 +++++++++
 include/linux/blkdev.h | 7 +++++++
 2 files changed, 16 insertions(+)

diff --git a/block/Kconfig b/block/Kconfig
index 444c5ab3b67e..c3857795fc0d 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -36,6 +36,15 @@ config BLOCK_LEGACY_AUTOLOAD
 	  created on demand, but scripts that manually create device nodes and
 	  then call losetup might rely on this behavior.
 
+config BLK_SUB_PAGE_SEGMENTS
+       bool "Support segments smaller than the page size"
+       default n
+       help
+	  Most storage controllers support DMA segments larger than the typical
+	  size of a virtual memory page. Some embedded controllers only support
+	  DMA segments smaller than the page size. Enable this option to support
+	  such controllers.
+
 config BLK_RQ_ALLOC_TIME
 	bool
 
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 3dbd45725b9f..a2362cf07366 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -548,6 +548,7 @@ struct request_queue {
 /* Keep blk_queue_flag_name[] in sync with the definitions below */
 #define QUEUE_FLAG_STOPPED	0	/* queue is stopped */
 #define QUEUE_FLAG_DYING	1	/* queue being torn down */
+#define QUEUE_FLAG_SUB_PAGE_SEGMENTS 2	/* segments smaller than one page */
 #define QUEUE_FLAG_NOMERGES     3	/* disable merge attempts */
 #define QUEUE_FLAG_SAME_COMP	4	/* complete on same CPU-group */
 #define QUEUE_FLAG_FAIL_IO	5	/* fake timeout */
@@ -614,6 +615,12 @@ bool blk_queue_flag_test_and_set(unsigned int flag, struct request_queue *q);
 #define blk_queue_sq_sched(q)	test_bit(QUEUE_FLAG_SQ_SCHED, &(q)->queue_flags)
 #define blk_queue_skip_tagset_quiesce(q) \
 	test_bit(QUEUE_FLAG_SKIP_TAGSET_QUIESCE, &(q)->queue_flags)
+#ifdef CONFIG_BLK_SUB_PAGE_SEGMENTS
+#define blk_queue_sub_page_segments(q)				\
+	test_bit(QUEUE_FLAG_SUB_PAGE_SEGMENTS, &(q)->queue_flags)
+#else
+#define blk_queue_sub_page_segments(q) false
+#endif
 
 extern void blk_set_pm_only(struct request_queue *q);
 extern void blk_clear_pm_only(struct request_queue *q);

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

* [PATCH v2 2/8] block: Support configuring limits below the page size
  2022-11-23 20:57 [PATCH v2 0/8] Add support for segments smaller than one page Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 1/8] block: Introduce CONFIG_BLK_SUB_PAGE_SEGMENTS and QUEUE_FLAG_SUB_PAGE_SEGMENTS Bart Van Assche
@ 2022-11-23 20:57 ` Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 3/8] block: Support submitting passthrough requests with small segments Bart Van Assche
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Bart Van Assche @ 2022-11-23 20:57 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Bart Van Assche, Ming Lei, Keith Busch

Allow block drivers to configure the following if
CONFIG_BLK_SUB_PAGE_SEGMENTS=y:
* Maximum number of hardware sectors values smaller than
  PAGE_SIZE >> SECTOR_SHIFT. With PAGE_SIZE = 4096 this means that values
  below 8 become supported.
* A maximum segment size smaller than the page size. This is most useful
  for page sizes above 4096 bytes.

The behavior of the block layer is not modified if
CONFIG_BLK_SUB_PAGE_SEGMENTS=n.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Keith Busch <kbusch@kernel.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 block/blk-settings.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/block/blk-settings.c b/block/blk-settings.c
index 0477c4d527fe..f9d78dea0291 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -122,12 +122,14 @@ EXPORT_SYMBOL(blk_queue_bounce_limit);
 void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
 {
 	struct queue_limits *limits = &q->limits;
+	unsigned int min_max_hw_sectors = blk_queue_sub_page_segments(q) ? 1 :
+		PAGE_SIZE >> SECTOR_SHIFT;
 	unsigned int max_sectors;
 
-	if ((max_hw_sectors << 9) < PAGE_SIZE) {
-		max_hw_sectors = 1 << (PAGE_SHIFT - 9);
-		printk(KERN_INFO "%s: set to minimum %d\n",
-		       __func__, max_hw_sectors);
+	if (max_hw_sectors < min_max_hw_sectors) {
+		max_hw_sectors = min_max_hw_sectors;
+		printk(KERN_INFO "%s: set to minimum %u\n", __func__,
+		       max_hw_sectors);
 	}
 
 	max_hw_sectors = round_down(max_hw_sectors,
@@ -277,10 +279,12 @@ EXPORT_SYMBOL_GPL(blk_queue_max_discard_segments);
  **/
 void blk_queue_max_segment_size(struct request_queue *q, unsigned int max_size)
 {
-	if (max_size < PAGE_SIZE) {
-		max_size = PAGE_SIZE;
-		printk(KERN_INFO "%s: set to minimum %d\n",
-		       __func__, max_size);
+	unsigned int min_max_segment_size = blk_queue_sub_page_segments(q) ?
+		SECTOR_SIZE : PAGE_SIZE;
+
+	if (max_size < min_max_segment_size) {
+		max_size = min_max_segment_size;
+		printk(KERN_INFO "%s: set to minimum %u\n", __func__, max_size);
 	}
 
 	/* see blk_queue_virt_boundary() for the explanation */

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

* [PATCH v2 3/8] block: Support submitting passthrough requests with small segments
  2022-11-23 20:57 [PATCH v2 0/8] Add support for segments smaller than one page Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 1/8] block: Introduce CONFIG_BLK_SUB_PAGE_SEGMENTS and QUEUE_FLAG_SUB_PAGE_SEGMENTS Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 2/8] block: Support configuring limits below the page size Bart Van Assche
@ 2022-11-23 20:57 ` Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 4/8] block: Add support for filesystem requests and " Bart Van Assche
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Bart Van Assche @ 2022-11-23 20:57 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Bart Van Assche, Ming Lei, Keith Busch

If the segment size is smaller than the page size there may be multiple
segments per bvec even if a bvec only contains a single page. Hence this
patch.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Keith Busch <kbusch@kernel.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 block/blk-map.c | 16 +++++++++++++++-
 block/blk.h     | 11 +++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/block/blk-map.c b/block/blk-map.c
index 19940c978c73..d2d6ee098514 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -524,6 +524,20 @@ static struct bio *bio_copy_kern(struct request_queue *q, void *data,
 	return ERR_PTR(-ENOMEM);
 }
 
+#ifdef CONFIG_BLK_SUB_PAGE_SEGMENTS
+/* Number of DMA segments required to transfer @bytes data. */
+unsigned int blk_segments(const struct queue_limits *limits, unsigned int bytes)
+{
+	const unsigned int mss = limits->max_segment_size;
+
+	if (bytes <= mss)
+		return 1;
+	if (is_power_of_2(mss))
+		return round_up(bytes, mss) >> ilog2(mss);
+	return (bytes + mss - 1) / mss;
+}
+#endif
+
 /*
  * Append a bio to a passthrough request.  Only works if the bio can be merged
  * into the request based on the driver constraints.
@@ -535,7 +549,7 @@ int blk_rq_append_bio(struct request *rq, struct bio *bio)
 	unsigned int nr_segs = 0;
 
 	bio_for_each_bvec(bv, bio, iter)
-		nr_segs++;
+		nr_segs += blk_segments(&rq->q->limits, bv.bv_len);
 
 	if (!rq->bio) {
 		blk_rq_bio_prep(rq, bio, nr_segs);
diff --git a/block/blk.h b/block/blk.h
index 5929559acd71..fb486eff3eef 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -80,6 +80,17 @@ struct bio_vec *bvec_alloc(mempool_t *pool, unsigned short *nr_vecs,
 		gfp_t gfp_mask);
 void bvec_free(mempool_t *pool, struct bio_vec *bv, unsigned short nr_vecs);
 
+#ifdef CONFIG_BLK_SUB_PAGE_SEGMENTS
+unsigned int blk_segments(const struct queue_limits *limits,
+			  unsigned int bytes);
+#else
+static inline unsigned int blk_segments(const struct queue_limits *limits,
+					unsigned int bytes)
+{
+	return 1;
+}
+#endif
+
 static inline bool biovec_phys_mergeable(struct request_queue *q,
 		struct bio_vec *vec1, struct bio_vec *vec2)
 {

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

* [PATCH v2 4/8] block: Add support for filesystem requests and small segments
  2022-11-23 20:57 [PATCH v2 0/8] Add support for segments smaller than one page Bart Van Assche
                   ` (2 preceding siblings ...)
  2022-11-23 20:57 ` [PATCH v2 3/8] block: Support submitting passthrough requests with small segments Bart Van Assche
@ 2022-11-23 20:57 ` Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 5/8] block: Add support for small segments in blk_rq_map_user_iov() Bart Van Assche
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Bart Van Assche @ 2022-11-23 20:57 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Bart Van Assche, Ming Lei, Keith Busch

Add support in the bio splitting code and also in the bio submission code
for bios with segments smaller than the page size.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Keith Busch <kbusch@kernel.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 block/blk-merge.c | 6 ++++--
 block/blk-mq.c    | 2 ++
 block/blk.h       | 3 ++-
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/block/blk-merge.c b/block/blk-merge.c
index 35a8f75cc45d..7badfbed09fc 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -294,7 +294,8 @@ static struct bio *bio_split_rw(struct bio *bio, const struct queue_limits *lim,
 		if (nsegs < lim->max_segments &&
 		    bytes + bv.bv_len <= max_bytes &&
 		    bv.bv_offset + bv.bv_len <= PAGE_SIZE) {
-			nsegs++;
+			/* single-page bvec optimization */
+			nsegs += blk_segments(lim, bv.bv_len);
 			bytes += bv.bv_len;
 		} else {
 			if (bvec_split_segs(lim, &bv, &nsegs, &bytes,
@@ -531,7 +532,8 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio,
 			    __blk_segment_map_sg_merge(q, &bvec, &bvprv, sg))
 				goto next_bvec;
 
-			if (bvec.bv_offset + bvec.bv_len <= PAGE_SIZE)
+			if (bvec.bv_offset + bvec.bv_len <= PAGE_SIZE &&
+			    bvec.bv_len <= q->limits.max_segment_size)
 				nsegs += __blk_bvec_map_sg(bvec, sglist, sg);
 			else
 				nsegs += blk_bvec_map_sg(q, &bvec, sglist, sg);
diff --git a/block/blk-mq.c b/block/blk-mq.c
index f72164429446..1560e4f76f2d 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2953,6 +2953,8 @@ void blk_mq_submit_bio(struct bio *bio)
 	bio = blk_queue_bounce(bio, q);
 	if (bio_may_exceed_limits(bio, &q->limits))
 		bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
+	else if (bio->bi_vcnt == 1)
+		nr_segs = blk_segments(&q->limits, bio->bi_io_vec[0].bv_len);
 
 	if (!bio_integrity_prep(bio))
 		return;
diff --git a/block/blk.h b/block/blk.h
index fb486eff3eef..c45f86b74b1d 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -320,7 +320,7 @@ static inline bool bio_may_exceed_limits(struct bio *bio,
 	}
 
 	/*
-	 * All drivers must accept single-segments bios that are <= PAGE_SIZE.
+	 * Check whether bio splitting should be performed.
 	 * This is a quick and dirty check that relies on the fact that
 	 * bi_io_vec[0] is always valid if a bio has data.  The check might
 	 * lead to occasional false negatives when bios are cloned, but compared
@@ -328,6 +328,7 @@ static inline bool bio_may_exceed_limits(struct bio *bio,
 	 * doesn't matter anyway.
 	 */
 	return lim->chunk_sectors || bio->bi_vcnt != 1 ||
+		bio->bi_io_vec->bv_len > lim->max_segment_size ||
 		bio->bi_io_vec->bv_len + bio->bi_io_vec->bv_offset > PAGE_SIZE;
 }
 

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

* [PATCH v2 5/8] block: Add support for small segments in blk_rq_map_user_iov()
  2022-11-23 20:57 [PATCH v2 0/8] Add support for segments smaller than one page Bart Van Assche
                   ` (3 preceding siblings ...)
  2022-11-23 20:57 ` [PATCH v2 4/8] block: Add support for filesystem requests and " Bart Van Assche
@ 2022-11-23 20:57 ` Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 6/8] scsi: core: Set the SUB_PAGE_SEGMENTS request queue flag Bart Van Assche
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Bart Van Assche @ 2022-11-23 20:57 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Bart Van Assche, Ming Lei, Keith Busch

Before changing the return value of bio_add_hw_page() into a value in
the range [0, len], make blk_rq_map_user_iov() fall back to copying data
if mapping the data is not possible due to the segment limit.

Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Keith Busch <kbusch@kernel.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 block/blk-map.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/block/blk-map.c b/block/blk-map.c
index d2d6ee098514..f3f2ed9c6183 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -308,17 +308,26 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
 		else {
 			for (j = 0; j < npages; j++) {
 				struct page *page = pages[j];
-				unsigned int n = PAGE_SIZE - offs;
+				unsigned int n = PAGE_SIZE - offs, added;
 				bool same_page = false;
 
 				if (n > bytes)
 					n = bytes;
 
-				if (!bio_add_hw_page(rq->q, bio, page, n, offs,
-						     max_sectors, &same_page)) {
+				added = bio_add_hw_page(rq->q, bio, page, n,
+						offs, max_sectors, &same_page);
+				if (added == 0) {
 					if (same_page)
 						put_page(page);
 					break;
+				} else if (added != n) {
+					/*
+					 * The segment size is smaller than the
+					 * page size and an iov exceeds the
+					 * segment size. Give up.
+					 */
+					ret = -EREMOTEIO;
+					goto out_unmap;
 				}
 
 				bytes -= n;
@@ -672,10 +681,18 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
 
 	i = *iter;
 	do {
-		if (copy)
+		if (copy) {
 			ret = bio_copy_user_iov(rq, map_data, &i, gfp_mask);
-		else
+		} else {
 			ret = bio_map_user_iov(rq, &i, gfp_mask);
+			/*
+			 * Fall back to copying the data if bio_map_user_iov()
+			 * returns -EREMOTEIO.
+			 */
+			if (ret == -EREMOTEIO)
+				ret = bio_copy_user_iov(rq, map_data, &i,
+							gfp_mask);
+		}
 		if (ret)
 			goto unmap_rq;
 		if (!bio)

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

* [PATCH v2 6/8] scsi: core: Set the SUB_PAGE_SEGMENTS request queue flag
  2022-11-23 20:57 [PATCH v2 0/8] Add support for segments smaller than one page Bart Van Assche
                   ` (4 preceding siblings ...)
  2022-11-23 20:57 ` [PATCH v2 5/8] block: Add support for small segments in blk_rq_map_user_iov() Bart Van Assche
@ 2022-11-23 20:57 ` Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 7/8] scsi_debug: Support configuring the maximum segment size Bart Van Assche
  2022-11-23 20:57 ` [PATCH v2 8/8] null_blk: " Bart Van Assche
  7 siblings, 0 replies; 14+ messages in thread
From: Bart Van Assche @ 2022-11-23 20:57 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Bart Van Assche, Martin K . Petersen

This patch enables support for segments smaller than the page size.
No changes other than setting the SUB_PAGE_SEGMENTS flag are required
since the SCSI code uses blk_rq_map_sg().

Cc: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_lib.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 249757ddd8fe..d91aefdfb8d4 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1877,6 +1877,8 @@ void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q)
 {
 	struct device *dev = shost->dma_dev;
 
+	blk_queue_flag_set(QUEUE_FLAG_SUB_PAGE_SEGMENTS, q);
+
 	/*
 	 * this limit is imposed by hardware restrictions
 	 */

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

* [PATCH v2 7/8] scsi_debug: Support configuring the maximum segment size
  2022-11-23 20:57 [PATCH v2 0/8] Add support for segments smaller than one page Bart Van Assche
                   ` (5 preceding siblings ...)
  2022-11-23 20:57 ` [PATCH v2 6/8] scsi: core: Set the SUB_PAGE_SEGMENTS request queue flag Bart Van Assche
@ 2022-11-23 20:57 ` Bart Van Assche
  2022-11-25 17:34   ` Douglas Gilbert
  2022-11-23 20:57 ` [PATCH v2 8/8] null_blk: " Bart Van Assche
  7 siblings, 1 reply; 14+ messages in thread
From: Bart Van Assche @ 2022-11-23 20:57 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Bart Van Assche, Doug Gilbert, Martin K . Petersen

Add a kernel module parameter for configuring the maximum segment size.
This patch enables testing SCSI support for segments smaller than the
page size.

Cc: Doug Gilbert <dgilbert@interlog.com>
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_debug.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index bebda917b138..ea8f762c55c3 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -770,6 +770,7 @@ static int sdebug_sector_size = DEF_SECTOR_SIZE;
 static int sdeb_tur_ms_to_ready = DEF_TUR_MS_TO_READY;
 static int sdebug_virtual_gb = DEF_VIRTUAL_GB;
 static int sdebug_vpd_use_hostno = DEF_VPD_USE_HOSTNO;
+static unsigned int sdebug_max_segment_size = -1U;
 static unsigned int sdebug_lbpu = DEF_LBPU;
 static unsigned int sdebug_lbpws = DEF_LBPWS;
 static unsigned int sdebug_lbpws10 = DEF_LBPWS10;
@@ -5851,6 +5852,7 @@ module_param_named(ndelay, sdebug_ndelay, int, S_IRUGO | S_IWUSR);
 module_param_named(no_lun_0, sdebug_no_lun_0, int, S_IRUGO | S_IWUSR);
 module_param_named(no_rwlock, sdebug_no_rwlock, bool, S_IRUGO | S_IWUSR);
 module_param_named(no_uld, sdebug_no_uld, int, S_IRUGO);
+module_param_named(max_segment_size, sdebug_max_segment_size, uint, S_IRUGO);
 module_param_named(num_parts, sdebug_num_parts, int, S_IRUGO);
 module_param_named(num_tgts, sdebug_num_tgts, int, S_IRUGO | S_IWUSR);
 module_param_named(opt_blks, sdebug_opt_blks, int, S_IRUGO);
@@ -7815,6 +7817,7 @@ static int sdebug_driver_probe(struct device *dev)
 
 	sdebug_driver_template.can_queue = sdebug_max_queue;
 	sdebug_driver_template.cmd_per_lun = sdebug_max_queue;
+	sdebug_driver_template.max_segment_size = sdebug_max_segment_size;
 	if (!sdebug_clustering)
 		sdebug_driver_template.dma_boundary = PAGE_SIZE - 1;
 

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

* [PATCH v2 8/8] null_blk: Support configuring the maximum segment size
  2022-11-23 20:57 [PATCH v2 0/8] Add support for segments smaller than one page Bart Van Assche
                   ` (6 preceding siblings ...)
  2022-11-23 20:57 ` [PATCH v2 7/8] scsi_debug: Support configuring the maximum segment size Bart Van Assche
@ 2022-11-23 20:57 ` Bart Van Assche
  2022-11-24  1:40   ` Damien Le Moal
  7 siblings, 1 reply; 14+ messages in thread
From: Bart Van Assche @ 2022-11-23 20:57 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Bart Van Assche, Ming Lei, Damien Le Moal,
	Chaitanya Kulkarni

Add support for configuring the maximum segment size.

Add support for segments smaller than the page size.

This patch enables testing segments smaller than the page size with a
driver that does not call blk_rq_map_sg().

Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Cc: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/block/null_blk/main.c     | 20 +++++++++++++++++---
 drivers/block/null_blk/null_blk.h |  1 +
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
index 1f154f92f4c2..bc811ab52c4a 100644
--- a/drivers/block/null_blk/main.c
+++ b/drivers/block/null_blk/main.c
@@ -157,6 +157,10 @@ static int g_max_sectors;
 module_param_named(max_sectors, g_max_sectors, int, 0444);
 MODULE_PARM_DESC(max_sectors, "Maximum size of a command (in 512B sectors)");
 
+static unsigned int g_max_segment_size = 1UL << 31;
+module_param_named(max_segment_size, g_max_segment_size, int, 0444);
+MODULE_PARM_DESC(max_segment_size, "Maximum size of a segment in bytes");
+
 static unsigned int nr_devices = 1;
 module_param(nr_devices, uint, 0444);
 MODULE_PARM_DESC(nr_devices, "Number of devices to register");
@@ -409,6 +413,7 @@ NULLB_DEVICE_ATTR(home_node, uint, NULL);
 NULLB_DEVICE_ATTR(queue_mode, uint, NULL);
 NULLB_DEVICE_ATTR(blocksize, uint, NULL);
 NULLB_DEVICE_ATTR(max_sectors, uint, NULL);
+NULLB_DEVICE_ATTR(max_segment_size, uint, NULL);
 NULLB_DEVICE_ATTR(irqmode, uint, NULL);
 NULLB_DEVICE_ATTR(hw_queue_depth, uint, NULL);
 NULLB_DEVICE_ATTR(index, uint, NULL);
@@ -532,6 +537,7 @@ static struct configfs_attribute *nullb_device_attrs[] = {
 	&nullb_device_attr_queue_mode,
 	&nullb_device_attr_blocksize,
 	&nullb_device_attr_max_sectors,
+	&nullb_device_attr_max_segment_size,
 	&nullb_device_attr_irqmode,
 	&nullb_device_attr_hw_queue_depth,
 	&nullb_device_attr_index,
@@ -610,7 +616,8 @@ static ssize_t memb_group_features_show(struct config_item *item, char *page)
 	return snprintf(page, PAGE_SIZE,
 			"badblocks,blocking,blocksize,cache_size,"
 			"completion_nsec,discard,home_node,hw_queue_depth,"
-			"irqmode,max_sectors,mbps,memory_backed,no_sched,"
+			"irqmode,max_sectors,max_segment_size,mbps,"
+			"memory_backed,no_sched,"
 			"poll_queues,power,queue_mode,shared_tag_bitmap,size,"
 			"submit_queues,use_per_node_hctx,virt_boundary,zoned,"
 			"zone_capacity,zone_max_active,zone_max_open,"
@@ -673,6 +680,7 @@ static struct nullb_device *null_alloc_dev(void)
 	dev->queue_mode = g_queue_mode;
 	dev->blocksize = g_bs;
 	dev->max_sectors = g_max_sectors;
+	dev->max_segment_size = g_max_segment_size;
 	dev->irqmode = g_irqmode;
 	dev->hw_queue_depth = g_hw_queue_depth;
 	dev->blocking = g_blocking;
@@ -1214,6 +1222,8 @@ static int null_transfer(struct nullb *nullb, struct page *page,
 	unsigned int valid_len = len;
 	int err = 0;
 
+	WARN_ONCE(len > dev->max_segment_size, "%u > %u\n", len,
+		  dev->max_segment_size);
 	if (!is_write) {
 		if (dev->zoned)
 			valid_len = null_zone_valid_read_len(nullb,
@@ -1249,7 +1259,8 @@ static int null_handle_rq(struct nullb_cmd *cmd)
 
 	spin_lock_irq(&nullb->lock);
 	rq_for_each_segment(bvec, rq, iter) {
-		len = bvec.bv_len;
+		len = min(bvec.bv_len, nullb->dev->max_segment_size);
+		bvec.bv_len = len;
 		err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset,
 				     op_is_write(req_op(rq)), sector,
 				     rq->cmd_flags & REQ_FUA);
@@ -1276,7 +1287,8 @@ static int null_handle_bio(struct nullb_cmd *cmd)
 
 	spin_lock_irq(&nullb->lock);
 	bio_for_each_segment(bvec, bio, iter) {
-		len = bvec.bv_len;
+		len = min(bvec.bv_len, nullb->dev->max_segment_size);
+		bvec.bv_len = len;
 		err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset,
 				     op_is_write(bio_op(bio)), sector,
 				     bio->bi_opf & REQ_FUA);
@@ -2088,6 +2100,7 @@ static int null_add_dev(struct nullb_device *dev)
 	nullb->q->queuedata = nullb;
 	blk_queue_flag_set(QUEUE_FLAG_NONROT, nullb->q);
 	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, nullb->q);
+	blk_queue_flag_set(QUEUE_FLAG_SUB_PAGE_SEGMENTS, nullb->q);
 
 	mutex_lock(&lock);
 	rv = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL);
@@ -2106,6 +2119,7 @@ static int null_add_dev(struct nullb_device *dev)
 	dev->max_sectors = min_t(unsigned int, dev->max_sectors,
 				 BLK_DEF_MAX_SECTORS);
 	blk_queue_max_hw_sectors(nullb->q, dev->max_sectors);
+	blk_queue_max_segment_size(nullb->q, dev->max_segment_size);
 
 	if (dev->virt_boundary)
 		blk_queue_virt_boundary(nullb->q, PAGE_SIZE - 1);
diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h
index 94ff68052b1e..6784ee9f5fda 100644
--- a/drivers/block/null_blk/null_blk.h
+++ b/drivers/block/null_blk/null_blk.h
@@ -102,6 +102,7 @@ struct nullb_device {
 	unsigned int queue_mode; /* block interface */
 	unsigned int blocksize; /* block size */
 	unsigned int max_sectors; /* Max sectors per command */
+	unsigned int max_segment_size; /* Max size of a single DMA segment. */
 	unsigned int irqmode; /* IRQ completion handler */
 	unsigned int hw_queue_depth; /* queue depth */
 	unsigned int index; /* index of the disk, only valid with a disk */

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

* Re: [PATCH v2 8/8] null_blk: Support configuring the maximum segment size
  2022-11-23 20:57 ` [PATCH v2 8/8] null_blk: " Bart Van Assche
@ 2022-11-24  1:40   ` Damien Le Moal
  2022-11-30 22:29     ` Bart Van Assche
  0 siblings, 1 reply; 14+ messages in thread
From: Damien Le Moal @ 2022-11-24  1:40 UTC (permalink / raw)
  To: Bart Van Assche, Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Ming Lei, Chaitanya Kulkarni

On 11/24/22 05:57, Bart Van Assche wrote:
> Add support for configuring the maximum segment size.
> 
> Add support for segments smaller than the page size.
> 
> This patch enables testing segments smaller than the page size with a
> driver that does not call blk_rq_map_sg().
> 
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Ming Lei <ming.lei@redhat.com>
> Cc: Damien Le Moal <damien.lemoal@opensource.wdc.com>
> Cc: Chaitanya Kulkarni <kch@nvidia.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>  drivers/block/null_blk/main.c     | 20 +++++++++++++++++---
>  drivers/block/null_blk/null_blk.h |  1 +
>  2 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
> index 1f154f92f4c2..bc811ab52c4a 100644
> --- a/drivers/block/null_blk/main.c
> +++ b/drivers/block/null_blk/main.c
> @@ -157,6 +157,10 @@ static int g_max_sectors;
>  module_param_named(max_sectors, g_max_sectors, int, 0444);
>  MODULE_PARM_DESC(max_sectors, "Maximum size of a command (in 512B sectors)");
>  
> +static unsigned int g_max_segment_size = 1UL << 31;

1UL is unsigned long be this var is unsigned int. Why not simply use
UINT_MAX here ? You prefer the 2GB value ? If yes, then may be at least
change that to "1U << 31", no ?

> +module_param_named(max_segment_size, g_max_segment_size, int, 0444);
> +MODULE_PARM_DESC(max_segment_size, "Maximum size of a segment in bytes");
> +
>  static unsigned int nr_devices = 1;
>  module_param(nr_devices, uint, 0444);
>  MODULE_PARM_DESC(nr_devices, "Number of devices to register");
> @@ -409,6 +413,7 @@ NULLB_DEVICE_ATTR(home_node, uint, NULL);
>  NULLB_DEVICE_ATTR(queue_mode, uint, NULL);
>  NULLB_DEVICE_ATTR(blocksize, uint, NULL);
>  NULLB_DEVICE_ATTR(max_sectors, uint, NULL);
> +NULLB_DEVICE_ATTR(max_segment_size, uint, NULL);
>  NULLB_DEVICE_ATTR(irqmode, uint, NULL);
>  NULLB_DEVICE_ATTR(hw_queue_depth, uint, NULL);
>  NULLB_DEVICE_ATTR(index, uint, NULL);
> @@ -532,6 +537,7 @@ static struct configfs_attribute *nullb_device_attrs[] = {
>  	&nullb_device_attr_queue_mode,
>  	&nullb_device_attr_blocksize,
>  	&nullb_device_attr_max_sectors,
> +	&nullb_device_attr_max_segment_size,
>  	&nullb_device_attr_irqmode,
>  	&nullb_device_attr_hw_queue_depth,
>  	&nullb_device_attr_index,
> @@ -610,7 +616,8 @@ static ssize_t memb_group_features_show(struct config_item *item, char *page)
>  	return snprintf(page, PAGE_SIZE,
>  			"badblocks,blocking,blocksize,cache_size,"
>  			"completion_nsec,discard,home_node,hw_queue_depth,"
> -			"irqmode,max_sectors,mbps,memory_backed,no_sched,"
> +			"irqmode,max_sectors,max_segment_size,mbps,"
> +			"memory_backed,no_sched,"
>  			"poll_queues,power,queue_mode,shared_tag_bitmap,size,"
>  			"submit_queues,use_per_node_hctx,virt_boundary,zoned,"
>  			"zone_capacity,zone_max_active,zone_max_open,"
> @@ -673,6 +680,7 @@ static struct nullb_device *null_alloc_dev(void)
>  	dev->queue_mode = g_queue_mode;
>  	dev->blocksize = g_bs;
>  	dev->max_sectors = g_max_sectors;
> +	dev->max_segment_size = g_max_segment_size;
>  	dev->irqmode = g_irqmode;
>  	dev->hw_queue_depth = g_hw_queue_depth;
>  	dev->blocking = g_blocking;
> @@ -1214,6 +1222,8 @@ static int null_transfer(struct nullb *nullb, struct page *page,
>  	unsigned int valid_len = len;
>  	int err = 0;
>  
> +	WARN_ONCE(len > dev->max_segment_size, "%u > %u\n", len,
> +		  dev->max_segment_size);
>  	if (!is_write) {
>  		if (dev->zoned)
>  			valid_len = null_zone_valid_read_len(nullb,
> @@ -1249,7 +1259,8 @@ static int null_handle_rq(struct nullb_cmd *cmd)
>  
>  	spin_lock_irq(&nullb->lock);
>  	rq_for_each_segment(bvec, rq, iter) {
> -		len = bvec.bv_len;
> +		len = min(bvec.bv_len, nullb->dev->max_segment_size);
> +		bvec.bv_len = len;
>  		err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset,
>  				     op_is_write(req_op(rq)), sector,
>  				     rq->cmd_flags & REQ_FUA);
> @@ -1276,7 +1287,8 @@ static int null_handle_bio(struct nullb_cmd *cmd)
>  
>  	spin_lock_irq(&nullb->lock);
>  	bio_for_each_segment(bvec, bio, iter) {
> -		len = bvec.bv_len;
> +		len = min(bvec.bv_len, nullb->dev->max_segment_size);
> +		bvec.bv_len = len;
>  		err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset,
>  				     op_is_write(bio_op(bio)), sector,
>  				     bio->bi_opf & REQ_FUA);
> @@ -2088,6 +2100,7 @@ static int null_add_dev(struct nullb_device *dev)
>  	nullb->q->queuedata = nullb;
>  	blk_queue_flag_set(QUEUE_FLAG_NONROT, nullb->q);
>  	blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, nullb->q);
> +	blk_queue_flag_set(QUEUE_FLAG_SUB_PAGE_SEGMENTS, nullb->q);
>  
>  	mutex_lock(&lock);
>  	rv = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL);
> @@ -2106,6 +2119,7 @@ static int null_add_dev(struct nullb_device *dev)
>  	dev->max_sectors = min_t(unsigned int, dev->max_sectors,
>  				 BLK_DEF_MAX_SECTORS);
>  	blk_queue_max_hw_sectors(nullb->q, dev->max_sectors);
> +	blk_queue_max_segment_size(nullb->q, dev->max_segment_size);

Should we keep the ability to use the kernel default value as the default
here ?
E.g.

	if (dev->max_segment_size)
		blk_queue_max_segment_size(nullb->q,
				dev->max_segment_size);

If yes, then g_max_segment_size initial value should be 0, meaning "kernel
default".

>  
>  	if (dev->virt_boundary)
>  		blk_queue_virt_boundary(nullb->q, PAGE_SIZE - 1);
> diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h
> index 94ff68052b1e..6784ee9f5fda 100644
> --- a/drivers/block/null_blk/null_blk.h
> +++ b/drivers/block/null_blk/null_blk.h
> @@ -102,6 +102,7 @@ struct nullb_device {
>  	unsigned int queue_mode; /* block interface */
>  	unsigned int blocksize; /* block size */
>  	unsigned int max_sectors; /* Max sectors per command */
> +	unsigned int max_segment_size; /* Max size of a single DMA segment. */
>  	unsigned int irqmode; /* IRQ completion handler */
>  	unsigned int hw_queue_depth; /* queue depth */
>  	unsigned int index; /* index of the disk, only valid with a disk */

-- 
Damien Le Moal
Western Digital Research


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

* Re: [PATCH v2 7/8] scsi_debug: Support configuring the maximum segment size
  2022-11-23 20:57 ` [PATCH v2 7/8] scsi_debug: Support configuring the maximum segment size Bart Van Assche
@ 2022-11-25 17:34   ` Douglas Gilbert
  2022-11-30 22:30     ` Bart Van Assche
  0 siblings, 1 reply; 14+ messages in thread
From: Douglas Gilbert @ 2022-11-25 17:34 UTC (permalink / raw)
  To: Bart Van Assche, Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Martin K . Petersen

On 2022-11-23 15:57, Bart Van Assche wrote:
> Add a kernel module parameter for configuring the maximum segment size.
> This patch enables testing SCSI support for segments smaller than the
> page size.
> 
> Cc: Doug Gilbert <dgilbert@interlog.com>
> Cc: Martin K. Petersen <martin.petersen@oracle.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>   drivers/scsi/scsi_debug.c | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index bebda917b138..ea8f762c55c3 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -770,6 +770,7 @@ static int sdebug_sector_size = DEF_SECTOR_SIZE;
>   static int sdeb_tur_ms_to_ready = DEF_TUR_MS_TO_READY;
>   static int sdebug_virtual_gb = DEF_VIRTUAL_GB;
>   static int sdebug_vpd_use_hostno = DEF_VPD_USE_HOSTNO;
> +static unsigned int sdebug_max_segment_size = -1U >   static unsigned int sdebug_lbpu = DEF_LBPU;
>   static unsigned int sdebug_lbpws = DEF_LBPWS;
>   static unsigned int sdebug_lbpws10 = DEF_LBPWS10;
> @@ -5851,6 +5852,7 @@ module_param_named(ndelay, sdebug_ndelay, int, S_IRUGO | S_IWUSR);
>   module_param_named(no_lun_0, sdebug_no_lun_0, int, S_IRUGO | S_IWUSR);
>   module_param_named(no_rwlock, sdebug_no_rwlock, bool, S_IRUGO | S_IWUSR);
>   module_param_named(no_uld, sdebug_no_uld, int, S_IRUGO);
> +module_param_named(max_segment_size, sdebug_max_segment_size, uint, S_IRUGO);

Could you place the above line in alphabetical order.

>   module_param_named(num_parts, sdebug_num_parts, int, S_IRUGO);
>   module_param_named(num_tgts, sdebug_num_tgts, int, S_IRUGO | S_IWUSR);
>   module_param_named(opt_blks, sdebug_opt_blks, int, S_IRUGO);
> @@ -7815,6 +7817,7 @@ static int sdebug_driver_probe(struct device *dev)
>   
>   	sdebug_driver_template.can_queue = sdebug_max_queue;
>   	sdebug_driver_template.cmd_per_lun = sdebug_max_queue;
> +	sdebug_driver_template.max_segment_size = sdebug_max_segment_size;
>   	if (!sdebug_clustering)
>   		sdebug_driver_template.dma_boundary = PAGE_SIZE - 1;
>   

And could you add a
MODULE_PARM_DESC(max_segment_size, "<1 line description>");

entry as well (also in alphabetical order).

Other than that:
   Ack-ed by: Douglas Gilbert <dgilbert@interlog.com>

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

* Re: [PATCH v2 8/8] null_blk: Support configuring the maximum segment size
  2022-11-24  1:40   ` Damien Le Moal
@ 2022-11-30 22:29     ` Bart Van Assche
  2022-12-01  0:39       ` Damien Le Moal
  0 siblings, 1 reply; 14+ messages in thread
From: Bart Van Assche @ 2022-11-30 22:29 UTC (permalink / raw)
  To: Damien Le Moal, Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Ming Lei, Chaitanya Kulkarni

On 11/23/22 17:40, Damien Le Moal wrote:
> On 11/24/22 05:57, Bart Van Assche wrote:
>> +static unsigned int g_max_segment_size = 1UL << 31;
> 
> 1UL is unsigned long be this var is unsigned int. Why not simply use
> UINT_MAX here ? You prefer the 2GB value ? If yes, then may be at least
> change that to "1U << 31", no ?
> 
> [ ... ]
>> @@ -2106,6 +2119,7 @@ static int null_add_dev(struct nullb_device *dev)
>>   	dev->max_sectors = min_t(unsigned int, dev->max_sectors,
>>   				 BLK_DEF_MAX_SECTORS);
>>   	blk_queue_max_hw_sectors(nullb->q, dev->max_sectors);
>> +	blk_queue_max_segment_size(nullb->q, dev->max_segment_size);
> 
> Should we keep the ability to use the kernel default value as the default
> here ?
> E.g.
> 
> 	if (dev->max_segment_size)
> 		blk_queue_max_segment_size(nullb->q,
> 				dev->max_segment_size);
> 
> If yes, then g_max_segment_size initial value should be 0, meaning "kernel
> default".

Hi Damien,

How about changing the default value for g_max_segment_size from
1UL << 31 into BLK_MAX_SEGMENT_SIZE? That will simplify the code and 
also prevents that this patch changes the behavior of the null_blk 
driver if g_max_segment_size is not modified by the user.

Thanks,

Bart.


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

* Re: [PATCH v2 7/8] scsi_debug: Support configuring the maximum segment size
  2022-11-25 17:34   ` Douglas Gilbert
@ 2022-11-30 22:30     ` Bart Van Assche
  0 siblings, 0 replies; 14+ messages in thread
From: Bart Van Assche @ 2022-11-30 22:30 UTC (permalink / raw)
  To: dgilbert, Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Martin K . Petersen

On 11/25/22 09:34, Douglas Gilbert wrote:
> On 2022-11-23 15:57, Bart Van Assche wrote:
>>   module_param_named(no_uld, sdebug_no_uld, int, S_IRUGO);
>> +module_param_named(max_segment_size, sdebug_max_segment_size, uint, 
>> S_IRUGO);
> 
> Could you place the above line in alphabetical order.
> 
>>   module_param_named(num_parts, sdebug_num_parts, int, S_IRUGO);
>>   module_param_named(num_tgts, sdebug_num_tgts, int, S_IRUGO | S_IWUSR);
>>   module_param_named(opt_blks, sdebug_opt_blks, int, S_IRUGO);
>> @@ -7815,6 +7817,7 @@ static int sdebug_driver_probe(struct device *dev)
>>       sdebug_driver_template.can_queue = sdebug_max_queue;
>>       sdebug_driver_template.cmd_per_lun = sdebug_max_queue;
>> +    sdebug_driver_template.max_segment_size = sdebug_max_segment_size;
>>       if (!sdebug_clustering)
>>           sdebug_driver_template.dma_boundary = PAGE_SIZE - 1;
> 
> And could you add a
> MODULE_PARM_DESC(max_segment_size, "<1 line description>");
> 
> entry as well (also in alphabetical order).

Hi Doug,

I will make these changes.

Thanks for the feedback.

Bart.


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

* Re: [PATCH v2 8/8] null_blk: Support configuring the maximum segment size
  2022-11-30 22:29     ` Bart Van Assche
@ 2022-12-01  0:39       ` Damien Le Moal
  0 siblings, 0 replies; 14+ messages in thread
From: Damien Le Moal @ 2022-12-01  0:39 UTC (permalink / raw)
  To: Bart Van Assche, Jens Axboe
  Cc: linux-block, linux-scsi, Christoph Hellwig, Adrian Hunter,
	Avri Altman, Ming Lei, Chaitanya Kulkarni

On 12/1/22 07:29, Bart Van Assche wrote:
> On 11/23/22 17:40, Damien Le Moal wrote:
>> On 11/24/22 05:57, Bart Van Assche wrote:
>>> +static unsigned int g_max_segment_size = 1UL << 31;
>>
>> 1UL is unsigned long be this var is unsigned int. Why not simply use
>> UINT_MAX here ? You prefer the 2GB value ? If yes, then may be at least
>> change that to "1U << 31", no ?
>>
>> [ ... ]
>>> @@ -2106,6 +2119,7 @@ static int null_add_dev(struct nullb_device *dev)
>>>   	dev->max_sectors = min_t(unsigned int, dev->max_sectors,
>>>   				 BLK_DEF_MAX_SECTORS);
>>>   	blk_queue_max_hw_sectors(nullb->q, dev->max_sectors);
>>> +	blk_queue_max_segment_size(nullb->q, dev->max_segment_size);
>>
>> Should we keep the ability to use the kernel default value as the default
>> here ?
>> E.g.
>>
>> 	if (dev->max_segment_size)
>> 		blk_queue_max_segment_size(nullb->q,
>> 				dev->max_segment_size);
>>
>> If yes, then g_max_segment_size initial value should be 0, meaning "kernel
>> default".
> 
> Hi Damien,
> 
> How about changing the default value for g_max_segment_size from
> 1UL << 31 into BLK_MAX_SEGMENT_SIZE? That will simplify the code and 
> also prevents that this patch changes the behavior of the null_blk 
> driver if g_max_segment_size is not modified by the user.

Sounds good to me.

> 
> Thanks,
> 
> Bart.
> 

-- 
Damien Le Moal
Western Digital Research


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

end of thread, other threads:[~2022-12-01  0:39 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-23 20:57 [PATCH v2 0/8] Add support for segments smaller than one page Bart Van Assche
2022-11-23 20:57 ` [PATCH v2 1/8] block: Introduce CONFIG_BLK_SUB_PAGE_SEGMENTS and QUEUE_FLAG_SUB_PAGE_SEGMENTS Bart Van Assche
2022-11-23 20:57 ` [PATCH v2 2/8] block: Support configuring limits below the page size Bart Van Assche
2022-11-23 20:57 ` [PATCH v2 3/8] block: Support submitting passthrough requests with small segments Bart Van Assche
2022-11-23 20:57 ` [PATCH v2 4/8] block: Add support for filesystem requests and " Bart Van Assche
2022-11-23 20:57 ` [PATCH v2 5/8] block: Add support for small segments in blk_rq_map_user_iov() Bart Van Assche
2022-11-23 20:57 ` [PATCH v2 6/8] scsi: core: Set the SUB_PAGE_SEGMENTS request queue flag Bart Van Assche
2022-11-23 20:57 ` [PATCH v2 7/8] scsi_debug: Support configuring the maximum segment size Bart Van Assche
2022-11-25 17:34   ` Douglas Gilbert
2022-11-30 22:30     ` Bart Van Assche
2022-11-23 20:57 ` [PATCH v2 8/8] null_blk: " Bart Van Assche
2022-11-24  1:40   ` Damien Le Moal
2022-11-30 22:29     ` Bart Van Assche
2022-12-01  0:39       ` Damien Le Moal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).