if driver reads data larger than VIRTIO_BLK_F_SIZE_MAX,
it will cause some issue to the DMA engine.
So when upper software wants to read data larger than
VIRTIO_BLK_F_SIZE_MAX, virtio-blk driver split one large
request into multiple smaller ones.
Signed-off-by: Andy Pei <andy.pei@intel.com>
Signed-off-by: Ding Limin <dinglimin@cmss.chinamobile.com>
---
src/hw/virtio-blk.c | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c
index 82b1d2a..929ba88 100644
--- a/src/hw/virtio-blk.c
+++ b/src/hw/virtio-blk.c
@@ -24,6 +24,11 @@
#include "virtio-ring.h"
#include "virtio-blk.h"
+#define min(a, b) ({\
+ typeof(a) _a = a;\
+ typeof(b) _b = b;\
+ _a < _b ? _a : _b; })
+
struct virtiodrive_s {
struct drive_s drive;
struct vring_virtqueue *vq;
@@ -82,8 +87,36 @@ virtio_blk_op(struct disk_op_s *op, int write)
.length = sizeof(status),
},
};
+ u32 max_io_size =
+ vdrive->drive.max_segment_size * vdrive->drive.max_segments;
+ u16 blk_num_max;
+
+ if (vdrive->drive.blksize != 0 && max_io_size != 0)
+ blk_num_max = (u16)max_io_size / vdrive->drive.blksize;
+ else
+ /* default blk_num_max if hardware doesnot advise a proper value */
+ blk_num_max = 8;
- virtio_blk_op_one_segment(vdrive, write, sg);
+ if (op->count <= blk_num_max) {
+ virtio_blk_op_one_segment(vdrive, write, sg);
+ } else {
+ void *p = op->buf_fl;
+ u16 count = op->count;
+
+ while (count > 0) {
+ u16 blk_num = min(count, blk_num_max);
+ sg[1].length = vdrive->drive.blksize * blk_num;
+ sg[1].addr = p;
+ virtio_blk_op_one_segment(vdrive, write, sg);
+ if (status == VIRTIO_BLK_S_OK) {
+ hdr.sector += blk_num;
+ p += sg[1].length;
+ count -= blk_num;
+ } else {
+ break;
+ }
+ }
+ }
return status == VIRTIO_BLK_S_OK ? DISK_RET_SUCCESS : DISK_RET_EBADTRACK;
}
--
1.8.3.1
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
On Tue, Dec 07, 2021 at 09:31:08AM +0800, Andy Pei wrote: > if driver reads data larger than VIRTIO_BLK_F_SIZE_MAX, > it will cause some issue to the DMA engine. > > So when upper software wants to read data larger than > VIRTIO_BLK_F_SIZE_MAX, virtio-blk driver split one large > request into multiple smaller ones. > > Signed-off-by: Andy Pei <andy.pei@intel.com> > Signed-off-by: Ding Limin <dinglimin@cmss.chinamobile.com> Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
Hi Gerd, Thanks for your effort. -----Original Message----- From: Gerd Hoffmann <kraxel@redhat.com> Sent: Tuesday, December 7, 2021 4:28 PM To: Pei, Andy <andy.pei@intel.com> Cc: seabios@seabios.org; kevin@koconnor.net; Ding Limin <dinglimin@cmss.chinamobile.com> Subject: Re: [PATCH v4 3/3] virtio-blk.: split large IO according to size_max On Tue, Dec 07, 2021 at 09:31:08AM +0800, Andy Pei wrote: > if driver reads data larger than VIRTIO_BLK_F_SIZE_MAX, it will cause > some issue to the DMA engine. > > So when upper software wants to read data larger than > VIRTIO_BLK_F_SIZE_MAX, virtio-blk driver split one large request into > multiple smaller ones. > > Signed-off-by: Andy Pei <andy.pei@intel.com> > Signed-off-by: Ding Limin <dinglimin@cmss.chinamobile.com> Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
© 2016 - 2023 Red Hat, Inc.