From: Bharath Ravi <rbharath@google.com>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: Vaibhav Nagarnaik <vnagarnaik@google.com>,
David Sharp <dhsharp@google.com>,
Bharath Ravi <rbharath@google.com>,
Laurent Chavey <chavey@google.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH 2/3] tracing: Allow instances to have independent trace flags/trace options.
Date: Mon, 24 Mar 2014 11:13:45 -0700 [thread overview]
Message-ID: <1395684826-22931-3-git-send-email-rbharath@google.com> (raw)
In-Reply-To: <1395684826-22931-1-git-send-email-rbharath@google.com>
Currently, the trace options are global, and shared among all
instances. This change divides the set of trace options into global
options and instance specific options. This division is done by using a
"global_flags_start" offset in the list of available trace options, that
marks the first global trace option, and is preceded by options that are
instance specific.
Instance specific options may be set independently by an instance
without affecting either the global tracer or other instances. Global
options are viewable and modifiable only from the global tracer,
preventing instances from modifying shared flags.
Currently, there are no instance specific options (global_flags_start is
set to 0). This patch only adds the infrastructure for allowing instance
specific trace options. Subsequently, options may be made instance
specific by changing global_flags_start and moving the option to a
position less than global_flags_start in the trace_options list.
Signed-off-by: Bharath Ravi <rbharath@google.com>
---
kernel/trace/trace.c | 73 ++++++++++++++++++++++++++++++++++++++++------------
kernel/trace/trace.h | 2 +-
2 files changed, 57 insertions(+), 18 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 9f0a5f9..61f2301 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -406,20 +406,24 @@ static inline void trace_access_lock_init(void)
#endif
-/* trace_flags holds trace_options default values */
-unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
- TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME |
- TRACE_ITER_GRAPH_TIME | TRACE_ITER_RECORD_CMD | TRACE_ITER_OVERWRITE |
- TRACE_ITER_IRQ_INFO | TRACE_ITER_MARKERS | TRACE_ITER_FUNCTION;
+/* Sets default values for a tracer's trace_options */
+static inline void init_trace_flags(unsigned long *trace_flags)
+{
+ *trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
+ TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO |
+ TRACE_ITER_SLEEP_TIME | TRACE_ITER_GRAPH_TIME |
+ TRACE_ITER_RECORD_CMD | TRACE_ITER_OVERWRITE |
+ TRACE_ITER_IRQ_INFO | TRACE_ITER_MARKERS | TRACE_ITER_FUNCTION;
+}
unsigned long global_trace_flags(void)
{
- return trace_flags;
+ return global_trace.trace_flags;
}
void set_global_trace_flags(unsigned long flags)
{
- trace_flags = flags;
+ global_trace.trace_flags = flags;
}
static void tracer_tracing_on(struct trace_array *tr)
@@ -799,6 +803,13 @@ static const char *trace_options[] = {
NULL
};
+/*
+ * The index of the first global flag in trace_options. Indices higher than or
+ * equal to this are global flags, while indices smaller than this are
+ * per-instance flags.
+ */
+static const int global_flags_start;
+
static struct {
u64 (*func)(void);
const char *name;
@@ -3333,13 +3344,23 @@ static int tracing_trace_options_show(struct seq_file *m, void *v)
tracer_flags = tr->current_trace->flags->val;
trace_opts = tr->current_trace->flags->opts;
- for (i = 0; trace_options[i]; i++) {
- if (global_trace_flags() & (1 << i))
+ for (i = 0; i < global_flags_start; i++) {
+ if (tr->trace_flags & (1 << i))
seq_printf(m, "%s\n", trace_options[i]);
else
seq_printf(m, "no%s\n", trace_options[i]);
}
+ /* For the global trace, also display global options*/
+ if (tr->flags & TRACE_ARRAY_FL_GLOBAL) {
+ for (i = global_flags_start; trace_options[i]; i++) {
+ if (global_trace_flags() & (1 << i))
+ seq_printf(m, "%s\n", trace_options[i]);
+ else
+ seq_printf(m, "no%s\n", trace_options[i]);
+ }
+ }
+
for (i = 0; trace_opts[i].name; i++) {
if (tracer_flags & trace_opts[i].bit)
seq_printf(m, "%s\n", trace_opts[i].name);
@@ -3397,9 +3418,14 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
{
- unsigned long trace_flags = global_trace_flags();
+ /* If this is a global flag, disallow instances from modifying it. */
+ if (mask >= (1 << global_flags_start) &&
+ !(tr->flags & TRACE_ARRAY_FL_GLOBAL))
+ return -EINVAL;
+
+
/* do nothing if flag is already set */
- if (!!(trace_flags & mask) == !!enabled)
+ if (!!(tr->trace_flags & mask) == !!enabled)
return 0;
/* Give the tracer a chance to approve the change */
@@ -3408,9 +3434,9 @@ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
return -EINVAL;
if (enabled)
- trace_flags |= mask;
+ tr->trace_flags |= mask;
else
- trace_flags &= ~mask;
+ tr->trace_flags &= ~mask;
if (mask == TRACE_ITER_RECORD_CMD)
trace_event_enable_cmd_record(enabled);
@@ -3434,6 +3460,7 @@ static int trace_set_options(struct trace_array *tr, char *option)
int neg = 0;
int ret = -ENODEV;
int i;
+ bool option_found = false;
cmp = strstrip(option);
@@ -3444,15 +3471,26 @@ static int trace_set_options(struct trace_array *tr, char *option)
mutex_lock(&trace_types_lock);
- for (i = 0; trace_options[i]; i++) {
+ for (i = 0; i < global_flags_start; i++) {
if (strcmp(cmp, trace_options[i]) == 0) {
ret = set_tracer_flag(tr, 1 << i, !neg);
break;
}
}
+ if (i < global_flags_start) {
+ option_found = true;
+ } else if (tr->flags & TRACE_ARRAY_FL_GLOBAL) {
+ /* If this is the global trace, try the global options */
+ for (i = global_flags_start; trace_options[i]; i++) {
+ ret = set_tracer_flag(tr, 1 << i, !neg);
+ break;
+ }
+ option_found = trace_options[i];
+ }
+
/* If no option could be set, test the specific tracer options */
- if (!trace_options[i])
+ if (!option_found)
ret = set_tracer_option(tr->current_trace, cmp, neg);
mutex_unlock(&trace_types_lock);
@@ -5967,9 +6005,8 @@ static int
allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size)
{
enum ring_buffer_flags rb_flags;
- unsigned long trace_flags = global_trace_flags();
- rb_flags = trace_flags & TRACE_ITER_OVERWRITE ? RB_FL_OVERWRITE : 0;
+ rb_flags = tr->trace_flags & TRACE_ITER_OVERWRITE ? RB_FL_OVERWRITE : 0;
buf->tr = tr;
@@ -6045,6 +6082,7 @@ static int new_instance_create(const char *name)
cpumask_copy(tr->tracing_cpumask, cpu_all_mask);
raw_spin_lock_init(&tr->start_lock);
+ init_trace_flags(&(tr->trace_flags));
tr->current_trace = &nop_trace;
@@ -6507,6 +6545,7 @@ __init static int tracer_alloc_buffers(void)
cpumask_copy(global_trace.tracing_cpumask, cpu_all_mask);
raw_spin_lock_init(&global_trace.start_lock);
+ init_trace_flags(&global_trace.trace_flags);
/* TODO: make the number of buffers hot pluggable with CPUS */
if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) {
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 82b50a0..38b511a 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -201,6 +201,7 @@ struct trace_array {
int clock_id;
struct tracer *current_trace;
unsigned int flags;
+ unsigned long trace_flags;
raw_spinlock_t start_lock;
struct dentry *dir;
struct dentry *options;
@@ -704,7 +705,6 @@ int trace_array_printk_buf(struct ring_buffer *buffer,
void trace_printk_seq(struct trace_seq *s);
enum print_line_t print_trace_line(struct trace_iterator *iter);
-extern unsigned long trace_flags;
unsigned long global_trace_flags(void);
void set_global_trace_flags(unsigned long flags);
--
1.9.1.423.g4596e3a
next prev parent reply other threads:[~2014-03-24 18:15 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-24 18:13 [PATCH 0/3] Allow instances to independently set trace options Bharath Ravi
2014-03-24 18:13 ` [PATCH 1/3] tracing: Replace usage of trace_flags with new accessors Bharath Ravi
2014-04-25 18:46 ` Steven Rostedt
2014-03-24 18:13 ` Bharath Ravi [this message]
2014-03-24 18:13 ` [PATCH 3/3] tracing: Allow instances to independently set trace_overwrite Bharath Ravi
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=1395684826-22931-3-git-send-email-rbharath@google.com \
--to=rbharath@google.com \
--cc=chavey@google.com \
--cc=dhsharp@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=vnagarnaik@google.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®