public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 19/21]  Add 'overwrite' mode back as 'flight' mode.
@ 2008-10-16  6:06 Tom Zanussi
  0 siblings, 0 replies; only message in thread
From: Tom Zanussi @ 2008-10-16  6:06 UTC (permalink / raw)
  To: Linux Kernel Mailing List
  Cc: Martin Bligh, Peter Zijlstra, prasad, Linus Torvalds,
	Thomas Gleixner, Mathieu Desnoyers, Steven Rostedt, od,
	Frank Ch. Eigler, Andrew Morton, hch, David Wilder, Jens Axboe,
	Pekka Enberg, Eduard - Gabriel Munteanu

Uses per-cpu page pools as flight buffers, recycling pages and adding
pagewriter_save_flight_data() to dump it all to relay.
---
 include/linux/relay_pagewriter.h |    3 ++
 kernel/relay_pagewriter.c        |   71 +++++++++++++++++++++++++++++++++++---
 2 files changed, 69 insertions(+), 5 deletions(-)

diff --git a/include/linux/relay_pagewriter.h b/include/linux/relay_pagewriter.h
index 12378e5..91ad16b 100644
--- a/include/linux/relay_pagewriter.h
+++ b/include/linux/relay_pagewriter.h
@@ -25,6 +25,7 @@
  * pagewriter flags
  */
 #define PAGEWRITER_PAD_WRITES		0x00010000	/* don't cross pages */
+#define PAGEWRITER_FLIGHT_MODE		0x00020000	/* n_pages page ring */
 
 /*
  * Per-cpu pagewriter buffer
@@ -37,6 +38,7 @@ struct pagewriter_buf {
 	struct kref kref;		/* channel buffer refcount */
 	struct list_head pool;		/* current set of unused pages */
 	struct list_head empty_rpage_structs;	/* cached rpage structs */
+	size_t n_pages_flight;		/* number full flight pages written */
 	unsigned int cpu;		/* this buf's cpu */
 } ____cacheline_aligned;
 
@@ -283,5 +285,6 @@ extern struct pagewriter *pagewriter_open(const char *base_filename,
 extern void pagewriter_flush(struct pagewriter *pagewriter);
 extern void pagewriter_close(struct pagewriter *pagewriter);
 extern void pagewriter_reset(struct pagewriter *pagewriter);
+extern void pagewriter_save_flight_data(struct pagewriter *pagewriter);
 
 #endif /* _LINUX_RELAY_PAGEWRITER_H */
diff --git a/kernel/relay_pagewriter.c b/kernel/relay_pagewriter.c
index d27267f..9bc1461 100644
--- a/kernel/relay_pagewriter.c
+++ b/kernel/relay_pagewriter.c
@@ -41,6 +41,7 @@ static struct pagewriter_buf *pagewriter_open_buf(struct pagewriter *pw,
 						  unsigned int cpu);
 static void pagewriter_destroy(struct kref *kref);
 static void __pagewriter_reset(struct pagewriter_buf *buf, unsigned int init);
+static void pagewriter_save_flight_buf(struct pagewriter_buf *buf);
 
 /*
  * pagewriter kernel API
@@ -201,6 +202,36 @@ void pagewriter_reset(struct pagewriter *pagewriter)
 }
 EXPORT_SYMBOL_GPL(pagewriter_reset);
 
+/**
+ *	pagewriter_save_flight_data - log all pages dirtied in flight mode
+ *	@pagewriter: pagewriter
+ *
+ *	In flight mode (PAGEWRITER_FLIGHT_MODE), the pages written to
+ *	via the pagewriter_write/reserve functions are simply cycled
+ *	around the per-cpu page pools, and not sent to relay.  This
+ *	function provides a way, at the user's request, to simply
+ *	sends all the dirty pages in the page pools to relay and
+ *	therefore onto their final destination e.g. disk or network.
+ *
+ *	The pagewriter and associated buffers will be in the same
+ *	state as if hey were reset after this call.
+ */
+void pagewriter_save_flight_data(struct pagewriter *pagewriter)
+{
+	unsigned int i;
+
+	if (!pagewriter)
+		return;
+
+	mutex_lock(&pagewriters_mutex);
+	for_each_possible_cpu(i)
+		if (pagewriter->buf[i])
+			pagewriter_save_flight_buf(pagewriter->buf[i]);
+	relay_flush(pagewriter->rchan);
+	mutex_unlock(&pagewriters_mutex);
+}
+EXPORT_SYMBOL_GPL(pagewriter_save_flight_data);
+
 /*
  * end relay kernel API
  */
@@ -534,11 +565,15 @@ size_t pagewriter_switch_page_default_callback(struct pagewriter_buf *buf,
 	if (!(buf->pagewriter->flags & PAGEWRITER_PAD_WRITES))
 		remainder = length - (PAGE_SIZE - buf->offset);
 
-	relay_add_page(buf->pagewriter->rchan, buf->page->page,
-		       &pagewriter_relay_page_callbacks, (void *)buf);
-
-	buf->page->page = NULL;
-	add_empty_rpage_struct(buf, buf->page);
+	if (buf->pagewriter->flags & PAGEWRITER_FLIGHT_MODE) {
+		list_add_tail(&buf->page->list, &buf->pool);
+		buf->n_pages_flight++;
+	} else {
+		relay_add_page(buf->pagewriter->rchan, buf->page->page,
+			       &pagewriter_relay_page_callbacks, (void *)buf);
+		buf->page->page = NULL;
+		add_empty_rpage_struct(buf, buf->page);
+	}
 
 	buf->page = new_page;
 	buf->data = page_address(buf->page->page);
@@ -574,10 +609,36 @@ static void __pagewriter_reset(struct pagewriter_buf *buf, unsigned int init)
 	buf->page = pagewriter_get_free_page(buf);
 	buf->data = page_address(buf->page->page);
 	buf->offset = 0;
+	buf->n_pages_flight = 0;
 
 	buf->pagewriter->cb->new_page(buf, buf->data);
 }
 
+static void pagewriter_save_flight_buf(struct pagewriter_buf *buf)
+{
+	size_t first_page, n_pages = buf->n_pages_flight;
+	struct relay_page *first_rpage;
+
+	buf->pagewriter->cb->switch_page(buf, 0, NULL);
+
+	if(buf->n_pages_flight > buf->pagewriter->n_pages)
+		n_pages = buf->pagewriter->n_pages;
+
+	first_page = buf->pagewriter->n_pages - n_pages;
+	list_for_each_entry(first_rpage, &buf->pool, list)
+		if (!first_page--)
+			break;
+
+	list_for_each_entry_from(first_rpage, &buf->pool, list) {
+		relay_add_page(buf->pagewriter->rchan, buf->page->page,
+			       &pagewriter_relay_page_callbacks, (void *)buf);
+		buf->page->page = NULL;
+		add_empty_rpage_struct(buf, buf->page);
+	}
+
+	__pagewriter_reset(buf, 0);
+}
+
 /**
  * 	pagewriter_hotcpu_callback - CPU hotplug callback
  * 	@nb: notifier block
-- 
1.5.3.5




^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2008-10-16  6:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-16  6:06 [RFC PATCH 19/21] Add 'overwrite' mode back as 'flight' mode Tom Zanussi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox