All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tom Zanussi <zanussi@comcast.net>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Cc: Martin Bligh <mbligh@google.com>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	prasad@linux.vnet.ibm.com,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Mathieu Desnoyers <compudj@krystal.dyndns.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	od@suse.com, "Frank Ch. Eigler" <fche@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	hch@lst.de, David Wilder <dwilder@us.ibm.com>,
	Jens Axboe <jens.axboe@oracle.com>,
	Pekka Enberg <penberg@cs.helsinki.fi>,
	Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Subject: [RFC PATCH 19/21]  Add 'overwrite' mode back as 'flight' mode.
Date: Thu, 16 Oct 2008 01:06:50 -0500	[thread overview]
Message-ID: <1224137210.16328.238.camel@charm-linux> (raw)

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




                 reply	other threads:[~2008-10-16  6:18 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1224137210.16328.238.camel@charm-linux \
    --to=zanussi@comcast.net \
    --cc=a.p.zijlstra@chello.nl \
    --cc=akpm@linux-foundation.org \
    --cc=compudj@krystal.dyndns.org \
    --cc=dwilder@us.ibm.com \
    --cc=eduard.munteanu@linux360.ro \
    --cc=fche@redhat.com \
    --cc=hch@lst.de \
    --cc=jens.axboe@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mbligh@google.com \
    --cc=od@suse.com \
    --cc=penberg@cs.helsinki.fi \
    --cc=prasad@linux.vnet.ibm.com \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.