Commit 59dbb2a0 authored by Akash Goel's avatar Akash Goel Committed by Linus Torvalds

relay: add global mode support for buffer-only channels

Commit 20d8b67c ("relay: add buffer-only channels; useful for early
logging") added support to use channels with no associated files.

This is useful when the exact location of relay file is not known or the
the parent directory of relay file is not available, while creating the
channel and the logging has to start right from the boot.

But there was no provision to use global mode with buffer-only channels,
which is added by this patch, without modifying the interface where
initially there will be a dummy invocation of create_buf_file callback
through which kernel client can convey the need of a global buffer.

For the use case where drivers/kernel clients want a simple interface
for the userspace, which enables them to capture data/logs from relay
file inorder & without any post processing, support of Global buffer
mode is warranted.

Modules, like i915, using relay_open() in early init would have to later
register their buffer-only relays, once debugfs is available, by calling
relay_late_setup_files().  Hence relay_late_setup_files() symbol also
needs to be exported.

Link: http://lkml.kernel.org/r/1468404563-11653-1-git-send-email-akash.goel@intel.comSigned-off-by: default avatarAkash Goel <akash.goel@intel.com>
Cc: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 841c06d7
...@@ -451,6 +451,13 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu) ...@@ -451,6 +451,13 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu)
if (!dentry) if (!dentry)
goto free_buf; goto free_buf;
relay_set_buf_dentry(buf, dentry); relay_set_buf_dentry(buf, dentry);
} else {
/* Only retrieve global info, nothing more, nothing less */
dentry = chan->cb->create_buf_file(NULL, NULL,
S_IRUSR, buf,
&chan->is_global);
if (WARN_ON(dentry))
goto free_buf;
} }
buf->cpu = cpu; buf->cpu = cpu;
...@@ -562,6 +569,10 @@ static int relay_hotcpu_callback(struct notifier_block *nb, ...@@ -562,6 +569,10 @@ static int relay_hotcpu_callback(struct notifier_block *nb,
* attributes specified. The created channel buffer files * attributes specified. The created channel buffer files
* will be named base_filename0...base_filenameN-1. File * will be named base_filename0...base_filenameN-1. File
* permissions will be %S_IRUSR. * permissions will be %S_IRUSR.
*
* If opening a buffer (@parent = NULL) that you later wish to register
* in a filesystem, call relay_late_setup_files() once the @parent dentry
* is available.
*/ */
struct rchan *relay_open(const char *base_filename, struct rchan *relay_open(const char *base_filename,
struct dentry *parent, struct dentry *parent,
...@@ -640,8 +651,12 @@ static void __relay_set_buf_dentry(void *info) ...@@ -640,8 +651,12 @@ static void __relay_set_buf_dentry(void *info)
* *
* Returns 0 if successful, non-zero otherwise. * Returns 0 if successful, non-zero otherwise.
* *
* Use to setup files for a previously buffer-only channel. * Use to setup files for a previously buffer-only channel created
* Useful to do early tracing in kernel, before VFS is up, for example. * by relay_open() with a NULL parent dentry.
*
* For example, this is useful for perfomring early tracing in kernel,
* before VFS is up and then exposing the early results once the dentry
* is available.
*/ */
int relay_late_setup_files(struct rchan *chan, int relay_late_setup_files(struct rchan *chan,
const char *base_filename, const char *base_filename,
...@@ -666,6 +681,20 @@ int relay_late_setup_files(struct rchan *chan, ...@@ -666,6 +681,20 @@ int relay_late_setup_files(struct rchan *chan,
} }
chan->has_base_filename = 1; chan->has_base_filename = 1;
chan->parent = parent; chan->parent = parent;
if (chan->is_global) {
err = -EINVAL;
if (!WARN_ON_ONCE(!chan->buf[0])) {
dentry = relay_create_buf_file(chan, chan->buf[0], 0);
if (dentry && !WARN_ON_ONCE(!chan->is_global)) {
relay_set_buf_dentry(chan->buf[0], dentry);
err = 0;
}
}
mutex_unlock(&relay_channels_mutex);
return err;
}
curr_cpu = get_cpu(); curr_cpu = get_cpu();
/* /*
* The CPU hotplug notifier ran before us and created buffers with * The CPU hotplug notifier ran before us and created buffers with
...@@ -706,6 +735,7 @@ int relay_late_setup_files(struct rchan *chan, ...@@ -706,6 +735,7 @@ int relay_late_setup_files(struct rchan *chan,
return err; return err;
} }
EXPORT_SYMBOL_GPL(relay_late_setup_files);
/** /**
* relay_switch_subbuf - switch to a new sub-buffer * relay_switch_subbuf - switch to a new sub-buffer
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment