lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Thu, 16 Oct 2008 01:06:50 -0500
From:	Tom Zanussi <zanussi@...cast.net>
To:	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Cc:	Martin Bligh <mbligh@...gle.com>,
	Peter Zijlstra <a.p.zijlstra@...llo.nl>,
	prasad@...ux.vnet.ibm.com,
	Linus Torvalds <torvalds@...ux-foundation.org>,
	Thomas Gleixner <tglx@...utronix.de>,
	Mathieu Desnoyers <compudj@...stal.dyndns.org>,
	Steven Rostedt <rostedt@...dmis.org>, od@...e.com,
	"Frank Ch. Eigler" <fche@...hat.com>,
	Andrew Morton <akpm@...ux-foundation.org>, hch@....de,
	David Wilder <dwilder@...ibm.com>,
	Jens Axboe <jens.axboe@...cle.com>,
	Pekka Enberg <penberg@...helsinki.fi>,
	Eduard - Gabriel Munteanu <eduard.munteanu@...ux360.ro>
Subject: [RFC PATCH 19/21]  Add 'overwrite' mode back as 'flight' mode.

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



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ