All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.