aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2014-05-06 13:10:24 -0400
committerSteven Rostedt <rostedt@goodmis.org>2014-05-15 11:29:37 -0400
commit4449bf927b61bdb4389393c6fea6837214d1ace7 (patch)
tree5f9ea6d6f6e797decf7ddc9712295c4fb28c5f5f
parente18eead3c3e0087b38b3ccec684808b6ee9ba7c3 (diff)
tracing: Add __bitmask() macro to trace events to cpumasks and other bitmasks
Being able to show a cpumask of events can be useful as some events may affect only some CPUs. There is no standard way to record the cpumask and converting it to a string is rather expensive during the trace as traces happen in hotpaths. It would be better to record the raw event mask and be able to parse it at print time. The following macros were added for use with the TRACE_EVENT() macro: __bitmask() __assign_bitmask() __get_bitmask() To test this, I added this to the sched_migrate_task event, which looked like this: TRACE_EVENT(sched_migrate_task, TP_PROTO(struct task_struct *p, int dest_cpu, const struct cpumask *cpus), TP_ARGS(p, dest_cpu, cpus), TP_STRUCT__entry( __array( char, comm, TASK_COMM_LEN ) __field( pid_t, pid ) __field( int, prio ) __field( int, orig_cpu ) __field( int, dest_cpu ) __bitmask( cpumask, num_possible_cpus() ) ), TP_fast_assign( memcpy(__entry->comm, p->comm, TASK_COMM_LEN); __entry->pid = p->pid; __entry->prio = p->prio; __entry->orig_cpu = task_cpu(p); __entry->dest_cpu = dest_cpu; __assign_bitmask(cpumask, cpumask_bits(cpus), num_possible_cpus()); ), TP_printk("comm=%s pid=%d prio=%d orig_cpu=%d dest_cpu=%d cpumask=%s", __entry->comm, __entry->pid, __entry->prio, __entry->orig_cpu, __entry->dest_cpu, __get_bitmask(cpumask)) ); With the output of: ksmtuned-3613 [003] d..2 485.220508: sched_migrate_task: comm=ksmtuned pid=3615 prio=120 orig_cpu=3 dest_cpu=2 cpumask=00000000,0000000f migration/1-13 [001] d..5 485.221202: sched_migrate_task: comm=ksmtuned pid=3614 prio=120 orig_cpu=1 dest_cpu=0 cpumask=00000000,0000000f awk-3615 [002] d.H5 485.221747: sched_migrate_task: comm=rcu_preempt pid=7 prio=120 orig_cpu=0 dest_cpu=1 cpumask=00000000,000000ff migration/2-18 [002] d..5 485.222062: sched_migrate_task: comm=ksmtuned pid=3615 prio=120 orig_cpu=2 dest_cpu=3 cpumask=00000000,0000000f Link: http://lkml.kernel.org/r/1399377998-14870-6-git-send-email-javi.merino@arm.com Link: http://lkml.kernel.org/r/20140506132238.22e136d1@gandalf.local.home Suggested-by: Javi Merino <javi.merino@arm.com> Tested-by: Javi Merino <javi.merino@arm.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--include/linux/ftrace_event.h3
-rw-r--r--include/linux/trace_seq.h10
-rw-r--r--include/trace/ftrace.h57
-rw-r--r--kernel/trace/trace_output.c41
4 files changed, 110 insertions, 1 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index d16da3e53bc7..cff3106ffe2c 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -38,6 +38,9 @@ const char *ftrace_print_symbols_seq_u64(struct trace_seq *p,
38 *symbol_array); 38 *symbol_array);
39#endif 39#endif
40 40
41const char *ftrace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr,
42 unsigned int bitmask_size);
43
41const char *ftrace_print_hex_seq(struct trace_seq *p, 44const char *ftrace_print_hex_seq(struct trace_seq *p,
42 const unsigned char *buf, int len); 45 const unsigned char *buf, int len);
43 46
diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h
index a32d86ec8bf2..136116924d8d 100644
--- a/include/linux/trace_seq.h
+++ b/include/linux/trace_seq.h
@@ -46,6 +46,9 @@ extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
46extern void *trace_seq_reserve(struct trace_seq *s, size_t len); 46extern void *trace_seq_reserve(struct trace_seq *s, size_t len);
47extern int trace_seq_path(struct trace_seq *s, const struct path *path); 47extern int trace_seq_path(struct trace_seq *s, const struct path *path);
48 48
49extern int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
50 int nmaskbits);
51
49#else /* CONFIG_TRACING */ 52#else /* CONFIG_TRACING */
50static inline int trace_seq_printf(struct trace_seq *s, const char *fmt, ...) 53static inline int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
51{ 54{
@@ -57,6 +60,13 @@ trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
57 return 0; 60 return 0;
58} 61}
59 62
63static inline int
64trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
65 int nmaskbits)
66{
67 return 0;
68}
69
60static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s) 70static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s)
61{ 71{
62 return 0; 72 return 0;
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 0a1a4f7caf09..9b7a989dcbcc 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -53,6 +53,9 @@
53#undef __string 53#undef __string
54#define __string(item, src) __dynamic_array(char, item, -1) 54#define __string(item, src) __dynamic_array(char, item, -1)
55 55
56#undef __bitmask
57#define __bitmask(item, nr_bits) __dynamic_array(char, item, -1)
58
56#undef TP_STRUCT__entry 59#undef TP_STRUCT__entry
57#define TP_STRUCT__entry(args...) args 60#define TP_STRUCT__entry(args...) args
58 61
@@ -128,6 +131,9 @@
128#undef __string 131#undef __string
129#define __string(item, src) __dynamic_array(char, item, -1) 132#define __string(item, src) __dynamic_array(char, item, -1)
130 133
134#undef __bitmask
135#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
136
131#undef DECLARE_EVENT_CLASS 137#undef DECLARE_EVENT_CLASS
132#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 138#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
133 struct ftrace_data_offsets_##call { \ 139 struct ftrace_data_offsets_##call { \
@@ -200,6 +206,15 @@
200#undef __get_str 206#undef __get_str
201#define __get_str(field) (char *)__get_dynamic_array(field) 207#define __get_str(field) (char *)__get_dynamic_array(field)
202 208
209#undef __get_bitmask
210#define __get_bitmask(field) \
211 ({ \
212 void *__bitmask = __get_dynamic_array(field); \
213 unsigned int __bitmask_size; \
214 __bitmask_size = (__entry->__data_loc_##field >> 16) & 0xffff; \
215 ftrace_print_bitmask_seq(p, __bitmask, __bitmask_size); \
216 })
217
203#undef __print_flags 218#undef __print_flags
204#define __print_flags(flag, delim, flag_array...) \ 219#define __print_flags(flag, delim, flag_array...) \
205 ({ \ 220 ({ \
@@ -322,6 +337,9 @@ static struct trace_event_functions ftrace_event_type_funcs_##call = { \
322#undef __string 337#undef __string
323#define __string(item, src) __dynamic_array(char, item, -1) 338#define __string(item, src) __dynamic_array(char, item, -1)
324 339
340#undef __bitmask
341#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
342
325#undef DECLARE_EVENT_CLASS 343#undef DECLARE_EVENT_CLASS
326#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \ 344#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, func, print) \
327static int notrace __init \ 345static int notrace __init \
@@ -372,6 +390,29 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \
372#define __string(item, src) __dynamic_array(char, item, \ 390#define __string(item, src) __dynamic_array(char, item, \
373 strlen((src) ? (const char *)(src) : "(null)") + 1) 391 strlen((src) ? (const char *)(src) : "(null)") + 1)
374 392
393/*
394 * __bitmask_size_in_bytes_raw is the number of bytes needed to hold
395 * num_possible_cpus().
396 */
397#define __bitmask_size_in_bytes_raw(nr_bits) \
398 (((nr_bits) + 7) / 8)
399
400#define __bitmask_size_in_longs(nr_bits) \
401 ((__bitmask_size_in_bytes_raw(nr_bits) + \
402 ((BITS_PER_LONG / 8) - 1)) / (BITS_PER_LONG / 8))
403
404/*
405 * __bitmask_size_in_bytes is the number of bytes needed to hold
406 * num_possible_cpus() padded out to the nearest long. This is what
407 * is saved in the buffer, just to be consistent.
408 */
409#define __bitmask_size_in_bytes(nr_bits) \
410 (__bitmask_size_in_longs(nr_bits) * (BITS_PER_LONG / 8))
411
412#undef __bitmask
413#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, \
414 __bitmask_size_in_longs(nr_bits))
415
375#undef DECLARE_EVENT_CLASS 416#undef DECLARE_EVENT_CLASS
376#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 417#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
377static inline notrace int ftrace_get_offsets_##call( \ 418static inline notrace int ftrace_get_offsets_##call( \
@@ -513,12 +554,22 @@ static inline notrace int ftrace_get_offsets_##call( \
513 __entry->__data_loc_##item = __data_offsets.item; 554 __entry->__data_loc_##item = __data_offsets.item;
514 555
515#undef __string 556#undef __string
516#define __string(item, src) __dynamic_array(char, item, -1) \ 557#define __string(item, src) __dynamic_array(char, item, -1)
517 558
518#undef __assign_str 559#undef __assign_str
519#define __assign_str(dst, src) \ 560#define __assign_str(dst, src) \
520 strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)"); 561 strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)");
521 562
563#undef __bitmask
564#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
565
566#undef __get_bitmask
567#define __get_bitmask(field) (char *)__get_dynamic_array(field)
568
569#undef __assign_bitmask
570#define __assign_bitmask(dst, src, nr_bits) \
571 memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits))
572
522#undef TP_fast_assign 573#undef TP_fast_assign
523#define TP_fast_assign(args...) args 574#define TP_fast_assign(args...) args
524 575
@@ -586,6 +637,7 @@ static inline void ftrace_test_probe_##call(void) \
586#undef __print_hex 637#undef __print_hex
587#undef __get_dynamic_array 638#undef __get_dynamic_array
588#undef __get_str 639#undef __get_str
640#undef __get_bitmask
589 641
590#undef TP_printk 642#undef TP_printk
591#define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args) 643#define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args)
@@ -651,6 +703,9 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
651#undef __get_str 703#undef __get_str
652#define __get_str(field) (char *)__get_dynamic_array(field) 704#define __get_str(field) (char *)__get_dynamic_array(field)
653 705
706#undef __get_bitmask
707#define __get_bitmask(field) (char *)__get_dynamic_array(field)
708
654#undef __perf_addr 709#undef __perf_addr
655#define __perf_addr(a) (__addr = (a)) 710#define __perf_addr(a) (__addr = (a))
656 711
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index a436de18aa99..f3dad80c20b2 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -126,6 +126,34 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
126EXPORT_SYMBOL_GPL(trace_seq_printf); 126EXPORT_SYMBOL_GPL(trace_seq_printf);
127 127
128/** 128/**
129 * trace_seq_bitmask - put a list of longs as a bitmask print output
130 * @s: trace sequence descriptor
131 * @maskp: points to an array of unsigned longs that represent a bitmask
132 * @nmaskbits: The number of bits that are valid in @maskp
133 *
134 * It returns 0 if the trace oversizes the buffer's free
135 * space, 1 otherwise.
136 *
137 * Writes a ASCII representation of a bitmask string into @s.
138 */
139int
140trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
141 int nmaskbits)
142{
143 int len = (PAGE_SIZE - 1) - s->len;
144 int ret;
145
146 if (s->full || !len)
147 return 0;
148
149 ret = bitmap_scnprintf(s->buffer, len, maskp, nmaskbits);
150 s->len += ret;
151
152 return 1;
153}
154EXPORT_SYMBOL_GPL(trace_seq_bitmask);
155
156/**
129 * trace_seq_vprintf - sequence printing of trace information 157 * trace_seq_vprintf - sequence printing of trace information
130 * @s: trace sequence descriptor 158 * @s: trace sequence descriptor
131 * @fmt: printf format string 159 * @fmt: printf format string
@@ -399,6 +427,19 @@ EXPORT_SYMBOL(ftrace_print_symbols_seq_u64);
399#endif 427#endif
400 428
401const char * 429const char *
430ftrace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr,
431 unsigned int bitmask_size)
432{
433 const char *ret = p->buffer + p->len;
434
435 trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8);
436 trace_seq_putc(p, 0);
437
438 return ret;
439}
440EXPORT_SYMBOL_GPL(ftrace_print_bitmask_seq);
441
442const char *
402ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) 443ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len)
403{ 444{
404 int i; 445 int i;