mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-22 23:04:43 +00:00
Some clean ups and small fixes, but the biggest change is the addition
of the TRACE_DEFINE_ENUM() macro that can be used by tracepoints. Tracepoints have helper functions for the TP_printk() called __print_symbolic() and __print_flags() that lets a numeric number be displayed as a a human comprehensible text. What is placed in the TP_printk() is also shown in the tracepoint format file such that user space tools like perf and trace-cmd can parse the binary data and express the values too. Unfortunately, the way the TRACE_EVENT() macro works, anything placed in the TP_printk() will be shown pretty much exactly as is. The problem arises when enums are used. That's because unlike macros, enums will not be changed into their values by the C pre-processor. Thus, the enum string is exported to the format file, and this makes it useless for user space tools. The TRACE_DEFINE_ENUM() solves this by converting the enum strings in the TP_printk() format into their number, and that is what is shown to user space. For example, the tracepoint tlb_flush currently has this in its format file: __print_symbolic(REC->reason, { TLB_FLUSH_ON_TASK_SWITCH, "flush on task switch" }, { TLB_REMOTE_SHOOTDOWN, "remote shootdown" }, { TLB_LOCAL_SHOOTDOWN, "local shootdown" }, { TLB_LOCAL_MM_SHOOTDOWN, "local mm shootdown" }) After adding: TRACE_DEFINE_ENUM(TLB_FLUSH_ON_TASK_SWITCH); TRACE_DEFINE_ENUM(TLB_REMOTE_SHOOTDOWN); TRACE_DEFINE_ENUM(TLB_LOCAL_SHOOTDOWN); TRACE_DEFINE_ENUM(TLB_LOCAL_MM_SHOOTDOWN); Its format file will contain this: __print_symbolic(REC->reason, { 0, "flush on task switch" }, { 1, "remote shootdown" }, { 2, "local shootdown" }, { 3, "local mm shootdown" }) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVLBTuAAoJEEjnJuOKh9ldjHMIALdRS755TXCZGOf0r7O2akOR wMPeum7C+ae1mH+jCsJKUC0/jUfQKaMt/UxoHlipDgcGg8kD2jtGnGCw4Xlwvdsr y4rFmcTRSl1mo0zDSsg6ujoupHlVYN0+JPjrd7S3cv/llJoY49zcanNLF7S2XLeM dZCtWRLWYpBiWO68ai6AqJTnE/eGFIqBI048qb5Eg8dbK243SSeSIf9Ywhb+VsA+ aq6F7cWI/H6j4tbeza8tAN19dcwenDro5EfCDY8ARQHJu1f6Y3+DLf2imjkd6Aiu JVAoGIjHIpI+djwCZC1u4gi4urjfOqYartrM3Q54tb3YWYqHeNqP2ASI2a4EpYk= =Ixwt -----END PGP SIGNATURE----- Merge tag 'trace-v4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace Pull tracing updates from Steven Rostedt: "Some clean ups and small fixes, but the biggest change is the addition of the TRACE_DEFINE_ENUM() macro that can be used by tracepoints. Tracepoints have helper functions for the TP_printk() called __print_symbolic() and __print_flags() that lets a numeric number be displayed as a a human comprehensible text. What is placed in the TP_printk() is also shown in the tracepoint format file such that user space tools like perf and trace-cmd can parse the binary data and express the values too. Unfortunately, the way the TRACE_EVENT() macro works, anything placed in the TP_printk() will be shown pretty much exactly as is. The problem arises when enums are used. That's because unlike macros, enums will not be changed into their values by the C pre-processor. Thus, the enum string is exported to the format file, and this makes it useless for user space tools. The TRACE_DEFINE_ENUM() solves this by converting the enum strings in the TP_printk() format into their number, and that is what is shown to user space. For example, the tracepoint tlb_flush currently has this in its format file: __print_symbolic(REC->reason, { TLB_FLUSH_ON_TASK_SWITCH, "flush on task switch" }, { TLB_REMOTE_SHOOTDOWN, "remote shootdown" }, { TLB_LOCAL_SHOOTDOWN, "local shootdown" }, { TLB_LOCAL_MM_SHOOTDOWN, "local mm shootdown" }) After adding: TRACE_DEFINE_ENUM(TLB_FLUSH_ON_TASK_SWITCH); TRACE_DEFINE_ENUM(TLB_REMOTE_SHOOTDOWN); TRACE_DEFINE_ENUM(TLB_LOCAL_SHOOTDOWN); TRACE_DEFINE_ENUM(TLB_LOCAL_MM_SHOOTDOWN); Its format file will contain this: __print_symbolic(REC->reason, { 0, "flush on task switch" }, { 1, "remote shootdown" }, { 2, "local shootdown" }, { 3, "local mm shootdown" })" * tag 'trace-v4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (27 commits) tracing: Add enum_map file to show enums that have been mapped writeback: Export enums used by tracepoint to user space v4l: Export enums used by tracepoints to user space SUNRPC: Export enums in tracepoints to user space mm: tracing: Export enums in tracepoints to user space irq/tracing: Export enums in tracepoints to user space f2fs: Export the enums in the tracepoints to userspace net/9p/tracing: Export enums in tracepoints to userspace x86/tlb/trace: Export enums in used by tlb_flush tracepoint tracing/samples: Update the trace-event-sample.h with TRACE_DEFINE_ENUM() tracing: Allow for modules to convert their enums to values tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values tracing: Update trace-event-sample with TRACE_SYSTEM_VAR documentation tracing: Give system name a pointer brcmsmac: Move each system tracepoints to their own header iwlwifi: Move each system tracepoints to their own header mac80211: Move message tracepoints to their own header tracing: Add TRACE_SYSTEM_VAR to xhci-hcd tracing: Add TRACE_SYSTEM_VAR to kvm-s390 tracing: Add TRACE_SYSTEM_VAR to intel-sst ...
This commit is contained in:
commit
eeee78cf77
52 changed files with 1959 additions and 909 deletions
|
@ -1704,6 +1704,125 @@ __register_event(struct ftrace_event_call *call, struct module *mod)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *enum_replace(char *ptr, struct trace_enum_map *map, int len)
|
||||
{
|
||||
int rlen;
|
||||
int elen;
|
||||
|
||||
/* Find the length of the enum value as a string */
|
||||
elen = snprintf(ptr, 0, "%ld", map->enum_value);
|
||||
/* Make sure there's enough room to replace the string with the value */
|
||||
if (len < elen)
|
||||
return NULL;
|
||||
|
||||
snprintf(ptr, elen + 1, "%ld", map->enum_value);
|
||||
|
||||
/* Get the rest of the string of ptr */
|
||||
rlen = strlen(ptr + len);
|
||||
memmove(ptr + elen, ptr + len, rlen);
|
||||
/* Make sure we end the new string */
|
||||
ptr[elen + rlen] = 0;
|
||||
|
||||
return ptr + elen;
|
||||
}
|
||||
|
||||
static void update_event_printk(struct ftrace_event_call *call,
|
||||
struct trace_enum_map *map)
|
||||
{
|
||||
char *ptr;
|
||||
int quote = 0;
|
||||
int len = strlen(map->enum_string);
|
||||
|
||||
for (ptr = call->print_fmt; *ptr; ptr++) {
|
||||
if (*ptr == '\\') {
|
||||
ptr++;
|
||||
/* paranoid */
|
||||
if (!*ptr)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (*ptr == '"') {
|
||||
quote ^= 1;
|
||||
continue;
|
||||
}
|
||||
if (quote)
|
||||
continue;
|
||||
if (isdigit(*ptr)) {
|
||||
/* skip numbers */
|
||||
do {
|
||||
ptr++;
|
||||
/* Check for alpha chars like ULL */
|
||||
} while (isalnum(*ptr));
|
||||
/*
|
||||
* A number must have some kind of delimiter after
|
||||
* it, and we can ignore that too.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (isalpha(*ptr) || *ptr == '_') {
|
||||
if (strncmp(map->enum_string, ptr, len) == 0 &&
|
||||
!isalnum(ptr[len]) && ptr[len] != '_') {
|
||||
ptr = enum_replace(ptr, map, len);
|
||||
/* Hmm, enum string smaller than value */
|
||||
if (WARN_ON_ONCE(!ptr))
|
||||
return;
|
||||
/*
|
||||
* No need to decrement here, as enum_replace()
|
||||
* returns the pointer to the character passed
|
||||
* the enum, and two enums can not be placed
|
||||
* back to back without something in between.
|
||||
* We can skip that something in between.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
skip_more:
|
||||
do {
|
||||
ptr++;
|
||||
} while (isalnum(*ptr) || *ptr == '_');
|
||||
/*
|
||||
* If what comes after this variable is a '.' or
|
||||
* '->' then we can continue to ignore that string.
|
||||
*/
|
||||
if (*ptr == '.' || (ptr[0] == '-' && ptr[1] == '>')) {
|
||||
ptr += *ptr == '.' ? 1 : 2;
|
||||
goto skip_more;
|
||||
}
|
||||
/*
|
||||
* Once again, we can skip the delimiter that came
|
||||
* after the string.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void trace_event_enum_update(struct trace_enum_map **map, int len)
|
||||
{
|
||||
struct ftrace_event_call *call, *p;
|
||||
const char *last_system = NULL;
|
||||
int last_i;
|
||||
int i;
|
||||
|
||||
down_write(&trace_event_sem);
|
||||
list_for_each_entry_safe(call, p, &ftrace_events, list) {
|
||||
/* events are usually grouped together with systems */
|
||||
if (!last_system || call->class->system != last_system) {
|
||||
last_i = 0;
|
||||
last_system = call->class->system;
|
||||
}
|
||||
|
||||
for (i = last_i; i < len; i++) {
|
||||
if (call->class->system == map[i]->system) {
|
||||
/* Save the first system if need be */
|
||||
if (!last_i)
|
||||
last_i = i;
|
||||
update_event_printk(call, map[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
up_write(&trace_event_sem);
|
||||
}
|
||||
|
||||
static struct ftrace_event_file *
|
||||
trace_create_new_event(struct ftrace_event_call *call,
|
||||
struct trace_array *tr)
|
||||
|
@ -1915,7 +2034,7 @@ static int trace_module_notify(struct notifier_block *self,
|
|||
|
||||
static struct notifier_block trace_module_nb = {
|
||||
.notifier_call = trace_module_notify,
|
||||
.priority = 0,
|
||||
.priority = 1, /* higher than trace.c module notify */
|
||||
};
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue