[CRIU] [PATCH 11/15] bfd: Multiple buffers management

Pavel Emelyanov xemul at parallels.com
Mon Sep 29 01:49:39 PDT 2014


I plan to re-use the bfd engine for images buffering. Right
now this engine uses one buffer that gets reused by all
bfdopen()-s. This works for current usage (one-by-pne proc
files access), but for images we'll need more buffers.

So this patch just puts buffers in a list and organizes a
stupid R-R with refill on it.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 bfd.c         | 53 ++++++++++++++++++++++++++++++++++++-----------------
 include/bfd.h |  2 ++
 2 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/bfd.c b/bfd.c
index 34030f5..e80120e 100644
--- a/bfd.c
+++ b/bfd.c
@@ -7,6 +7,8 @@
 
 #include "log.h"
 #include "bfd.h"
+#include "list.h"
+#include "xmalloc.h"
 #include "asm-generic/page.h"
 
 /*
@@ -15,43 +17,60 @@
  */
 #define BUFSIZE	(PAGE_SIZE)
 
-/*
- * XXX currently CRIU doesn't open several files
- * at once, so we can have just one buffer.
- */
-static char *buf;
-static bool buf_busy;
+struct bfd_buf {
+	char *mem;
+	struct list_head l;
+};
+
+static LIST_HEAD(bufs);
+
+#define BUFBATCH	(16)
 
 static int buf_get(struct xbuf *xb)
 {
-	if (buf_busy) {
-		pr_err("bfd: Buffer busy\n");
-		return -1;
-	}
+	struct bfd_buf *b;
+
+	if (list_empty(&bufs)) {
+		void *mem;
+		int i;
 
-	if (!buf) {
-		buf = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
+		pr_debug("BUF++\n");
+		mem = mmap(NULL, BUFBATCH * BUFSIZE, PROT_READ | PROT_WRITE,
 				MAP_PRIVATE | MAP_ANON, 0, 0);
-		if (buf == MAP_FAILED) {
+		if (mem == MAP_FAILED) {
 			pr_perror("bfd: No buf");
 			return -1;
 		}
+
+		for (i = 0; i < BUFBATCH; i++) {
+			b = xmalloc(sizeof(*b));
+			b->mem = mem + i * BUFSIZE;
+			list_add_tail(&b->l, &bufs);
+		}
 	}
 
-	buf_busy = true;
-	xb->mem = buf;
-	xb->pos = buf;
+	b = list_first_entry(&bufs, struct bfd_buf, l);
+	list_del_init(&b->l);
+
+	xb->mem = b->mem;
+	xb->pos = xb->mem;
 	xb->bleft = 0;
+	xb->buf = b;
+	pr_debug("BUF<\n");
 	return 0;
 }
 
 static void buf_put(struct xbuf *xb)
 {
-	buf_busy = false;
 	/*
 	 * Don't unmap buffer back, it will get reused
 	 * by next bfdopen call
 	 */
+	pr_debug("BUF>\n");
+	list_add(&xb->buf->l, &bufs);
+	xb->buf = NULL;
+	xb->mem = NULL;
+	xb->pos = NULL;
 }
 
 int bfdopen(struct bfd *f)
diff --git a/include/bfd.h b/include/bfd.h
index cea6d3a..dbaea16 100644
--- a/include/bfd.h
+++ b/include/bfd.h
@@ -1,9 +1,11 @@
 #ifndef __CR_BFD_H__
 #define __CR_BFD_H__
+struct bfd_buf;
 struct xbuf {
 	char *mem;		/* buffer */
 	char *pos;		/* position we see bytes at */
 	unsigned int bleft;	/* bytes left after b->pos */
+	struct bfd_buf *buf;
 };
 
 struct bfd {
-- 
1.8.4.2




More information about the CRIU mailing list