* [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization
@ 2015-11-09 9:03 arei.gonglei
2015-11-09 13:28 ` Paolo Bonzini
2015-11-09 13:57 ` Stefan Hajnoczi
0 siblings, 2 replies; 7+ messages in thread
From: arei.gonglei @ 2015-11-09 9:03 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, Gonglei, qemu-block, stefanha
From: Gonglei <arei.gonglei@huawei.com>
1. avoid possible superflous checking
2. make code more robustness
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
---
v3: change the third condition too [Paolo]
add Fam's R-by
---
hw/block/virtio-blk.c | 27 +++++++++------------------
1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 093e475..9124358 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -404,24 +404,15 @@ void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb)
for (i = 0; i < mrb->num_reqs; i++) {
VirtIOBlockReq *req = mrb->reqs[i];
if (num_reqs > 0) {
- bool merge = true;
-
- /* merge would exceed maximum number of IOVs */
- if (niov + req->qiov.niov > IOV_MAX) {
- merge = false;
- }
-
- /* merge would exceed maximum transfer length of backend device */
- if (req->qiov.size / BDRV_SECTOR_SIZE + nb_sectors > max_xfer_len) {
- merge = false;
- }
-
- /* requests are not sequential */
- if (sector_num + nb_sectors != req->sector_num) {
- merge = false;
- }
-
- if (!merge) {
+ /*
+ * NOTE: We cannot merge the requests in below situations:
+ * 1. requests are not sequential
+ * 2. merge would exceed maximum number of IOVs
+ * 3. merge would exceed maximum transfer length of backend device
+ */
+ if (sector_num + nb_sectors != req->sector_num ||
+ niov > IOV_MAX - req->qiov.niov ||
+ nb_sectors > max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE) {
submit_requests(blk, mrb, start, num_reqs, niov);
num_reqs = 0;
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization 2015-11-09 9:03 [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization arei.gonglei @ 2015-11-09 13:28 ` Paolo Bonzini 2015-11-09 13:57 ` Stefan Hajnoczi 1 sibling, 0 replies; 7+ messages in thread From: Paolo Bonzini @ 2015-11-09 13:28 UTC (permalink / raw) To: arei.gonglei, qemu-devel; +Cc: qemu-block, stefanha On 09/11/2015 10:03, arei.gonglei@huawei.com wrote: > From: Gonglei <arei.gonglei@huawei.com> > > 1. avoid possible superflous checking > 2. make code more robustness > > Signed-off-by: Gonglei <arei.gonglei@huawei.com> > Reviewed-by: Fam Zheng <famz@redhat.com> > --- > v3: change the third condition too [Paolo] > add Fam's R-by > --- > hw/block/virtio-blk.c | 27 +++++++++------------------ > 1 file changed, 9 insertions(+), 18 deletions(-) > > diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c > index 093e475..9124358 100644 > --- a/hw/block/virtio-blk.c > +++ b/hw/block/virtio-blk.c > @@ -404,24 +404,15 @@ void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) > for (i = 0; i < mrb->num_reqs; i++) { > VirtIOBlockReq *req = mrb->reqs[i]; > if (num_reqs > 0) { > - bool merge = true; > - > - /* merge would exceed maximum number of IOVs */ > - if (niov + req->qiov.niov > IOV_MAX) { > - merge = false; > - } > - > - /* merge would exceed maximum transfer length of backend device */ > - if (req->qiov.size / BDRV_SECTOR_SIZE + nb_sectors > max_xfer_len) { > - merge = false; > - } > - > - /* requests are not sequential */ > - if (sector_num + nb_sectors != req->sector_num) { > - merge = false; > - } > - > - if (!merge) { > + /* > + * NOTE: We cannot merge the requests in below situations: > + * 1. requests are not sequential > + * 2. merge would exceed maximum number of IOVs > + * 3. merge would exceed maximum transfer length of backend device > + */ > + if (sector_num + nb_sectors != req->sector_num || > + niov > IOV_MAX - req->qiov.niov || > + nb_sectors > max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE) { > submit_requests(blk, mrb, start, num_reqs, niov); > num_reqs = 0; > } > Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization 2015-11-09 9:03 [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization arei.gonglei 2015-11-09 13:28 ` Paolo Bonzini @ 2015-11-09 13:57 ` Stefan Hajnoczi 2015-11-10 6:35 ` Gonglei 1 sibling, 1 reply; 7+ messages in thread From: Stefan Hajnoczi @ 2015-11-09 13:57 UTC (permalink / raw) To: arei.gonglei; +Cc: pbonzini, qemu-devel, qemu-block [-- Attachment #1: Type: text/plain, Size: 2374 bytes --] On Mon, Nov 09, 2015 at 05:03:30PM +0800, arei.gonglei@huawei.com wrote: > From: Gonglei <arei.gonglei@huawei.com> > > 1. avoid possible superflous checking > 2. make code more robustness > > Signed-off-by: Gonglei <arei.gonglei@huawei.com> > Reviewed-by: Fam Zheng <famz@redhat.com> > --- > v3: change the third condition too [Paolo] > add Fam's R-by > --- > hw/block/virtio-blk.c | 27 +++++++++------------------ > 1 file changed, 9 insertions(+), 18 deletions(-) > > diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c > index 093e475..9124358 100644 > --- a/hw/block/virtio-blk.c > +++ b/hw/block/virtio-blk.c > @@ -404,24 +404,15 @@ void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) > for (i = 0; i < mrb->num_reqs; i++) { > VirtIOBlockReq *req = mrb->reqs[i]; > if (num_reqs > 0) { > - bool merge = true; > - > - /* merge would exceed maximum number of IOVs */ > - if (niov + req->qiov.niov > IOV_MAX) { > - merge = false; > - } > - > - /* merge would exceed maximum transfer length of backend device */ > - if (req->qiov.size / BDRV_SECTOR_SIZE + nb_sectors > max_xfer_len) { > - merge = false; > - } > - > - /* requests are not sequential */ > - if (sector_num + nb_sectors != req->sector_num) { > - merge = false; > - } > - > - if (!merge) { > + /* > + * NOTE: We cannot merge the requests in below situations: > + * 1. requests are not sequential > + * 2. merge would exceed maximum number of IOVs > + * 3. merge would exceed maximum transfer length of backend device > + */ > + if (sector_num + nb_sectors != req->sector_num || > + niov > IOV_MAX - req->qiov.niov || > + nb_sectors > max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE) { nb_sectors - int max_xfer_len - int req->qiov.size - size_t BDRV_SECTOR_SIZE - unsigned long long Therefore this expression is an int > unsigned long long comparison. req->qiov.size can be larger than max_xfer_len so this comparison suffers from underflow. Please check that req->qiov.size <= max_xfer_len first. Stefan [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization 2015-11-09 13:57 ` Stefan Hajnoczi @ 2015-11-10 6:35 ` Gonglei 2015-11-10 9:51 ` Paolo Bonzini 2015-11-10 9:56 ` Stefan Hajnoczi 0 siblings, 2 replies; 7+ messages in thread From: Gonglei @ 2015-11-10 6:35 UTC (permalink / raw) To: Stefan Hajnoczi; +Cc: pbonzini, qemu-devel, qemu-block On 2015/11/9 21:57, Stefan Hajnoczi wrote: > On Mon, Nov 09, 2015 at 05:03:30PM +0800, arei.gonglei@huawei.com wrote: >> From: Gonglei <arei.gonglei@huawei.com> >> >> 1. avoid possible superflous checking >> 2. make code more robustness >> >> Signed-off-by: Gonglei <arei.gonglei@huawei.com> >> Reviewed-by: Fam Zheng <famz@redhat.com> >> --- >> v3: change the third condition too [Paolo] >> add Fam's R-by >> --- >> hw/block/virtio-blk.c | 27 +++++++++------------------ >> 1 file changed, 9 insertions(+), 18 deletions(-) >> >> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c >> index 093e475..9124358 100644 >> --- a/hw/block/virtio-blk.c >> +++ b/hw/block/virtio-blk.c >> @@ -404,24 +404,15 @@ void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) >> for (i = 0; i < mrb->num_reqs; i++) { >> VirtIOBlockReq *req = mrb->reqs[i]; >> if (num_reqs > 0) { >> - bool merge = true; >> - >> - /* merge would exceed maximum number of IOVs */ >> - if (niov + req->qiov.niov > IOV_MAX) { >> - merge = false; >> - } >> - >> - /* merge would exceed maximum transfer length of backend device */ >> - if (req->qiov.size / BDRV_SECTOR_SIZE + nb_sectors > max_xfer_len) { >> - merge = false; >> - } >> - >> - /* requests are not sequential */ >> - if (sector_num + nb_sectors != req->sector_num) { >> - merge = false; >> - } >> - >> - if (!merge) { >> + /* >> + * NOTE: We cannot merge the requests in below situations: >> + * 1. requests are not sequential >> + * 2. merge would exceed maximum number of IOVs >> + * 3. merge would exceed maximum transfer length of backend device >> + */ >> + if (sector_num + nb_sectors != req->sector_num || >> + niov > IOV_MAX - req->qiov.niov || >> + nb_sectors > max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE) { > > nb_sectors - int > max_xfer_len - int > req->qiov.size - size_t > BDRV_SECTOR_SIZE - unsigned long long > > Therefore this expression is an int > unsigned long long comparison. > Sorry, I'm confused. max_xfer_len is int, "req->qiov.size / BDRV_SECTOR_SIZE" is unsigned long long, so, "max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE" will be int, and nb_sectors is int too, so this comparison is right. Am I wrong? > req->qiov.size can be larger than max_xfer_len so this comparison > suffers from underflow. Please check that req->qiov.size <= > max_xfer_len first. > Regards, -Gonglei ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization 2015-11-10 6:35 ` Gonglei @ 2015-11-10 9:51 ` Paolo Bonzini 2015-11-10 9:56 ` Stefan Hajnoczi 1 sibling, 0 replies; 7+ messages in thread From: Paolo Bonzini @ 2015-11-10 9:51 UTC (permalink / raw) To: Gonglei, Stefan Hajnoczi; +Cc: qemu-devel, qemu-block On 10/11/2015 07:35, Gonglei wrote: >> > nb_sectors - int >> > max_xfer_len - int >> > req->qiov.size - size_t >> > BDRV_SECTOR_SIZE - unsigned long long >> > >> > Therefore this expression is an int > unsigned long long comparison. >> > > Sorry, I'm confused. > max_xfer_len is int, > "req->qiov.size / BDRV_SECTOR_SIZE" is unsigned long long, > so, "max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE" will be int, No, the result will be unsigned long long, and the comparison is wrong if max_xfer_len < req->qiov.size / BDRV_SECTOR_SIZE. Paolo > and nb_sectors is int too, so this comparison is right. Am I wrong? > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization 2015-11-10 6:35 ` Gonglei 2015-11-10 9:51 ` Paolo Bonzini @ 2015-11-10 9:56 ` Stefan Hajnoczi 2015-11-11 1:53 ` Gonglei 1 sibling, 1 reply; 7+ messages in thread From: Stefan Hajnoczi @ 2015-11-10 9:56 UTC (permalink / raw) To: Gonglei; +Cc: pbonzini, qemu-devel, qemu-block [-- Attachment #1: Type: text/plain, Size: 3541 bytes --] On Tue, Nov 10, 2015 at 02:35:19PM +0800, Gonglei wrote: > On 2015/11/9 21:57, Stefan Hajnoczi wrote: > > On Mon, Nov 09, 2015 at 05:03:30PM +0800, arei.gonglei@huawei.com wrote: > >> From: Gonglei <arei.gonglei@huawei.com> > >> > >> 1. avoid possible superflous checking > >> 2. make code more robustness > >> > >> Signed-off-by: Gonglei <arei.gonglei@huawei.com> > >> Reviewed-by: Fam Zheng <famz@redhat.com> > >> --- > >> v3: change the third condition too [Paolo] > >> add Fam's R-by > >> --- > >> hw/block/virtio-blk.c | 27 +++++++++------------------ > >> 1 file changed, 9 insertions(+), 18 deletions(-) > >> > >> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c > >> index 093e475..9124358 100644 > >> --- a/hw/block/virtio-blk.c > >> +++ b/hw/block/virtio-blk.c > >> @@ -404,24 +404,15 @@ void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) > >> for (i = 0; i < mrb->num_reqs; i++) { > >> VirtIOBlockReq *req = mrb->reqs[i]; > >> if (num_reqs > 0) { > >> - bool merge = true; > >> - > >> - /* merge would exceed maximum number of IOVs */ > >> - if (niov + req->qiov.niov > IOV_MAX) { > >> - merge = false; > >> - } > >> - > >> - /* merge would exceed maximum transfer length of backend device */ > >> - if (req->qiov.size / BDRV_SECTOR_SIZE + nb_sectors > max_xfer_len) { > >> - merge = false; > >> - } > >> - > >> - /* requests are not sequential */ > >> - if (sector_num + nb_sectors != req->sector_num) { > >> - merge = false; > >> - } > >> - > >> - if (!merge) { > >> + /* > >> + * NOTE: We cannot merge the requests in below situations: > >> + * 1. requests are not sequential > >> + * 2. merge would exceed maximum number of IOVs > >> + * 3. merge would exceed maximum transfer length of backend device > >> + */ > >> + if (sector_num + nb_sectors != req->sector_num || > >> + niov > IOV_MAX - req->qiov.niov || > >> + nb_sectors > max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE) { > > > > nb_sectors - int > > max_xfer_len - int > > req->qiov.size - size_t > > BDRV_SECTOR_SIZE - unsigned long long > > > > Therefore this expression is an int > unsigned long long comparison. > > > Sorry, I'm confused. > max_xfer_len is int, > "req->qiov.size / BDRV_SECTOR_SIZE" is unsigned long long, > so, "max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE" will be int, The type of "max_xfer_len - req->qiov.size / BDRV_SECTOR_SIZE" cannot be int because you said req->qiov.size / BDRV_SECTOR_SIZE" is unsigned long long. The C99 standard says: 6.3.1.1 Boolean, characters, and integers - The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision. ... - The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any. 6.3.1.8 Usual arithmetic conversions Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type. So the max_xfer_len int operand must be converted to the higher ranking unsigned long long. Stefan [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization 2015-11-10 9:56 ` Stefan Hajnoczi @ 2015-11-11 1:53 ` Gonglei 0 siblings, 0 replies; 7+ messages in thread From: Gonglei @ 2015-11-11 1:53 UTC (permalink / raw) To: Stefan Hajnoczi; +Cc: pbonzini, qemu-devel, qemu-block On 2015/11/10 17:56, Stefan Hajnoczi wrote: > The C99 standard says: > > 6.3.1.1 Boolean, characters, and integers > > - The rank of a signed integer type shall be greater than the rank of > any signed integer type with less precision. > > ... > > - The rank of any unsigned integer type shall equal the rank of the > corresponding signed integer type, if any. > > 6.3.1.8 Usual arithmetic conversions > > Otherwise, if the operand that has unsigned integer type has rank > greater or equal to the rank of the type of the other operand, then the > operand with signed integer type is converted to the type of the operand > with unsigned integer type. > > So the max_xfer_len int operand must be converted to the higher ranking > unsigned long long. > Thank you so much, it's clear. I'll add a check before subtraction. Please review v4. Regards, -Gonglei ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-11-11 1:56 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-11-09 9:03 [Qemu-devel] [PATCH v3] virtio-blk: trivial code optimization arei.gonglei 2015-11-09 13:28 ` Paolo Bonzini 2015-11-09 13:57 ` Stefan Hajnoczi 2015-11-10 6:35 ` Gonglei 2015-11-10 9:51 ` Paolo Bonzini 2015-11-10 9:56 ` Stefan Hajnoczi 2015-11-11 1:53 ` Gonglei
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.