Message ID | 20190123163049.24863-6-joro@8bytes.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fix virtio-blk issue with SWIOTLB | expand |
On Wed, Jan 23, 2019 at 05:30:49PM +0100, Joerg Roedel wrote: > + max_size = virtio_max_dma_size(vdev); > + > /* Host can optionally specify maximum segment size and number of > * segments. */ > err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SIZE_MAX, > struct virtio_blk_config, size_max, &v); > if (!err) > - blk_queue_max_segment_size(q, v); > - else > - blk_queue_max_segment_size(q, -1U); > + max_size = min(max_size, v); > + > + blk_queue_max_segment_size(q, max_size); I wonder if we should just move the dma max segment size check into blk_queue_max_segment_size so that all block drivers benefit from it. Even if not I think at least the SCSI midlayer should be updated to support it. Btw, I wonder why virtio-scsi sticks to the default segment size, unlike virtio-blk.
On Wed, Jan 23, 2019 at 10:31:39PM +0100, Christoph Hellwig wrote: > On Wed, Jan 23, 2019 at 05:30:49PM +0100, Joerg Roedel wrote: > > + max_size = virtio_max_dma_size(vdev); > > + > > /* Host can optionally specify maximum segment size and number of > > * segments. */ > > err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SIZE_MAX, > > struct virtio_blk_config, size_max, &v); > > if (!err) > > - blk_queue_max_segment_size(q, v); > > - else > > - blk_queue_max_segment_size(q, -1U); > > + max_size = min(max_size, v); > > + > > + blk_queue_max_segment_size(q, max_size); > > I wonder if we should just move the dma max segment size check > into blk_queue_max_segment_size so that all block drivers benefit > from it. Even if not I think at least the SCSI midlayer should > be updated to support it. > > Btw, I wonder why virtio-scsi sticks to the default segment size, > unlike virtio-blk. Well no one bothered exposing that through that device. Why does virtio block have it? Hard for me to say. First driver version had it already but QEMU does not seem to use it and it seems that it never did.
On Wed, Jan 23, 2019 at 10:31:39PM +0100, Christoph Hellwig wrote: > On Wed, Jan 23, 2019 at 05:30:49PM +0100, Joerg Roedel wrote: > > + max_size = virtio_max_dma_size(vdev); > > + > > /* Host can optionally specify maximum segment size and number of > > * segments. */ > > err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SIZE_MAX, > > struct virtio_blk_config, size_max, &v); > > if (!err) > > - blk_queue_max_segment_size(q, v); > > - else > > - blk_queue_max_segment_size(q, -1U); > > + max_size = min(max_size, v); > > + > > + blk_queue_max_segment_size(q, max_size); > > I wonder if we should just move the dma max segment size check > into blk_queue_max_segment_size so that all block drivers benefit > from it. Even if not I think at least the SCSI midlayer should > be updated to support it. In that case the limit would also apply to virtio-blk even if it doesn't use the DMA-API. If that is acceptable we can move the check to blk_queue_max_segment_size(). Regards, Joerg
On Thu, Jan 24, 2019 at 09:40:11AM +0100, Joerg Roedel wrote: > > I wonder if we should just move the dma max segment size check > > into blk_queue_max_segment_size so that all block drivers benefit > > from it. Even if not I think at least the SCSI midlayer should > > be updated to support it. > > In that case the limit would also apply to virtio-blk even if it doesn't > use the DMA-API. If that is acceptable we can move the check to > blk_queue_max_segment_size(). Yes. But more importantly it would fix the limit for all other block drivers that set large segment sizes when running over swiotlb.
On Thu, Jan 24, 2019 at 09:42:21AM +0100, Christoph Hellwig wrote: > Yes. But more importantly it would fix the limit for all other block > drivers that set large segment sizes when running over swiotlb. True, so it would be something like the diff below? I havn't worked on the block layer, so I don't know if that needs additional checks for ->dev or anything. diff --git a/block/blk-settings.c b/block/blk-settings.c index 3e7038e475ee..9a927280c904 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -1,6 +1,7 @@ /* * Functions related to setting various queue properties from drivers */ +#include <linux/dma-mapping.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -303,13 +304,17 @@ EXPORT_SYMBOL_GPL(blk_queue_max_discard_segments); **/ void blk_queue_max_segment_size(struct request_queue *q, unsigned int max_size) { + unsigned int dma_max_size; + if (max_size < PAGE_SIZE) { max_size = PAGE_SIZE; printk(KERN_INFO "%s: set to minimum %d\n", __func__, max_size); } - q->limits.max_segment_size = max_size; + dma_max_size = dma_max_mapping_size(q->backing_dev_info->dev); + + q->limits.max_segment_size = min(max_size, dma_max_size); } EXPORT_SYMBOL(blk_queue_max_segment_size);
On Thu, Jan 24, 2019 at 10:51:51AM +0100, Joerg Roedel wrote: > On Thu, Jan 24, 2019 at 09:42:21AM +0100, Christoph Hellwig wrote: > > Yes. But more importantly it would fix the limit for all other block > > drivers that set large segment sizes when running over swiotlb. > > True, so it would be something like the diff below? I havn't worked on > the block layer, so I don't know if that needs additional checks for > ->dev or anything. Looks sensible. Maybe for now we'll just do the virtio-blk case that triggered it, and we'll do something like this patch for the next merge window. We'll also need to apply the same magic to the DMA boundary.
On Mon, Jan 28, 2019 at 09:05:26AM +0100, Christoph Hellwig wrote: > On Thu, Jan 24, 2019 at 10:51:51AM +0100, Joerg Roedel wrote: > > On Thu, Jan 24, 2019 at 09:42:21AM +0100, Christoph Hellwig wrote: > > > Yes. But more importantly it would fix the limit for all other block > > > drivers that set large segment sizes when running over swiotlb. > > > > True, so it would be something like the diff below? I havn't worked on > > the block layer, so I don't know if that needs additional checks for > > ->dev or anything. > > Looks sensible. Maybe for now we'll just do the virtio-blk case > that triggered it, and we'll do something like this patch for the > next merge window. We'll also need to apply the same magic to the > DMA boundary. So do I get an ack for this patch then?
On Mon, Jan 28, 2019 at 12:14:33PM -0500, Michael S. Tsirkin wrote: > On Mon, Jan 28, 2019 at 09:05:26AM +0100, Christoph Hellwig wrote: > > On Thu, Jan 24, 2019 at 10:51:51AM +0100, Joerg Roedel wrote: > > > On Thu, Jan 24, 2019 at 09:42:21AM +0100, Christoph Hellwig wrote: > > > > Yes. But more importantly it would fix the limit for all other block > > > > drivers that set large segment sizes when running over swiotlb. > > > > > > True, so it would be something like the diff below? I havn't worked on > > > the block layer, so I don't know if that needs additional checks for > > > ->dev or anything. > > > > Looks sensible. Maybe for now we'll just do the virtio-blk case > > that triggered it, and we'll do something like this patch for the > > next merge window. We'll also need to apply the same magic to the > > DMA boundary. > > So do I get an ack for this patch then? I'll wait for a resend of the series to review the whole thing.
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index b16a887bbd02..4bc083b7c9b5 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -723,7 +723,7 @@ static int virtblk_probe(struct virtio_device *vdev) struct request_queue *q; int err, index; - u32 v, blk_size, sg_elems, opt_io_size; + u32 v, blk_size, max_size, sg_elems, opt_io_size; u16 min_io_size; u8 physical_block_exp, alignment_offset; @@ -826,14 +826,16 @@ static int virtblk_probe(struct virtio_device *vdev) /* No real sector limit. */ blk_queue_max_hw_sectors(q, -1U); + max_size = virtio_max_dma_size(vdev); + /* Host can optionally specify maximum segment size and number of * segments. */ err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SIZE_MAX, struct virtio_blk_config, size_max, &v); if (!err) - blk_queue_max_segment_size(q, v); - else - blk_queue_max_segment_size(q, -1U); + max_size = min(max_size, v); + + blk_queue_max_segment_size(q, max_size); /* Host can optionally specify the block size of the device */ err = virtio_cread_feature(vdev, VIRTIO_BLK_F_BLK_SIZE,