[CRIU] [PATCH 15/15] bfd: Implement buffered reads
Pavel Emelyanov
xemul at parallels.com
Mon Sep 29 01:50:44 PDT 2014
The restore times look like
Before patch:
futex: 370 3.554482 (84.2%)
umount: 41 0.234796 (5.6%)
read: 4737 0.113987 (2.7%)
recvmsg: 43 0.100083 (2.4%)
wait4: 10 0.033344 (0.8%)
After patch:
futex: 187 1.547642 (72.9%)
umount: 41 0.234595 (11.0%)
recvmsg: 43 0.075738 (3.6%)
flock: 42 0.038696 (1.8%)
clone: 35 0.037699 (1.8%)
Most of the time we wait for other processes to restore,
but that's OK (would only affect parallel restore). And
we see that read-s really go away (onto 7th position).
Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
bfd.c | 41 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/bfd.c b/bfd.c
index 0bc9a64..55a0cfa 100644
--- a/bfd.c
+++ b/bfd.c
@@ -6,6 +6,7 @@
#include <fcntl.h>
#include <sys/uio.h>
+#include "bug.h"
#include "log.h"
#include "bfd.h"
#include "list.h"
@@ -89,6 +90,12 @@ static int bflush(struct bfd *bfd);
void bclose(struct bfd *f)
{
if (bfd_buffered(f)) {
+ /*
+ * FIXME -- when we bread from images we don't
+ * need to flush. This call doesn't fail simply
+ * becase we read _all_ data from them and the
+ * b->sz would be 0 by the time we close them.
+ */
if (bflush(f) < 0)
/*
* FIXME -- propagate error up. It's
@@ -121,7 +128,7 @@ static int brefill(struct bfd *f)
return 0;
b->sz += ret;
- return 0;
+ return 1;
}
static char *strnchr(char *str, unsigned int len, char c)
@@ -182,7 +189,7 @@ again:
ss = b->sz;
/* no full line in the buffer -- refill one */
- if (brefill(f))
+ if (brefill(f) < 0)
return BREADERR;
refilled = true;
@@ -257,5 +264,33 @@ int bwritev(struct bfd *bfd, const struct iovec *iov, int cnt)
int bread(struct bfd *bfd, void *buf, int size)
{
- return read(bfd->fd, buf, size);
+ struct xbuf *b = &bfd->b;
+ int more = 1, filled = 0;
+
+ if (!bfd_buffered(bfd))
+ return read(bfd->fd, buf, size);
+
+ while (more > 0) {
+ int chunk;
+
+ chunk = size - filled;
+ if (chunk > b->sz)
+ chunk = b->sz;
+
+ if (chunk) {
+ memcpy(buf + filled, b->data, chunk);
+ b->data += chunk;
+ b->sz -= chunk;
+ filled += chunk;
+ }
+
+ if (filled < size)
+ more = brefill(bfd);
+ else {
+ BUG_ON(filled > size);
+ more = 0;
+ }
+ }
+
+ return more < 0 ? more : filled;
}
--
1.8.4.2
More information about the CRIU
mailing list