* [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set
2025-06-23 8:02 fix virt_boundary_mask handling in SCSI Christoph Hellwig
@ 2025-06-23 8:02 ` Christoph Hellwig
2025-06-23 15:31 ` Bart Van Assche
2025-06-24 5:57 ` Hannes Reinecke
0 siblings, 2 replies; 10+ messages in thread
From: Christoph Hellwig @ 2025-06-23 8:02 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Bart Van Assche, Ming Lei, K. Y. Srinivasan, Haiyang Zhang,
Wei Liu, Ewan D. Milne, Laurence Oberman, linux-rdma, linux-scsi,
linux-block
virt_boundary_mask implies an unlimited max_segment_size. Setting both
can lead to data corruption, and we're going to check for this in the
SCSI midlayer soon.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/infiniband/ulp/srp/ib_srp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 1378651735f6..23ed2fc688f0 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -3705,9 +3705,10 @@ static ssize_t add_target_store(struct device *dev,
target_host->max_id = 1;
target_host->max_lun = -1LL;
target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
- target_host->max_segment_size = ib_dma_max_seg_size(ibdev);
- if (!(ibdev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG))
+ if (ibdev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG)
+ target_host->max_segment_size = ib_dma_max_seg_size(ibdev);
+ else
target_host->virt_boundary_mask = ~srp_dev->mr_page_mask;
target = host_to_target(target_host);
--
2.47.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set
2025-06-23 8:02 ` [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set Christoph Hellwig
@ 2025-06-23 15:31 ` Bart Van Assche
2025-06-24 5:57 ` Hannes Reinecke
1 sibling, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2025-06-23 15:31 UTC (permalink / raw)
To: Christoph Hellwig, Martin K. Petersen
Cc: Ming Lei, K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Ewan D. Milne,
Laurence Oberman, linux-rdma, linux-scsi, linux-block
On 6/23/25 1:02 AM, Christoph Hellwig wrote:
> virt_boundary_mask implies an unlimited max_segment_size. Setting both
> can lead to data corruption, and we're going to check for this in the
> SCSI midlayer soon.
Please make this patch description more detailed and mention that
__blk_rq_map_sg() may split sg-lists such that the virt_boundary_mask is
not respected if max_segment_size != UINT_MAX.
Thanks,
Bart.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set
2025-06-23 8:02 ` [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set Christoph Hellwig
2025-06-23 15:31 ` Bart Van Assche
@ 2025-06-24 5:57 ` Hannes Reinecke
1 sibling, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2025-06-24 5:57 UTC (permalink / raw)
To: Christoph Hellwig, Martin K. Petersen
Cc: Bart Van Assche, Ming Lei, K. Y. Srinivasan, Haiyang Zhang,
Wei Liu, Ewan D. Milne, Laurence Oberman, linux-rdma, linux-scsi,
linux-block
On 6/23/25 10:02, Christoph Hellwig wrote:
> virt_boundary_mask implies an unlimited max_segment_size. Setting both
> can lead to data corruption, and we're going to check for this in the
> SCSI midlayer soon.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> drivers/infiniband/ulp/srp/ib_srp.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
> index 1378651735f6..23ed2fc688f0 100644
> --- a/drivers/infiniband/ulp/srp/ib_srp.c
> +++ b/drivers/infiniband/ulp/srp/ib_srp.c
> @@ -3705,9 +3705,10 @@ static ssize_t add_target_store(struct device *dev,
> target_host->max_id = 1;
> target_host->max_lun = -1LL;
> target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
> - target_host->max_segment_size = ib_dma_max_seg_size(ibdev);
>
> - if (!(ibdev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG))
> + if (ibdev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG)
> + target_host->max_segment_size = ib_dma_max_seg_size(ibdev);
> + else
> target_host->virt_boundary_mask = ~srp_dev->mr_page_mask;
>
> target = host_to_target(target_host);
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
^ permalink raw reply [flat|nested] 10+ messages in thread
* fix virt_boundary_mask handling in SCSI v2
@ 2025-06-24 12:52 Christoph Hellwig
2025-06-24 12:52 ` [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set Christoph Hellwig
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Christoph Hellwig @ 2025-06-24 12:52 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Bart Van Assche, Ming Lei, K. Y. Srinivasan, Haiyang Zhang,
Wei Liu, Ewan D. Milne, Laurence Oberman, linux-rdma, linux-scsi,
linux-block
Hi all,
this series fixes a corruption when drivers using virt_boundary_mask set
a limited max_segment_size by accident, which Red Hat reported as causing
data corruption with storvsc. I did audit the tree and also found that
this can affect SRP and iSER as well.
Changes since v1:
- improve the srp commit log
- slightly simplify the limits assignment in hosts.c
Diffstat:
infiniband/ulp/srp/ib_srp.c | 5 +++--
scsi/hosts.c | 18 +++++++++++-------
2 files changed, 14 insertions(+), 9 deletions(-)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set
2025-06-24 12:52 fix virt_boundary_mask handling in SCSI v2 Christoph Hellwig
@ 2025-06-24 12:52 ` Christoph Hellwig
2025-06-24 13:25 ` John Garry
2025-06-24 15:54 ` Bart Van Assche
2025-06-24 12:52 ` [PATCH 2/2] scsi: enforce unlimited " Christoph Hellwig
2025-06-25 1:47 ` fix virt_boundary_mask handling in SCSI v2 Martin K. Petersen
2 siblings, 2 replies; 10+ messages in thread
From: Christoph Hellwig @ 2025-06-24 12:52 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Bart Van Assche, Ming Lei, K. Y. Srinivasan, Haiyang Zhang,
Wei Liu, Ewan D. Milne, Laurence Oberman, linux-rdma, linux-scsi,
linux-block, Hannes Reinecke
virt_boundary_mask implies an unlimited max_segment_size. Setting both
can lead to data corruption because __blk_rq_map_sg() can split requests
so that the virt_boundary_mask is not respected if max_segment_size is
not UINT_MAX.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
---
drivers/infiniband/ulp/srp/ib_srp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 1378651735f6..23ed2fc688f0 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -3705,9 +3705,10 @@ static ssize_t add_target_store(struct device *dev,
target_host->max_id = 1;
target_host->max_lun = -1LL;
target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
- target_host->max_segment_size = ib_dma_max_seg_size(ibdev);
- if (!(ibdev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG))
+ if (ibdev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG)
+ target_host->max_segment_size = ib_dma_max_seg_size(ibdev);
+ else
target_host->virt_boundary_mask = ~srp_dev->mr_page_mask;
target = host_to_target(target_host);
--
2.47.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/2] scsi: enforce unlimited max_segment_size when virt_boundary_mask is set
2025-06-24 12:52 fix virt_boundary_mask handling in SCSI v2 Christoph Hellwig
2025-06-24 12:52 ` [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set Christoph Hellwig
@ 2025-06-24 12:52 ` Christoph Hellwig
2025-06-24 15:56 ` Bart Van Assche
2025-06-25 1:47 ` fix virt_boundary_mask handling in SCSI v2 Martin K. Petersen
2 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2025-06-24 12:52 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Bart Van Assche, Ming Lei, K. Y. Srinivasan, Haiyang Zhang,
Wei Liu, Ewan D. Milne, Laurence Oberman, linux-rdma, linux-scsi,
linux-block, John Garry, Hannes Reinecke
The virt_boundary_mask limit requires an unlimited max_segment_size for
bio splitting to not corrupt data. Historically, the block layer tried
to validate this, although the check was half-hearted until the addition
of the atomic queue limits API. The full blown check than triggered
issues with stacked devices incorrectly inheriting limits such as the
virt boundary and got disabled in commit b561ea56a264 ("block: allow
device to have both virt_boundary_mask and max segment size") instead of
fixing the issue properly.
Ensure that the SCSI mid layer doesn't set the default low
max_segment_size limit for this case, and check for invalid
max_segment_size values in the host template, similar to the original
block layer check given that SCSI devices can't be stacked.
This fixes reported data corruption on storvsc, although as far as I can
tell storvsc always failed to properly set the max_segment_size limit as
the SCSI APIs historically applied that when setting up the host, while
storvsc only set the virt_boundary_mask when configuring the scsi_device.
Fixes: 81988a0e6b03 ("storvsc: get rid of bounce buffer")
Fixes: b561ea56a264 ("block: allow device to have both virt_boundary_mask and max segment size")
Reported-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
---
drivers/scsi/hosts.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index e021f1106bea..cc5d05dc395c 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -473,10 +473,17 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
else
shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS;
- if (sht->max_segment_size)
- shost->max_segment_size = sht->max_segment_size;
- else
- shost->max_segment_size = BLK_MAX_SEGMENT_SIZE;
+ shost->virt_boundary_mask = sht->virt_boundary_mask;
+ if (shost->virt_boundary_mask) {
+ WARN_ON_ONCE(sht->max_segment_size &&
+ sht->max_segment_size != UINT_MAX);
+ shost->max_segment_size = UINT_MAX;
+ } else {
+ if (sht->max_segment_size)
+ shost->max_segment_size = sht->max_segment_size;
+ else
+ shost->max_segment_size = BLK_MAX_SEGMENT_SIZE;
+ }
/* 32-byte (dword) is a common minimum for HBAs. */
if (sht->dma_alignment)
@@ -492,9 +499,6 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
else
shost->dma_boundary = 0xffffffff;
- if (sht->virt_boundary_mask)
- shost->virt_boundary_mask = sht->virt_boundary_mask;
-
device_initialize(&shost->shost_gendev);
dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
shost->shost_gendev.bus = &scsi_bus_type;
--
2.47.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set
2025-06-24 12:52 ` [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set Christoph Hellwig
@ 2025-06-24 13:25 ` John Garry
2025-06-24 15:54 ` Bart Van Assche
1 sibling, 0 replies; 10+ messages in thread
From: John Garry @ 2025-06-24 13:25 UTC (permalink / raw)
To: Christoph Hellwig, Martin K. Petersen
Cc: Bart Van Assche, Ming Lei, K. Y. Srinivasan, Haiyang Zhang,
Wei Liu, Ewan D. Milne, Laurence Oberman, linux-rdma, linux-scsi,
linux-block, Hannes Reinecke
On 24/06/2025 13:52, Christoph Hellwig wrote:
> virt_boundary_mask implies an unlimited max_segment_size. Setting both
> can lead to data corruption because __blk_rq_map_sg() can split requests
> so that the virt_boundary_mask is not respected if max_segment_size is
> not UINT_MAX.
>
> Signed-off-by: Christoph Hellwig<hch@lst.de>
> Reviewed-by: Hannes Reinecke<hare@suse.de>
Reviewed-by: John Garry <john.g.garry@oracle.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set
2025-06-24 12:52 ` [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set Christoph Hellwig
2025-06-24 13:25 ` John Garry
@ 2025-06-24 15:54 ` Bart Van Assche
1 sibling, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2025-06-24 15:54 UTC (permalink / raw)
To: Christoph Hellwig, Martin K. Petersen
Cc: Ming Lei, K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Ewan D. Milne,
Laurence Oberman, linux-rdma, linux-scsi, linux-block,
Hannes Reinecke
On 6/24/25 5:52 AM, Christoph Hellwig wrote:
> virt_boundary_mask implies an unlimited max_segment_size. Setting both
> can lead to data corruption because __blk_rq_map_sg() can split requests
> so that the virt_boundary_mask is not respected if max_segment_size is
> not UINT_MAX.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Hannes Reinecke <hare@suse.de>
> ---
> drivers/infiniband/ulp/srp/ib_srp.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
> index 1378651735f6..23ed2fc688f0 100644
> --- a/drivers/infiniband/ulp/srp/ib_srp.c
> +++ b/drivers/infiniband/ulp/srp/ib_srp.c
> @@ -3705,9 +3705,10 @@ static ssize_t add_target_store(struct device *dev,
> target_host->max_id = 1;
> target_host->max_lun = -1LL;
> target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
> - target_host->max_segment_size = ib_dma_max_seg_size(ibdev);
>
> - if (!(ibdev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG))
> + if (ibdev->attrs.kernel_cap_flags & IBK_SG_GAPS_REG)
> + target_host->max_segment_size = ib_dma_max_seg_size(ibdev);
> + else
> target_host->virt_boundary_mask = ~srp_dev->mr_page_mask;
>
> target = host_to_target(target_host);
Acked-by: Bart Van Assche <bvanassche@acm.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] scsi: enforce unlimited max_segment_size when virt_boundary_mask is set
2025-06-24 12:52 ` [PATCH 2/2] scsi: enforce unlimited " Christoph Hellwig
@ 2025-06-24 15:56 ` Bart Van Assche
0 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2025-06-24 15:56 UTC (permalink / raw)
To: Christoph Hellwig, Martin K. Petersen
Cc: Ming Lei, K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Ewan D. Milne,
Laurence Oberman, linux-rdma, linux-scsi, linux-block, John Garry,
Hannes Reinecke
On 6/24/25 5:52 AM, Christoph Hellwig wrote:
> diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
> index e021f1106bea..cc5d05dc395c 100644
> --- a/drivers/scsi/hosts.c
> +++ b/drivers/scsi/hosts.c
> @@ -473,10 +473,17 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
> else
> shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS;
>
> - if (sht->max_segment_size)
> - shost->max_segment_size = sht->max_segment_size;
> - else
> - shost->max_segment_size = BLK_MAX_SEGMENT_SIZE;
> + shost->virt_boundary_mask = sht->virt_boundary_mask;
> + if (shost->virt_boundary_mask) {
> + WARN_ON_ONCE(sht->max_segment_size &&
> + sht->max_segment_size != UINT_MAX);
> + shost->max_segment_size = UINT_MAX;
> + } else {
> + if (sht->max_segment_size)
> + shost->max_segment_size = sht->max_segment_size;
> + else
> + shost->max_segment_size = BLK_MAX_SEGMENT_SIZE;
> + }
>
> /* 32-byte (dword) is a common minimum for HBAs. */
> if (sht->dma_alignment)
> @@ -492,9 +499,6 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
> else
> shost->dma_boundary = 0xffffffff;
>
> - if (sht->virt_boundary_mask)
> - shost->virt_boundary_mask = sht->virt_boundary_mask;
> -
> device_initialize(&shost->shost_gendev);
> dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
> shost->shost_gendev.bus = &scsi_bus_type;
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: fix virt_boundary_mask handling in SCSI v2
2025-06-24 12:52 fix virt_boundary_mask handling in SCSI v2 Christoph Hellwig
2025-06-24 12:52 ` [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set Christoph Hellwig
2025-06-24 12:52 ` [PATCH 2/2] scsi: enforce unlimited " Christoph Hellwig
@ 2025-06-25 1:47 ` Martin K. Petersen
2 siblings, 0 replies; 10+ messages in thread
From: Martin K. Petersen @ 2025-06-25 1:47 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Martin K . Petersen, Bart Van Assche, Ming Lei, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Ewan D. Milne, Laurence Oberman,
linux-rdma, linux-scsi, linux-block
On Tue, 24 Jun 2025 14:52:26 +0200, Christoph Hellwig wrote:
> this series fixes a corruption when drivers using virt_boundary_mask set
> a limited max_segment_size by accident, which Red Hat reported as causing
> data corruption with storvsc. I did audit the tree and also found that
> this can affect SRP and iSER as well.
>
> Changes since v1:
> - improve the srp commit log
> - slightly simplify the limits assignment in hosts.c
>
> [...]
Applied to 6.16/scsi-fixes, thanks!
[1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set
https://git.kernel.org/mkp/scsi/c/844c6a160e69
[2/2] scsi: enforce unlimited max_segment_size when virt_boundary_mask is set
https://git.kernel.org/mkp/scsi/c/4937e604ca24
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-06-25 1:48 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-24 12:52 fix virt_boundary_mask handling in SCSI v2 Christoph Hellwig
2025-06-24 12:52 ` [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set Christoph Hellwig
2025-06-24 13:25 ` John Garry
2025-06-24 15:54 ` Bart Van Assche
2025-06-24 12:52 ` [PATCH 2/2] scsi: enforce unlimited " Christoph Hellwig
2025-06-24 15:56 ` Bart Van Assche
2025-06-25 1:47 ` fix virt_boundary_mask handling in SCSI v2 Martin K. Petersen
-- strict thread matches above, loose matches on Subject: below --
2025-06-23 8:02 fix virt_boundary_mask handling in SCSI Christoph Hellwig
2025-06-23 8:02 ` [PATCH 1/2] RDMA/srp: don't set a max_segment_size when virt_boundary_mask is set Christoph Hellwig
2025-06-23 15:31 ` Bart Van Assche
2025-06-24 5:57 ` Hannes Reinecke
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).