qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] iov: avoid memcpy for "simple" iov_from_buf/iov_to_buf
@ 2015-12-16 10:57 Paolo Bonzini
  2015-12-18  5:08 ` Stefan Hajnoczi
  0 siblings, 1 reply; 3+ messages in thread
From: Paolo Bonzini @ 2015-12-16 10:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: mjt, stefanha

memcpy can take a large amount of time for small reads and writes.
For virtio it is a common case that the first iovec can satisfy the
whole read or write.  In that case, and if bytes is a constant to
avoid excessive growth of code, inline the first iteration
into the caller.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/iov.h | 32 ++++++++++++++++++++++++++++----
 util/iov.c         |  8 ++++----
 2 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/include/qemu/iov.h b/include/qemu/iov.h
index 569b2c2..e79a91d 100644
--- a/include/qemu/iov.h
+++ b/include/qemu/iov.h
@@ -39,10 +39,34 @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
  * such "large" value is -1 (sinice size_t is unsigned),
  * so specifying `-1' as `bytes' means 'up to the end of iovec'.
  */
-size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
-                    size_t offset, const void *buf, size_t bytes);
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
-                  size_t offset, void *buf, size_t bytes);
+size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
+                         size_t offset, const void *buf, size_t bytes);
+size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
+		       size_t offset, void *buf, size_t bytes);
+
+static inline size_t
+iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
+             size_t offset, const void *buf, size_t bytes)
+{
+    if (__builtin_constant_p(bytes) && iov_cnt && offset + bytes <= iov[0].iov_len) {
+        memcpy(iov[0].iov_base + offset, buf, bytes);
+        return bytes;
+    } else {
+        return iov_from_buf_full(iov, iov_cnt, offset, buf, bytes);
+    }
+}
+
+static inline size_t
+iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
+           size_t offset, void *buf, size_t bytes)
+{
+    if (__builtin_constant_p(bytes) && iov_cnt && offset + bytes <= iov[0].iov_len) {
+        memcpy(buf, iov[0].iov_base + offset, bytes);
+        return bytes;
+    } else {
+        return iov_to_buf_full(iov, iov_cnt, offset, buf, bytes);
+    }
+}
 
 /**
  * Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
diff --git a/util/iov.c b/util/iov.c
index a0d5934..f113467 100644
--- a/util/iov.c
+++ b/util/iov.c
@@ -19,8 +19,8 @@
 #include "qemu/iov.h"
 #include "qemu/sockets.h"
 
-size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
-                    size_t offset, const void *buf, size_t bytes)
+size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
+                         size_t offset, const void *buf, size_t bytes)
 {
     size_t done;
     unsigned int i;
@@ -38,8 +38,8 @@ size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
     return done;
 }
 
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
-                  size_t offset, void *buf, size_t bytes)
+size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
+                       size_t offset, void *buf, size_t bytes)
 {
     size_t done;
     unsigned int i;
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH] iov: avoid memcpy for "simple" iov_from_buf/iov_to_buf
  2015-12-16 10:57 [Qemu-devel] [PATCH] iov: avoid memcpy for "simple" iov_from_buf/iov_to_buf Paolo Bonzini
@ 2015-12-18  5:08 ` Stefan Hajnoczi
  2015-12-22  8:34   ` Stefan Hajnoczi
  0 siblings, 1 reply; 3+ messages in thread
From: Stefan Hajnoczi @ 2015-12-18  5:08 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: mjt, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 678 bytes --]

On Wed, Dec 16, 2015 at 11:57:33AM +0100, Paolo Bonzini wrote:
> memcpy can take a large amount of time for small reads and writes.
> For virtio it is a common case that the first iovec can satisfy the
> whole read or write.  In that case, and if bytes is a constant to
> avoid excessive growth of code, inline the first iteration
> into the caller.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qemu/iov.h | 32 ++++++++++++++++++++++++++++----
>  util/iov.c         |  8 ++++----
>  2 files changed, 32 insertions(+), 8 deletions(-)

Thanks, applied to my block-next tree:
https://github.com/stefanha/qemu/commits/block-next

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH] iov: avoid memcpy for "simple" iov_from_buf/iov_to_buf
  2015-12-18  5:08 ` Stefan Hajnoczi
@ 2015-12-22  8:34   ` Stefan Hajnoczi
  0 siblings, 0 replies; 3+ messages in thread
From: Stefan Hajnoczi @ 2015-12-22  8:34 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Paolo Bonzini, mjt, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 916 bytes --]

On Fri, Dec 18, 2015 at 01:08:43PM +0800, Stefan Hajnoczi wrote:
> On Wed, Dec 16, 2015 at 11:57:33AM +0100, Paolo Bonzini wrote:
> > memcpy can take a large amount of time for small reads and writes.
> > For virtio it is a common case that the first iovec can satisfy the
> > whole read or write.  In that case, and if bytes is a constant to
> > avoid excessive growth of code, inline the first iteration
> > into the caller.
> > 
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > ---
> >  include/qemu/iov.h | 32 ++++++++++++++++++++++++++++----
> >  util/iov.c         |  8 ++++----
> >  2 files changed, 32 insertions(+), 8 deletions(-)
> 
> Thanks, applied to my block-next tree:
> https://github.com/stefanha/qemu/commits/block-next

Paolo, I've dropped this from block-next because it breaks
tests/test-iov.

Please resolve the failure and submit a new patch.

Thanks,
Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-12-22  8:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-16 10:57 [Qemu-devel] [PATCH] iov: avoid memcpy for "simple" iov_from_buf/iov_to_buf Paolo Bonzini
2015-12-18  5:08 ` Stefan Hajnoczi
2015-12-22  8:34   ` Stefan Hajnoczi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).