diff mbox series

[RFC,v2,03/10] vringh: reset kiov 'consumed' field in __vringh_iov()

Message ID 20210128144127.113245-4-sgarzare@redhat.com (mailing list archive)
State New, archived
Headers show
Series vdpa: add vdpa simulator for block device | expand

Commit Message

Stefano Garzarella Jan. 28, 2021, 2:41 p.m. UTC
__vringh_iov() overwrites the contents of riov and wiov, in fact it
resets the 'i' and 'used' fields, but also the consumed field should
be reset to avoid an inconsistent state.

Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
 drivers/vhost/vringh.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Jason Wang Feb. 1, 2021, 5:40 a.m. UTC | #1
On 2021/1/28 下午10:41, Stefano Garzarella wrote:
> __vringh_iov() overwrites the contents of riov and wiov, in fact it
> resets the 'i' and 'used' fields, but also the consumed field should
> be reset to avoid an inconsistent state.
>
> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>


I had a question(I remember we had some discussion like this but I 
forget the conclusion):

I see e.g in vringh_getdesc_kern() it has the following comment:

/*
  * Note that you may need to clean up riov and wiov, even on error!
  */

So it looks to me the correct way is to call vringh_kiov_cleanup() before?

Thanks


> ---
>   drivers/vhost/vringh.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
> index f68122705719..bee63d68201a 100644
> --- a/drivers/vhost/vringh.c
> +++ b/drivers/vhost/vringh.c
> @@ -290,9 +290,9 @@ __vringh_iov(struct vringh *vrh, u16 i,
>   		return -EINVAL;
>   
>   	if (riov)
> -		riov->i = riov->used = 0;
> +		riov->i = riov->used = riov->consumed = 0;
>   	if (wiov)
> -		wiov->i = wiov->used = 0;
> +		wiov->i = wiov->used = wiov->consumed = 0;
>   
>   	for (;;) {
>   		void *addr;
Stefano Garzarella Feb. 1, 2021, 10:21 a.m. UTC | #2
On Mon, Feb 01, 2021 at 01:40:01PM +0800, Jason Wang wrote:
>
>On 2021/1/28 下午10:41, Stefano Garzarella wrote:
>>__vringh_iov() overwrites the contents of riov and wiov, in fact it
>>resets the 'i' and 'used' fields, but also the consumed field should
>>be reset to avoid an inconsistent state.
>>
>>Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
>
>
>I had a question(I remember we had some discussion like this but I 
>forget the conclusion):

Sorry, I forgot to update you.

>
>I see e.g in vringh_getdesc_kern() it has the following comment:
>
>/*
> * Note that you may need to clean up riov and wiov, even on error!
> */
>
>So it looks to me the correct way is to call vringh_kiov_cleanup() 
>before?

Looking at the code the right pattern should be:

     vringh_getdesc_*(..., &out_iov, &in_iov, ...);

     // use out_iov and in_iov

     vringh_kiov_cleanup(&out_iov);
     vringh_kiov_cleanup(&in_iov);

This because vringh_getdesc_*() calls __vringh_iov() where 
resize_iovec() is called to allocate the iov wrapped by 'struct 
vringh_kiov' and vringh_kiov_cleanup() frees that memory.

Looking better, __vringh_iov() is able to extend a 'vringh_kiov' 
pre-allocated, so in order to avoid to allocate and free the iov for 
each request we can avoid to call vringh_kiov_cleanup(), but this patch 
is needed to avoid an inconsistent state.

And also patch "vdpa_sim: cleanup kiovs in vdpasim_free()" is required 
to free the iov when the device is going away.

Does that make sense to you?

Maybe I should add a comment in vringh.c to explain this better.

Thanks,
Stefano

>
>Thanks
>
>
>>---
>>  drivers/vhost/vringh.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>>diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
>>index f68122705719..bee63d68201a 100644
>>--- a/drivers/vhost/vringh.c
>>+++ b/drivers/vhost/vringh.c
>>@@ -290,9 +290,9 @@ __vringh_iov(struct vringh *vrh, u16 i,
>>  		return -EINVAL;
>>  	if (riov)
>>-		riov->i = riov->used = 0;
>>+		riov->i = riov->used = riov->consumed = 0;
>>  	if (wiov)
>>-		wiov->i = wiov->used = 0;
>>+		wiov->i = wiov->used = wiov->consumed = 0;
>>  	for (;;) {
>>  		void *addr;
>
Jason Wang Feb. 2, 2021, 3:26 a.m. UTC | #3
On 2021/2/1 下午6:21, Stefano Garzarella wrote:
> On Mon, Feb 01, 2021 at 01:40:01PM +0800, Jason Wang wrote:
>>
>> On 2021/1/28 下午10:41, Stefano Garzarella wrote:
>>> __vringh_iov() overwrites the contents of riov and wiov, in fact it
>>> resets the 'i' and 'used' fields, but also the consumed field should
>>> be reset to avoid an inconsistent state.
>>>
>>> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
>>
>>
>> I had a question(I remember we had some discussion like this but I 
>> forget the conclusion):
>
> Sorry, I forgot to update you.
>
>>
>> I see e.g in vringh_getdesc_kern() it has the following comment:
>>
>> /*
>>  * Note that you may need to clean up riov and wiov, even on error!
>>  */
>>
>> So it looks to me the correct way is to call vringh_kiov_cleanup() 
>> before?
>
> Looking at the code the right pattern should be:
>
>     vringh_getdesc_*(..., &out_iov, &in_iov, ...);
>
>     // use out_iov and in_iov
>
>     vringh_kiov_cleanup(&out_iov);
>     vringh_kiov_cleanup(&in_iov);
>
> This because vringh_getdesc_*() calls __vringh_iov() where 
> resize_iovec() is called to allocate the iov wrapped by 'struct 
> vringh_kiov' and vringh_kiov_cleanup() frees that memory.
>
> Looking better, __vringh_iov() is able to extend a 'vringh_kiov' 
> pre-allocated, so in order to avoid to allocate and free the iov for 
> each request we can avoid to call vringh_kiov_cleanup(), but this 
> patch is needed to avoid an inconsistent state.
>
> And also patch "vdpa_sim: cleanup kiovs in vdpasim_free()" is required 
> to free the iov when the device is going away.
>
> Does that make sense to you?


Make sense.


>
> Maybe I should add a comment in vringh.c to explain this better.


Yes, please.

Thanks


>
> Thanks,
> Stefano
>
>>
>> Thanks
>>
>>
>>> ---
>>>  drivers/vhost/vringh.c | 4 ++--
>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
>>> index f68122705719..bee63d68201a 100644
>>> --- a/drivers/vhost/vringh.c
>>> +++ b/drivers/vhost/vringh.c
>>> @@ -290,9 +290,9 @@ __vringh_iov(struct vringh *vrh, u16 i,
>>>          return -EINVAL;
>>>      if (riov)
>>> -        riov->i = riov->used = 0;
>>> +        riov->i = riov->used = riov->consumed = 0;
>>>      if (wiov)
>>> -        wiov->i = wiov->used = 0;
>>> +        wiov->i = wiov->used = wiov->consumed = 0;
>>>      for (;;) {
>>>          void *addr;
>>
>
diff mbox series

Patch

diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index f68122705719..bee63d68201a 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -290,9 +290,9 @@  __vringh_iov(struct vringh *vrh, u16 i,
 		return -EINVAL;
 
 	if (riov)
-		riov->i = riov->used = 0;
+		riov->i = riov->used = riov->consumed = 0;
 	if (wiov)
-		wiov->i = wiov->used = 0;
+		wiov->i = wiov->used = wiov->consumed = 0;
 
 	for (;;) {
 		void *addr;