aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkash Goel <akash.goel@intel.com>2016-08-02 17:07:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-02 19:35:41 -0400
commit59dbb2a06fc2bcb752b964e036884fe9bb9dbbe0 (patch)
tree0f48defe51684cc222ab1a030c40850ea7dd3cbe
parent841c06d71e25a4e5fe8f7ed4ba7ba4324397f910 (diff)
relay: add global mode support for buffer-only channels
Commit 20d8b67c06fa ("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.com Signed-off-by: Akash 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/relay.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/kernel/relay.c b/kernel/relay.c
index 04d7cf3ef8cf..d797502140b9 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -451,6 +451,13 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu)
451 if (!dentry) 451 if (!dentry)
452 goto free_buf; 452 goto free_buf;
453 relay_set_buf_dentry(buf, dentry); 453 relay_set_buf_dentry(buf, dentry);
454 } else {
455 /* Only retrieve global info, nothing more, nothing less */
456 dentry = chan->cb->create_buf_file(NULL, NULL,
457 S_IRUSR, buf,
458 &chan->is_global);
459 if (WARN_ON(dentry))
460 goto free_buf;
454 } 461 }
455 462
456 buf->cpu = cpu; 463 buf->cpu = cpu;
@@ -562,6 +569,10 @@ static int relay_hotcpu_callback(struct notifier_block *nb,
562 * attributes specified. The created channel buffer files 569 * attributes specified. The created channel buffer files
563 * will be named base_filename0...base_filenameN-1. File 570 * will be named base_filename0...base_filenameN-1. File
564 * permissions will be %S_IRUSR. 571 * permissions will be %S_IRUSR.
572 *
573 * If opening a buffer (@parent = NULL) that you later wish to register
574 * in a filesystem, call relay_late_setup_files() once the @parent dentry
575 * is available.
565 */ 576 */
566struct rchan *relay_open(const char *base_filename, 577struct rchan *relay_open(const char *base_filename,
567 struct dentry *parent, 578 struct dentry *parent,
@@ -640,8 +651,12 @@ static void __relay_set_buf_dentry(void *info)
640 * 651 *
641 * Returns 0 if successful, non-zero otherwise. 652 * Returns 0 if successful, non-zero otherwise.
642 * 653 *
643 * Use to setup files for a previously buffer-only channel. 654 * Use to setup files for a previously buffer-only channel created
644 * Useful to do early tracing in kernel, before VFS is up, for example. 655 * by relay_open() with a NULL parent dentry.
656 *
657 * For example, this is useful for perfomring early tracing in kernel,
658 * before VFS is up and then exposing the early results once the dentry
659 * is available.
645 */ 660 */
646int relay_late_setup_files(struct rchan *chan, 661int relay_late_setup_files(struct rchan *chan,
647 const char *base_filename, 662 const char *base_filename,
@@ -666,6 +681,20 @@ int relay_late_setup_files(struct rchan *chan,
666 } 681 }
667 chan->has_base_filename = 1; 682 chan->has_base_filename = 1;
668 chan->parent = parent; 683 chan->parent = parent;
684
685 if (chan->is_global) {
686 err = -EINVAL;
687 if (!WARN_ON_ONCE(!chan->buf[0])) {
688 dentry = relay_create_buf_file(chan, chan->buf[0], 0);
689 if (dentry && !WARN_ON_ONCE(!chan->is_global)) {
690 relay_set_buf_dentry(chan->buf[0], dentry);
691 err = 0;
692 }
693 }
694 mutex_unlock(&relay_channels_mutex);
695 return err;
696 }
697
669 curr_cpu = get_cpu(); 698 curr_cpu = get_cpu();
670 /* 699 /*
671 * The CPU hotplug notifier ran before us and created buffers with 700 * The CPU hotplug notifier ran before us and created buffers with
@@ -706,6 +735,7 @@ int relay_late_setup_files(struct rchan *chan,
706 735
707 return err; 736 return err;
708} 737}
738EXPORT_SYMBOL_GPL(relay_late_setup_files);
709 739
710/** 740/**
711 * relay_switch_subbuf - switch to a new sub-buffer 741 * relay_switch_subbuf - switch to a new sub-buffer