diff mbox series

[RFC,v2,04/10] vringh: implement vringh_kiov_advance()

Message ID 20210128144127.113245-5-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
In some cases, it may be useful to provide a way to skip a number
of bytes in a vringh_kiov.

Let's implement vringh_kiov_advance() for this purpose, reusing the
code from vringh_iov_xfer().
We replace that code calling the new vringh_kiov_advance().

Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
 include/linux/vringh.h |  2 ++
 drivers/vhost/vringh.c | 41 +++++++++++++++++++++++++++++------------
 2 files changed, 31 insertions(+), 12 deletions(-)

Comments

Jason Wang Feb. 1, 2021, 5:43 a.m. UTC | #1
On 2021/1/28 下午10:41, Stefano Garzarella wrote:
> In some cases, it may be useful to provide a way to skip a number
> of bytes in a vringh_kiov.
>
> Let's implement vringh_kiov_advance() for this purpose, reusing the
> code from vringh_iov_xfer().
> We replace that code calling the new vringh_kiov_advance().


Acked-by: Jason Wang <jasowang@redhat.com>

In the long run we need to switch to use iov iterator library instead.

Thanks


>
> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
> ---
>   include/linux/vringh.h |  2 ++
>   drivers/vhost/vringh.c | 41 +++++++++++++++++++++++++++++------------
>   2 files changed, 31 insertions(+), 12 deletions(-)
>
> diff --git a/include/linux/vringh.h b/include/linux/vringh.h
> index 9c077863c8f6..755211ebd195 100644
> --- a/include/linux/vringh.h
> +++ b/include/linux/vringh.h
> @@ -199,6 +199,8 @@ static inline void vringh_kiov_cleanup(struct vringh_kiov *kiov)
>   	kiov->iov = NULL;
>   }
>   
> +void vringh_kiov_advance(struct vringh_kiov *kiov, size_t len);
> +
>   int vringh_getdesc_kern(struct vringh *vrh,
>   			struct vringh_kiov *riov,
>   			struct vringh_kiov *wiov,
> diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
> index bee63d68201a..4d800e4f31ca 100644
> --- a/drivers/vhost/vringh.c
> +++ b/drivers/vhost/vringh.c
> @@ -75,6 +75,34 @@ static inline int __vringh_get_head(const struct vringh *vrh,
>   	return head;
>   }
>   
> +/**
> + * vringh_kiov_advance - skip bytes from vring_kiov
> + * @iov: an iov passed to vringh_getdesc_*() (updated as we consume)
> + * @len: the maximum length to advance
> + */
> +void vringh_kiov_advance(struct vringh_kiov *iov, size_t len)
> +{
> +	while (len && iov->i < iov->used) {
> +		size_t partlen = min(iov->iov[iov->i].iov_len, len);
> +
> +		iov->consumed += partlen;
> +		iov->iov[iov->i].iov_len -= partlen;
> +		iov->iov[iov->i].iov_base += partlen;
> +
> +		if (!iov->iov[iov->i].iov_len) {
> +			/* Fix up old iov element then increment. */
> +			iov->iov[iov->i].iov_len = iov->consumed;
> +			iov->iov[iov->i].iov_base -= iov->consumed;
> +
> +			iov->consumed = 0;
> +			iov->i++;
> +		}
> +
> +		len -= partlen;
> +	}
> +}
> +EXPORT_SYMBOL(vringh_kiov_advance);
> +
>   /* Copy some bytes to/from the iovec.  Returns num copied. */
>   static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
>   				      struct vringh_kiov *iov,
> @@ -95,19 +123,8 @@ static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
>   		done += partlen;
>   		len -= partlen;
>   		ptr += partlen;
> -		iov->consumed += partlen;
> -		iov->iov[iov->i].iov_len -= partlen;
> -		iov->iov[iov->i].iov_base += partlen;
>   
> -		if (!iov->iov[iov->i].iov_len) {
> -			/* Fix up old iov element then increment. */
> -			iov->iov[iov->i].iov_len = iov->consumed;
> -			iov->iov[iov->i].iov_base -= iov->consumed;
> -
> -			
> -			iov->consumed = 0;
> -			iov->i++;
> -		}
> +		vringh_kiov_advance(iov, partlen);
>   	}
>   	return done;
>   }
Stefano Garzarella Feb. 1, 2021, 10:23 a.m. UTC | #2
On Mon, Feb 01, 2021 at 01:43:23PM +0800, Jason Wang wrote:
>
>On 2021/1/28 下午10:41, Stefano Garzarella wrote:
>>In some cases, it may be useful to provide a way to skip a number
>>of bytes in a vringh_kiov.
>>
>>Let's implement vringh_kiov_advance() for this purpose, reusing the
>>code from vringh_iov_xfer().
>>We replace that code calling the new vringh_kiov_advance().
>
>
>Acked-by: Jason Wang <jasowang@redhat.com>
>
>In the long run we need to switch to use iov iterator library instead.

Yes I agree.
I've tried to do this, but it requires quite a bit of work to change 
vringh, I'll put it on my todo list.

Thanks,
Stefano

>
>Thanks
>
>
>>
>>Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
>>---
>>  include/linux/vringh.h |  2 ++
>>  drivers/vhost/vringh.c | 41 +++++++++++++++++++++++++++++------------
>>  2 files changed, 31 insertions(+), 12 deletions(-)
>>
>>diff --git a/include/linux/vringh.h b/include/linux/vringh.h
>>index 9c077863c8f6..755211ebd195 100644
>>--- a/include/linux/vringh.h
>>+++ b/include/linux/vringh.h
>>@@ -199,6 +199,8 @@ static inline void vringh_kiov_cleanup(struct vringh_kiov *kiov)
>>  	kiov->iov = NULL;
>>  }
>>+void vringh_kiov_advance(struct vringh_kiov *kiov, size_t len);
>>+
>>  int vringh_getdesc_kern(struct vringh *vrh,
>>  			struct vringh_kiov *riov,
>>  			struct vringh_kiov *wiov,
>>diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
>>index bee63d68201a..4d800e4f31ca 100644
>>--- a/drivers/vhost/vringh.c
>>+++ b/drivers/vhost/vringh.c
>>@@ -75,6 +75,34 @@ static inline int __vringh_get_head(const struct vringh *vrh,
>>  	return head;
>>  }
>>+/**
>>+ * vringh_kiov_advance - skip bytes from vring_kiov
>>+ * @iov: an iov passed to vringh_getdesc_*() (updated as we consume)
>>+ * @len: the maximum length to advance
>>+ */
>>+void vringh_kiov_advance(struct vringh_kiov *iov, size_t len)
>>+{
>>+	while (len && iov->i < iov->used) {
>>+		size_t partlen = min(iov->iov[iov->i].iov_len, len);
>>+
>>+		iov->consumed += partlen;
>>+		iov->iov[iov->i].iov_len -= partlen;
>>+		iov->iov[iov->i].iov_base += partlen;
>>+
>>+		if (!iov->iov[iov->i].iov_len) {
>>+			/* Fix up old iov element then increment. */
>>+			iov->iov[iov->i].iov_len = iov->consumed;
>>+			iov->iov[iov->i].iov_base -= iov->consumed;
>>+
>>+			iov->consumed = 0;
>>+			iov->i++;
>>+		}
>>+
>>+		len -= partlen;
>>+	}
>>+}
>>+EXPORT_SYMBOL(vringh_kiov_advance);
>>+
>>  /* Copy some bytes to/from the iovec.  Returns num copied. */
>>  static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
>>  				      struct vringh_kiov *iov,
>>@@ -95,19 +123,8 @@ static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
>>  		done += partlen;
>>  		len -= partlen;
>>  		ptr += partlen;
>>-		iov->consumed += partlen;
>>-		iov->iov[iov->i].iov_len -= partlen;
>>-		iov->iov[iov->i].iov_base += partlen;
>>-		if (!iov->iov[iov->i].iov_len) {
>>-			/* Fix up old iov element then increment. */
>>-			iov->iov[iov->i].iov_len = iov->consumed;
>>-			iov->iov[iov->i].iov_base -= iov->consumed;
>>-
>>-			
>>-			iov->consumed = 0;
>>-			iov->i++;
>>-		}
>>+		vringh_kiov_advance(iov, partlen);
>>  	}
>>  	return done;
>>  }
>
diff mbox series

Patch

diff --git a/include/linux/vringh.h b/include/linux/vringh.h
index 9c077863c8f6..755211ebd195 100644
--- a/include/linux/vringh.h
+++ b/include/linux/vringh.h
@@ -199,6 +199,8 @@  static inline void vringh_kiov_cleanup(struct vringh_kiov *kiov)
 	kiov->iov = NULL;
 }
 
+void vringh_kiov_advance(struct vringh_kiov *kiov, size_t len);
+
 int vringh_getdesc_kern(struct vringh *vrh,
 			struct vringh_kiov *riov,
 			struct vringh_kiov *wiov,
diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index bee63d68201a..4d800e4f31ca 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -75,6 +75,34 @@  static inline int __vringh_get_head(const struct vringh *vrh,
 	return head;
 }
 
+/**
+ * vringh_kiov_advance - skip bytes from vring_kiov
+ * @iov: an iov passed to vringh_getdesc_*() (updated as we consume)
+ * @len: the maximum length to advance
+ */
+void vringh_kiov_advance(struct vringh_kiov *iov, size_t len)
+{
+	while (len && iov->i < iov->used) {
+		size_t partlen = min(iov->iov[iov->i].iov_len, len);
+
+		iov->consumed += partlen;
+		iov->iov[iov->i].iov_len -= partlen;
+		iov->iov[iov->i].iov_base += partlen;
+
+		if (!iov->iov[iov->i].iov_len) {
+			/* Fix up old iov element then increment. */
+			iov->iov[iov->i].iov_len = iov->consumed;
+			iov->iov[iov->i].iov_base -= iov->consumed;
+
+			iov->consumed = 0;
+			iov->i++;
+		}
+
+		len -= partlen;
+	}
+}
+EXPORT_SYMBOL(vringh_kiov_advance);
+
 /* Copy some bytes to/from the iovec.  Returns num copied. */
 static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
 				      struct vringh_kiov *iov,
@@ -95,19 +123,8 @@  static inline ssize_t vringh_iov_xfer(struct vringh *vrh,
 		done += partlen;
 		len -= partlen;
 		ptr += partlen;
-		iov->consumed += partlen;
-		iov->iov[iov->i].iov_len -= partlen;
-		iov->iov[iov->i].iov_base += partlen;
 
-		if (!iov->iov[iov->i].iov_len) {
-			/* Fix up old iov element then increment. */
-			iov->iov[iov->i].iov_len = iov->consumed;
-			iov->iov[iov->i].iov_base -= iov->consumed;
-
-			
-			iov->consumed = 0;
-			iov->i++;
-		}
+		vringh_kiov_advance(iov, partlen);
 	}
 	return done;
 }