* [RFC PATCH 21/21] Re-add late setup/early tracing.
@ 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
---
include/linux/relay_pagewriter.h | 5 +++
kernel/relay_pagewriter.c | 66 +++++++++++++++++++++++++++++++-------
2 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/include/linux/relay_pagewriter.h b/include/linux/relay_pagewriter.h
index 91ad16b..8fb4038 100644
--- a/include/linux/relay_pagewriter.h
+++ b/include/linux/relay_pagewriter.h
@@ -26,6 +26,7 @@
*/
#define PAGEWRITER_PAD_WRITES 0x00010000 /* don't cross pages */
#define PAGEWRITER_FLIGHT_MODE 0x00020000 /* n_pages page ring */
+#define PAGEWRITER_LATE_SETUP 0x00040000 /* delay chan create */
/*
* Per-cpu pagewriter buffer
@@ -49,12 +50,14 @@ struct pagewriter {
struct rchan *rchan; /* associated relay channel */
struct pagewriter_callbacks *cb; /* client callbacks */
size_t n_pages; /* number of pages per buffer */
+ size_t n_pages_wakeup; /* save for LATE */
struct kref kref; /* channel refcount */
void *private_data; /* for user-defined data */
size_t last_toobig; /* tried to log event > page size */
struct pagewriter_buf *buf[NR_CPUS]; /* per-cpu channel buffers */
struct list_head list; /* for channel list */
atomic_t dropped; /* dropped events due to buffer-full */
+ char base_filename[NAME_MAX]; /* saved base filename, for LATE */
unsigned long flags; /* pagewriter flags for this channel */
};
@@ -286,5 +289,7 @@ 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);
+extern int pagewriter_late_setup(struct pagewriter *pagewriter,
+ struct dentry *parent);
#endif /* _LINUX_RELAY_PAGEWRITER_H */
diff --git a/kernel/relay_pagewriter.c b/kernel/relay_pagewriter.c
index c3369f5..369abbe 100644
--- a/kernel/relay_pagewriter.c
+++ b/kernel/relay_pagewriter.c
@@ -72,23 +72,27 @@ struct pagewriter *pagewriter_open(const char *base_filename,
{
unsigned int i;
struct pagewriter *pagewriter;
- struct rchan *rchan;
if (!n_pages)
return NULL;
- rchan = relay_open(base_filename, parent, n_pages_wakeup, NULL,
- private_data, flags);
- if (!rchan)
- return NULL;
-
pagewriter = kzalloc(sizeof(struct pagewriter), GFP_KERNEL);
- if (!pagewriter) {
- relay_close(rchan);
+ if (!pagewriter)
return NULL;
+
+ if (flags & PAGEWRITER_LATE_SETUP) {
+ strlcpy(pagewriter->base_filename, base_filename, NAME_MAX);
+ pagewriter->n_pages_wakeup = n_pages_wakeup;
+ } else {
+ pagewriter->rchan = relay_open(base_filename, parent,
+ n_pages_wakeup, NULL,
+ private_data, flags);
+ if (!pagewriter->rchan) {
+ kfree(pagewriter);
+ return NULL;
+ }
}
- pagewriter->rchan = rchan;
pagewriter->flags = flags;
pagewriter->n_pages = n_pages;
atomic_set(&pagewriter->dropped, 0);
@@ -115,9 +119,9 @@ free_bufs:
pagewriter_close_buf(pagewriter->buf[i]);
}
- kfree(pagewriter);
- relay_close(rchan);
+ relay_close(pagewriter->rchan);
kref_put(&pagewriter->kref, pagewriter_destroy);
+ kfree(pagewriter);
mutex_unlock(&pagewriters_mutex);
return NULL;
}
@@ -240,6 +244,43 @@ void pagewriter_save_flight_data(struct pagewriter *pagewriter)
}
EXPORT_SYMBOL_GPL(pagewriter_save_flight_data);
+/**
+ * pagewriter_late_setup - create relay channel and log early pages
+ * @pagewriter: pagewriter
+ * @parent: dentry of parent directory, %NULL for root directory
+ *
+ * If the pagewriter was initially created in early mode
+ * (PAGEWRITER_LATE_SETUP), this creates the relay channel and
+ * sends all the early pages in the page pools to relay and
+ * therefore onto their final destination e.g. disk or network.
+ *
+ * Returns 0 if successful, non-zero otherwise.
+ *
+ * Use to setup files for a previously buffer-only channel.
+ * Useful to do early tracing in kernel, before VFS is up, for example.
+ */
+int pagewriter_late_setup(struct pagewriter *pagewriter,
+ struct dentry *parent)
+{
+ if (!pagewriter)
+ return -EINVAL;
+
+ pagewriter->rchan = relay_open(pagewriter->base_filename,
+ parent,
+ pagewriter->n_pages_wakeup,
+ NULL,
+ pagewriter->private_data,
+ pagewriter->flags);
+ if (!pagewriter->rchan)
+ return -ENOMEM;
+
+ pagewriter->flags &= ~PAGEWRITER_LATE_SETUP;
+ pagewriter_save_flight_data(pagewriter);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pagewriter_late_setup);
+
/*
* end relay kernel API
*/
@@ -573,7 +614,8 @@ size_t pagewriter_switch_page_default_callback(struct pagewriter_buf *buf,
if (!(buf->pagewriter->flags & PAGEWRITER_PAD_WRITES))
remainder = length - (PAGE_SIZE - buf->offset);
- if (buf->pagewriter->flags & PAGEWRITER_FLIGHT_MODE) {
+ if (buf->pagewriter->flags & PAGEWRITER_FLIGHT_MODE ||
+ buf->pagewriter->flags & PAGEWRITER_LATE_SETUP) {
list_add_tail(&buf->page->list, &buf->pool);
buf->n_pages_flight++;
} else {
--
1.5.3.5
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2008-10-16 6:19 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 21/21] Re-add late setup/early tracing Tom Zanussi
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.