diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-14 10:49:03 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-14 10:49:03 -0700 |
commit | eeee78cf77df0450ca285a7cd6d73842181e825c (patch) | |
tree | 330540323eae82977756e5086492654b9e461871 | |
parent | 3f3c73de77b5598e9f87812ac4da9445090c3b4a (diff) | |
parent | 9828413d4715d4ed12bc92b161f4ed377d777ffb (diff) | |
download | lwn-eeee78cf77df0450ca285a7cd6d73842181e825c.tar.gz lwn-eeee78cf77df0450ca285a7cd6d73842181e825c.zip |
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
...
52 files changed, 1959 insertions, 909 deletions
diff --git a/arch/s390/kvm/trace-s390.h b/arch/s390/kvm/trace-s390.h index 653a7ec09ef5..3208d33a48cb 100644 --- a/arch/s390/kvm/trace-s390.h +++ b/arch/s390/kvm/trace-s390.h @@ -10,6 +10,13 @@ #define TRACE_INCLUDE_FILE trace-s390 /* + * The TRACE_SYSTEM_VAR defaults to TRACE_SYSTEM, but must be a + * legitimate C variable. It is not exported to user space. + */ +#undef TRACE_SYSTEM_VAR +#define TRACE_SYSTEM_VAR kvm_s390 + +/* * Trace point for the creation of the kvm instance. */ TRACE_EVENT(kvm_s390_create_vm, diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h index 27cc95f36381..ce3c42813fbb 100644 --- a/drivers/gpu/drm/drm_trace.h +++ b/drivers/gpu/drm/drm_trace.h @@ -7,7 +7,6 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM drm -#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) #define TRACE_INCLUDE_FILE drm_trace TRACE_EVENT(drm_vblank_event, diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 6058a01b4443..d776621c8521 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -12,7 +12,6 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM i915 -#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) #define TRACE_INCLUDE_FILE i915_trace /* pipe updates */ diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h index ce075cb08cb2..fdce4062901f 100644 --- a/drivers/gpu/drm/radeon/radeon_trace.h +++ b/drivers/gpu/drm/radeon/radeon_trace.h @@ -9,7 +9,6 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM radeon -#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) #define TRACE_INCLUDE_FILE radeon_trace TRACE_EVENT(radeon_bo_create, diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_brcmsmac.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_brcmsmac.h new file mode 100644 index 000000000000..a0da3248b942 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_brcmsmac.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ) +#define __TRACE_BRCMSMAC_H + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM brcmsmac + +/* + * We define a tracepoint, its arguments, its printk format and its + * 'fast binary record' layout. + */ +TRACE_EVENT(brcms_timer, + /* TPPROTO is the prototype of the function called by this tracepoint */ + TP_PROTO(struct brcms_timer *t), + /* + * TPARGS(firstarg, p) are the parameters names, same as found in the + * prototype. + */ + TP_ARGS(t), + /* + * Fast binary tracing: define the trace record via TP_STRUCT__entry(). + * You can think about it like a regular C structure local variable + * definition. + */ + TP_STRUCT__entry( + __field(uint, ms) + __field(uint, set) + __field(uint, periodic) + ), + TP_fast_assign( + __entry->ms = t->ms; + __entry->set = t->set; + __entry->periodic = t->periodic; + ), + TP_printk( + "ms=%u set=%u periodic=%u", + __entry->ms, __entry->set, __entry->periodic + ) +); + +TRACE_EVENT(brcms_dpc, + TP_PROTO(unsigned long data), + TP_ARGS(data), + TP_STRUCT__entry( + __field(unsigned long, data) + ), + TP_fast_assign( + __entry->data = data; + ), + TP_printk( + "data=%p", + (void *)__entry->data + ) +); + +TRACE_EVENT(brcms_macintstatus, + TP_PROTO(const struct device *dev, int in_isr, u32 macintstatus, + u32 mask), + TP_ARGS(dev, in_isr, macintstatus, mask), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) + __field(int, in_isr) + __field(u32, macintstatus) + __field(u32, mask) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); + __entry->in_isr = in_isr; + __entry->macintstatus = macintstatus; + __entry->mask = mask; + ), + TP_printk("[%s] in_isr=%d macintstatus=%#x mask=%#x", __get_str(dev), + __entry->in_isr, __entry->macintstatus, __entry->mask) +); +#endif /* __TRACE_BRCMSMAC_H */ + +#ifdef CONFIG_BRCM_TRACING + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE brcms_trace_brcmsmac +#include <trace/define_trace.h> + +#endif /* CONFIG_BRCM_TRACING */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h new file mode 100644 index 000000000000..0e8a69ab909f --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if !defined(__TRACE_BRCMSMAC_MSG_H) || defined(TRACE_HEADER_MULTI_READ) +#define __TRACE_BRCMSMAC_MSG_H + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM brcmsmac_msg + +#define MAX_MSG_LEN 100 + +DECLARE_EVENT_CLASS(brcms_msg_event, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf), + TP_STRUCT__entry( + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + TP_fast_assign( + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + TP_printk("%s", __get_str(msg)) +); + +DEFINE_EVENT(brcms_msg_event, brcms_info, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(brcms_msg_event, brcms_warn, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(brcms_msg_event, brcms_err, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(brcms_msg_event, brcms_crit, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +TRACE_EVENT(brcms_dbg, + TP_PROTO(u32 level, const char *func, struct va_format *vaf), + TP_ARGS(level, func, vaf), + TP_STRUCT__entry( + __field(u32, level) + __string(func, func) + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + TP_fast_assign( + __entry->level = level; + __assign_str(func, func); + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + TP_printk("%s: %s", __get_str(func), __get_str(msg)) +); +#endif /* __TRACE_BRCMSMAC_MSG_H */ + +#ifdef CONFIG_BRCM_TRACING + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE brcms_trace_brcmsmac_msg +#include <trace/define_trace.h> + +#endif /* CONFIG_BRCM_TRACING */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h new file mode 100644 index 000000000000..cf2cc070f1e5 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if !defined(__TRACE_BRCMSMAC_TX_H) || defined(TRACE_HEADER_MULTI_READ) +#define __TRACE_BRCMSMAC_TX_H + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM brcmsmac_tx + +TRACE_EVENT(brcms_txdesc, + TP_PROTO(const struct device *dev, + void *txh, size_t txh_len), + TP_ARGS(dev, txh, txh_len), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) + __dynamic_array(u8, txh, txh_len) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); + memcpy(__get_dynamic_array(txh), txh, txh_len); + ), + TP_printk("[%s] txdesc", __get_str(dev)) +); + +TRACE_EVENT(brcms_txstatus, + TP_PROTO(const struct device *dev, u16 framelen, u16 frameid, + u16 status, u16 lasttxtime, u16 sequence, u16 phyerr, + u16 ackphyrxsh), + TP_ARGS(dev, framelen, frameid, status, lasttxtime, sequence, phyerr, + ackphyrxsh), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) + __field(u16, framelen) + __field(u16, frameid) + __field(u16, status) + __field(u16, lasttxtime) + __field(u16, sequence) + __field(u16, phyerr) + __field(u16, ackphyrxsh) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); + __entry->framelen = framelen; + __entry->frameid = frameid; + __entry->status = status; + __entry->lasttxtime = lasttxtime; + __entry->sequence = sequence; + __entry->phyerr = phyerr; + __entry->ackphyrxsh = ackphyrxsh; + ), + TP_printk("[%s] FrameId %#04x TxStatus %#04x LastTxTime %#04x " + "Seq %#04x PHYTxStatus %#04x RxAck %#04x", + __get_str(dev), __entry->frameid, __entry->status, + __entry->lasttxtime, __entry->sequence, __entry->phyerr, + __entry->ackphyrxsh) +); + +TRACE_EVENT(brcms_ampdu_session, + TP_PROTO(const struct device *dev, unsigned max_ampdu_len, + u16 max_ampdu_frames, u16 ampdu_len, u16 ampdu_frames, + u16 dma_len), + TP_ARGS(dev, max_ampdu_len, max_ampdu_frames, ampdu_len, ampdu_frames, + dma_len), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) + __field(unsigned, max_ampdu_len) + __field(u16, max_ampdu_frames) + __field(u16, ampdu_len) + __field(u16, ampdu_frames) + __field(u16, dma_len) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); + __entry->max_ampdu_len = max_ampdu_len; + __entry->max_ampdu_frames = max_ampdu_frames; + __entry->ampdu_len = ampdu_len; + __entry->ampdu_frames = ampdu_frames; + __entry->dma_len = dma_len; + ), + TP_printk("[%s] ampdu session max_len=%u max_frames=%u len=%u frames=%u dma_len=%u", + __get_str(dev), __entry->max_ampdu_len, + __entry->max_ampdu_frames, __entry->ampdu_len, + __entry->ampdu_frames, __entry->dma_len) +); +#endif /* __TRACE_BRCMSMAC_TX_H */ + +#ifdef CONFIG_BRCM_TRACING + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE brcms_trace_brcmsmac_tx +#include <trace/define_trace.h> + +#endif /* CONFIG_BRCM_TRACING */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h index 871781e6a713..cbf2f06436fc 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h @@ -14,9 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ) - -#define __TRACE_BRCMSMAC_H +#ifndef __BRCMS_TRACE_EVENTS_H +#define __BRCMS_TRACE_EVENTS_H #include <linux/types.h> #include <linux/device.h> @@ -34,222 +33,8 @@ static inline void trace_ ## name(proto) {} static inline void trace_ ## name(proto) {} #endif -#undef TRACE_SYSTEM -#define TRACE_SYSTEM brcmsmac - -/* - * We define a tracepoint, its arguments, its printk format and its - * 'fast binary record' layout. - */ -TRACE_EVENT(brcms_timer, - /* TPPROTO is the prototype of the function called by this tracepoint */ - TP_PROTO(struct brcms_timer *t), - /* - * TPARGS(firstarg, p) are the parameters names, same as found in the - * prototype. - */ - TP_ARGS(t), - /* - * Fast binary tracing: define the trace record via TP_STRUCT__entry(). - * You can think about it like a regular C structure local variable - * definition. - */ - TP_STRUCT__entry( - __field(uint, ms) - __field(uint, set) - __field(uint, periodic) - ), - TP_fast_assign( - __entry->ms = t->ms; - __entry->set = t->set; - __entry->periodic = t->periodic; - ), - TP_printk( - "ms=%u set=%u periodic=%u", - __entry->ms, __entry->set, __entry->periodic - ) -); - -TRACE_EVENT(brcms_dpc, - TP_PROTO(unsigned long data), - TP_ARGS(data), - TP_STRUCT__entry( - __field(unsigned long, data) - ), - TP_fast_assign( - __entry->data = data; - ), - TP_printk( - "data=%p", - (void *)__entry->data - ) -); - -TRACE_EVENT(brcms_macintstatus, - TP_PROTO(const struct device *dev, int in_isr, u32 macintstatus, - u32 mask), - TP_ARGS(dev, in_isr, macintstatus, mask), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __field(int, in_isr) - __field(u32, macintstatus) - __field(u32, mask) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - __entry->in_isr = in_isr; - __entry->macintstatus = macintstatus; - __entry->mask = mask; - ), - TP_printk("[%s] in_isr=%d macintstatus=%#x mask=%#x", __get_str(dev), - __entry->in_isr, __entry->macintstatus, __entry->mask) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM brcmsmac_tx - -TRACE_EVENT(brcms_txdesc, - TP_PROTO(const struct device *dev, - void *txh, size_t txh_len), - TP_ARGS(dev, txh, txh_len), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __dynamic_array(u8, txh, txh_len) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - memcpy(__get_dynamic_array(txh), txh, txh_len); - ), - TP_printk("[%s] txdesc", __get_str(dev)) -); - -TRACE_EVENT(brcms_txstatus, - TP_PROTO(const struct device *dev, u16 framelen, u16 frameid, - u16 status, u16 lasttxtime, u16 sequence, u16 phyerr, - u16 ackphyrxsh), - TP_ARGS(dev, framelen, frameid, status, lasttxtime, sequence, phyerr, - ackphyrxsh), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __field(u16, framelen) - __field(u16, frameid) - __field(u16, status) - __field(u16, lasttxtime) - __field(u16, sequence) - __field(u16, phyerr) - __field(u16, ackphyrxsh) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - __entry->framelen = framelen; - __entry->frameid = frameid; - __entry->status = status; - __entry->lasttxtime = lasttxtime; - __entry->sequence = sequence; - __entry->phyerr = phyerr; - __entry->ackphyrxsh = ackphyrxsh; - ), - TP_printk("[%s] FrameId %#04x TxStatus %#04x LastTxTime %#04x " - "Seq %#04x PHYTxStatus %#04x RxAck %#04x", - __get_str(dev), __entry->frameid, __entry->status, - __entry->lasttxtime, __entry->sequence, __entry->phyerr, - __entry->ackphyrxsh) -); - -TRACE_EVENT(brcms_ampdu_session, - TP_PROTO(const struct device *dev, unsigned max_ampdu_len, - u16 max_ampdu_frames, u16 ampdu_len, u16 ampdu_frames, - u16 dma_len), - TP_ARGS(dev, max_ampdu_len, max_ampdu_frames, ampdu_len, ampdu_frames, - dma_len), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __field(unsigned, max_ampdu_len) - __field(u16, max_ampdu_frames) - __field(u16, ampdu_len) - __field(u16, ampdu_frames) - __field(u16, dma_len) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - __entry->max_ampdu_len = max_ampdu_len; - __entry->max_ampdu_frames = max_ampdu_frames; - __entry->ampdu_len = ampdu_len; - __entry->ampdu_frames = ampdu_frames; - __entry->dma_len = dma_len; - ), - TP_printk("[%s] ampdu session max_len=%u max_frames=%u len=%u frames=%u dma_len=%u", - __get_str(dev), __entry->max_ampdu_len, - __entry->max_ampdu_frames, __entry->ampdu_len, - __entry->ampdu_frames, __entry->dma_len) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM brcmsmac_msg - -#define MAX_MSG_LEN 100 - -DECLARE_EVENT_CLASS(brcms_msg_event, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf), - TP_STRUCT__entry( - __dynamic_array(char, msg, MAX_MSG_LEN) - ), - TP_fast_assign( - WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), - MAX_MSG_LEN, vaf->fmt, - *vaf->va) >= MAX_MSG_LEN); - ), - TP_printk("%s", __get_str(msg)) -); - -DEFINE_EVENT(brcms_msg_event, brcms_info, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(brcms_msg_event, brcms_warn, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(brcms_msg_event, brcms_err, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(brcms_msg_event, brcms_crit, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -TRACE_EVENT(brcms_dbg, - TP_PROTO(u32 level, const char *func, struct va_format *vaf), - TP_ARGS(level, func, vaf), - TP_STRUCT__entry( - __field(u32, level) - __string(func, func) - __dynamic_array(char, msg, MAX_MSG_LEN) - ), - TP_fast_assign( - __entry->level = level; - __assign_str(func, func); - WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), - MAX_MSG_LEN, vaf->fmt, - *vaf->va) >= MAX_MSG_LEN); - ), - TP_printk("%s: %s", __get_str(func), __get_str(msg)) -); +#include "brcms_trace_brcmsmac.h" +#include "brcms_trace_brcmsmac_tx.h" +#include "brcms_trace_brcmsmac_msg.h" #endif /* __TRACE_BRCMSMAC_H */ - -#ifdef CONFIG_BRCM_TRACING - -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE brcms_trace_events - -#include <trace/define_trace.h> - -#endif /* CONFIG_BRCM_TRACING */ diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace-data.h b/drivers/net/wireless/iwlwifi/iwl-devtrace-data.h new file mode 100644 index 000000000000..04e6649340b8 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace-data.h @@ -0,0 +1,79 @@ +/****************************************************************************** + * + * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless <ilw@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#if !defined(__IWLWIFI_DEVICE_TRACE_DATA) || defined(TRACE_HEADER_MULTI_READ) +#define __IWLWIFI_DEVICE_TRACE_DATA + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM iwlwifi_data + +TRACE_EVENT(iwlwifi_dev_tx_data, + TP_PROTO(const struct device *dev, + struct sk_buff *skb, + void *data, size_t data_len), + TP_ARGS(dev, skb, data, data_len), + TP_STRUCT__entry( + DEV_ENTRY + + __dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0) + ), + TP_fast_assign( + DEV_ASSIGN; + if (iwl_trace_data(skb)) + memcpy(__get_dynamic_array(data), data, data_len); + ), + TP_printk("[%s] TX frame data", __get_str(dev)) +); + +TRACE_EVENT(iwlwifi_dev_rx_data, + TP_PROTO(const struct device *dev, + const struct iwl_trans *trans, + void *rxbuf, size_t len), + TP_ARGS(dev, trans, rxbuf, len), + TP_STRUCT__entry( + DEV_ENTRY + + __dynamic_array(u8, data, + len - iwl_rx_trace_len(trans, rxbuf, len)) + ), + TP_fast_assign( + size_t offs = iwl_rx_trace_len(trans, rxbuf, len); + DEV_ASSIGN; + if (offs < len) + memcpy(__get_dynamic_array(data), + ((u8 *)rxbuf) + offs, len - offs); + ), + TP_printk("[%s] RX frame data", __get_str(dev)) +); +#endif /* __IWLWIFI_DEVICE_TRACE_DATA */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE iwl-devtrace-data +#include <trace/define_trace.h> diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace-io.h b/drivers/net/wireless/iwlwifi/iwl-devtrace-io.h new file mode 100644 index 000000000000..f62c54485852 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace-io.h @@ -0,0 +1,155 @@ +/****************************************************************************** + * + * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless <ilw@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#if !defined(__IWLWIFI_DEVICE_TRACE_IO) || defined(TRACE_HEADER_MULTI_READ) +#define __IWLWIFI_DEVICE_TRACE_IO + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM iwlwifi_io + +TRACE_EVENT(iwlwifi_dev_ioread32, + TP_PROTO(const struct device *dev, u32 offs, u32 val), + TP_ARGS(dev, offs, val), + TP_STRUCT__entry( + DEV_ENTRY + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] read io[%#x] = %#x", + __get_str(dev), __entry->offs, __entry->val) +); + +TRACE_EVENT(iwlwifi_dev_iowrite8, + TP_PROTO(const struct device *dev, u32 offs, u8 val), + TP_ARGS(dev, offs, val), + TP_STRUCT__entry( + DEV_ENTRY + __field(u32, offs) + __field(u8, val) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] write io[%#x] = %#x)", + __get_str(dev), __entry->offs, __entry->val) +); + +TRACE_EVENT(iwlwifi_dev_iowrite32, + TP_PROTO(const struct device *dev, u32 offs, u32 val), + TP_ARGS(dev, offs, val), + TP_STRUCT__entry( + DEV_ENTRY + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] write io[%#x] = %#x)", + __get_str(dev), __entry->offs, __entry->val) +); + +TRACE_EVENT(iwlwifi_dev_iowrite_prph32, + TP_PROTO(const struct device *dev, u32 offs, u32 val), + TP_ARGS(dev, offs, val), + TP_STRUCT__entry( + DEV_ENTRY + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] write PRPH[%#x] = %#x)", + __get_str(dev), __entry->offs, __entry->val) +); + +TRACE_EVENT(iwlwifi_dev_ioread_prph32, + TP_PROTO(const struct device *dev, u32 offs, u32 val), + TP_ARGS(dev, offs, val), + TP_STRUCT__entry( + DEV_ENTRY + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] read PRPH[%#x] = %#x", + __get_str(dev), __entry->offs, __entry->val) +); + +TRACE_EVENT(iwlwifi_dev_irq, + TP_PROTO(const struct device *dev), + TP_ARGS(dev), + TP_STRUCT__entry( + DEV_ENTRY + ), + TP_fast_assign( + DEV_ASSIGN; + ), + /* TP_printk("") doesn't compile */ + TP_printk("%d", 0) +); + +TRACE_EVENT(iwlwifi_dev_ict_read, + TP_PROTO(const struct device *dev, u32 index, u32 value), + TP_ARGS(dev, index, value), + TP_STRUCT__entry( + DEV_ENTRY + __field(u32, index) + __field(u32, value) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->index = index; + __entry->value = value; + ), + TP_printk("[%s] read ict[%d] = %#.8x", + __get_str(dev), __entry->index, __entry->value) +); +#endif /* __IWLWIFI_DEVICE_TRACE_IO */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE iwl-devtrace-io +#include <trace/define_trace.h> diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace-iwlwifi.h b/drivers/net/wireless/iwlwifi/iwl-devtrace-iwlwifi.h new file mode 100644 index 000000000000..6cb66a988271 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace-iwlwifi.h @@ -0,0 +1,200 @@ +/****************************************************************************** + * + * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless <ilw@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#if !defined(__IWLWIFI_DEVICE_TRACE_IWLWIFI) || defined(TRACE_HEADER_MULTI_READ) +#define __IWLWIFI_DEVICE_TRACE_IWLWIFI + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM iwlwifi + +TRACE_EVENT(iwlwifi_dev_hcmd, + TP_PROTO(const struct device *dev, + struct iwl_host_cmd *cmd, u16 total_size, + struct iwl_cmd_header *hdr), + TP_ARGS(dev, cmd, total_size, hdr), + TP_STRUCT__entry( + DEV_ENTRY + __dynamic_array(u8, hcmd, total_size) + __field(u32, flags) + ), + TP_fast_assign( + int i, offset = sizeof(*hdr); + + DEV_ASSIGN; + __entry->flags = cmd->flags; + memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr)); + + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { + if (!cmd->len[i]) + continue; + memcpy((u8 *)__get_dynamic_array(hcmd) + offset, + cmd->data[i], cmd->len[i]); + offset += cmd->len[i]; + } + ), + TP_printk("[%s] hcmd %#.2x (%ssync)", + __get_str(dev), ((u8 *)__get_dynamic_array(hcmd))[0], + __entry->flags & CMD_ASYNC ? "a" : "") +); + +TRACE_EVENT(iwlwifi_dev_rx, + TP_PROTO(const struct device *dev, const struct iwl_trans *trans, + void *rxbuf, size_t len), + TP_ARGS(dev, trans, rxbuf, len), + TP_STRUCT__entry( + DEV_ENTRY + __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, rxbuf, len)) + ), + TP_fast_assign( + DEV_ASSIGN; + memcpy(__get_dynamic_array(rxbuf), rxbuf, + iwl_rx_trace_len(trans, rxbuf, len)); + ), + TP_printk("[%s] RX cmd %#.2x", + __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) +); + +TRACE_EVENT(iwlwifi_dev_tx, + TP_PROTO(const struct device *dev, struct sk_buff *skb, + void *tfd, size_t tfdlen, + void *buf0, size_t buf0_len, + void *buf1, size_t buf1_len), + TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), + TP_STRUCT__entry( + DEV_ENTRY + + __field(size_t, framelen) + __dynamic_array(u8, tfd, tfdlen) + + /* + * Do not insert between or below these items, + * we want to keep the frame together (except + * for the possible padding). + */ + __dynamic_array(u8, buf0, buf0_len) + __dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->framelen = buf0_len + buf1_len; + memcpy(__get_dynamic_array(tfd), tfd, tfdlen); + memcpy(__get_dynamic_array(buf0), buf0, buf0_len); + if (!iwl_trace_data(skb)) + memcpy(__get_dynamic_array(buf1), buf1, buf1_len); + ), + TP_printk("[%s] TX %.2x (%zu bytes)", + __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], + __entry->framelen) +); + +TRACE_EVENT(iwlwifi_dev_ucode_error, + TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, + u32 data1, u32 data2, u32 line, u32 blink1, + u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, + u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, + u32 brd_ver), + TP_ARGS(dev, desc, tsf_low, data1, data2, line, + blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, + gp3, ucode_ver, hw_ver, brd_ver), + TP_STRUCT__entry( + DEV_ENTRY + __field(u32, desc) + __field(u32, tsf_low) + __field(u32, data1) + __field(u32, data2) + __field(u32, line) + __field(u32, blink1) + __field(u32, blink2) + __field(u32, ilink1) + __field(u32, ilink2) + __field(u32, bcon_time) + __field(u32, gp1) + __field(u32, gp2) + __field(u32, gp3) + __field(u32, ucode_ver) + __field(u32, hw_ver) + __field(u32, brd_ver) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->desc = desc; + __entry->tsf_low = tsf_low; + __entry->data1 = data1; + __entry->data2 = data2; + __entry->line = line; + __entry->blink1 = blink1; + __entry->blink2 = blink2; + __entry->ilink1 = ilink1; + __entry->ilink2 = ilink2; + __entry->bcon_time = bcon_time; + __entry->gp1 = gp1; + __entry->gp2 = gp2; + __entry->gp3 = gp3; + __entry->ucode_ver = ucode_ver; + __entry->hw_ver = hw_ver; + __entry->brd_ver = brd_ver; + ), + TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " + "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " + "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " + "hw 0x%08X brd 0x%08X", + __get_str(dev), __entry->desc, __entry->tsf_low, + __entry->data1, + __entry->data2, __entry->line, __entry->blink1, + __entry->blink2, __entry->ilink1, __entry->ilink2, + __entry->bcon_time, __entry->gp1, __entry->gp2, + __entry->gp3, __entry->ucode_ver, __entry->hw_ver, + __entry->brd_ver) +); + +TRACE_EVENT(iwlwifi_dev_ucode_event, + TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), + TP_ARGS(dev, time, data, ev), + TP_STRUCT__entry( + DEV_ENTRY + + __field(u32, time) + __field(u32, data) + __field(u32, ev) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->time = time; + __entry->data = data; + __entry->ev = ev; + ), + TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", + __get_str(dev), __entry->time, __entry->data, __entry->ev) +); +#endif /* __IWLWIFI_DEVICE_TRACE_IWLWIFI */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE iwl-devtrace-iwlwifi +#include <trace/define_trace.h> diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace-msg.h b/drivers/net/wireless/iwlwifi/iwl-devtrace-msg.h new file mode 100644 index 000000000000..a3b3c2465f89 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace-msg.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * + * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless <ilw@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#if !defined(__IWLWIFI_DEVICE_TRACE_MSG) || defined(TRACE_HEADER_MULTI_READ) +#define __IWLWIFI_DEVICE_TRACE_MSG + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM iwlwifi_msg + +#define MAX_MSG_LEN 110 + +DECLARE_EVENT_CLASS(iwlwifi_msg_event, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf), + TP_STRUCT__entry( + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + TP_fast_assign( + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + TP_printk("%s", __get_str(msg)) +); + +DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +TRACE_EVENT(iwlwifi_dbg, + TP_PROTO(u32 level, bool in_interrupt, const char *function, + struct va_format *vaf), + TP_ARGS(level, in_interrupt, function, vaf), + TP_STRUCT__entry( + __field(u32, level) + __field(u8, in_interrupt) + __string(function, function) + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + TP_fast_assign( + __entry->level = level; + __entry->in_interrupt = in_interrupt; + __assign_str(function, function); + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + TP_printk("%s", __get_str(msg)) +); +#endif /* __IWLWIFI_DEVICE_TRACE_MSG */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE iwl-devtrace-msg +#include <trace/define_trace.h> diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace-ucode.h b/drivers/net/wireless/iwlwifi/iwl-devtrace-ucode.h new file mode 100644 index 000000000000..10839fae9cd9 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace-ucode.h @@ -0,0 +1,81 @@ +/****************************************************************************** + * + * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless <ilw@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#if !defined(__IWLWIFI_DEVICE_TRACE_UCODE) || defined(TRACE_HEADER_MULTI_READ) +#define __IWLWIFI_DEVICE_TRACE_UCODE + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM iwlwifi_ucode + +TRACE_EVENT(iwlwifi_dev_ucode_cont_event, + TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), + TP_ARGS(dev, time, data, ev), + TP_STRUCT__entry( + DEV_ENTRY + + __field(u32, time) + __field(u32, data) + __field(u32, ev) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->time = time; + __entry->data = data; + __entry->ev = ev; + ), + TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", + __get_str(dev), __entry->time, __entry->data, __entry->ev) +); + +TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, + TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry), + TP_ARGS(dev, wraps, n_entry, p_entry), + TP_STRUCT__entry( + DEV_ENTRY + + __field(u32, wraps) + __field(u32, n_entry) + __field(u32, p_entry) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->wraps = wraps; + __entry->n_entry = n_entry; + __entry->p_entry = p_entry; + ), + TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X", + __get_str(dev), __entry->wraps, __entry->n_entry, + __entry->p_entry) +); +#endif /* __IWLWIFI_DEVICE_TRACE_UCODE */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE iwl-devtrace-ucode +#include <trace/define_trace.h> diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 78bd41bf34b0..b87acd6a229b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -24,7 +24,7 @@ * *****************************************************************************/ -#if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) +#ifndef __IWLWIFI_DEVICE_TRACE #include <linux/skbuff.h> #include <linux/ieee80211.h> #include <net/cfg80211.h> @@ -80,436 +80,10 @@ static inline void trace_ ## name(proto) {} #define DEV_ENTRY __string(dev, dev_name(dev)) #define DEV_ASSIGN __assign_str(dev, dev_name(dev)) -#undef TRACE_SYSTEM -#define TRACE_SYSTEM iwlwifi_io +#include "iwl-devtrace-io.h" +#include "iwl-devtrace-ucode.h" +#include "iwl-devtrace-msg.h" +#include "iwl-devtrace-data.h" +#include "iwl-devtrace-iwlwifi.h" -TRACE_EVENT(iwlwifi_dev_ioread32, - TP_PROTO(const struct device *dev, u32 offs, u32 val), - TP_ARGS(dev, offs, val), - TP_STRUCT__entry( - DEV_ENTRY - __field(u32, offs) - __field(u32, val) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->offs = offs; - __entry->val = val; - ), - TP_printk("[%s] read io[%#x] = %#x", - __get_str(dev), __entry->offs, __entry->val) -); - -TRACE_EVENT(iwlwifi_dev_iowrite8, - TP_PROTO(const struct device *dev, u32 offs, u8 val), - TP_ARGS(dev, offs, val), - TP_STRUCT__entry( - DEV_ENTRY - __field(u32, offs) - __field(u8, val) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->offs = offs; - __entry->val = val; - ), - TP_printk("[%s] write io[%#x] = %#x)", - __get_str(dev), __entry->offs, __entry->val) -); - -TRACE_EVENT(iwlwifi_dev_iowrite32, - TP_PROTO(const struct device *dev, u32 offs, u32 val), - TP_ARGS(dev, offs, val), - TP_STRUCT__entry( - DEV_ENTRY - __field(u32, offs) - __field(u32, val) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->offs = offs; - __entry->val = val; - ), - TP_printk("[%s] write io[%#x] = %#x)", - __get_str(dev), __entry->offs, __entry->val) -); - -TRACE_EVENT(iwlwifi_dev_iowrite_prph32, - TP_PROTO(const struct device *dev, u32 offs, u32 val), - TP_ARGS(dev, offs, val), - TP_STRUCT__entry( - DEV_ENTRY - __field(u32, offs) - __field(u32, val) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->offs = offs; - __entry->val = val; - ), - TP_printk("[%s] write PRPH[%#x] = %#x)", - __get_str(dev), __entry->offs, __entry->val) -); - -TRACE_EVENT(iwlwifi_dev_ioread_prph32, - TP_PROTO(const struct device *dev, u32 offs, u32 val), - TP_ARGS(dev, offs, val), - TP_STRUCT__entry( - DEV_ENTRY - __field(u32, offs) - __field(u32, val) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->offs = offs; - __entry->val = val; - ), - TP_printk("[%s] read PRPH[%#x] = %#x", - __get_str(dev), __entry->offs, __entry->val) -); - -TRACE_EVENT(iwlwifi_dev_irq, - TP_PROTO(const struct device *dev), - TP_ARGS(dev), - TP_STRUCT__entry( - DEV_ENTRY - ), - TP_fast_assign( - DEV_ASSIGN; - ), - /* TP_printk("") doesn't compile */ - TP_printk("%d", 0) -); - -TRACE_EVENT(iwlwifi_dev_ict_read, - TP_PROTO(const struct device *dev, u32 index, u32 value), - TP_ARGS(dev, index, value), - TP_STRUCT__entry( - DEV_ENTRY - __field(u32, index) - __field(u32, value) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->index = index; - __entry->value = value; - ), - TP_printk("[%s] read ict[%d] = %#.8x", - __get_str(dev), __entry->index, __entry->value) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM iwlwifi_ucode - -TRACE_EVENT(iwlwifi_dev_ucode_cont_event, - TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), - TP_ARGS(dev, time, data, ev), - TP_STRUCT__entry( - DEV_ENTRY - - __field(u32, time) - __field(u32, data) - __field(u32, ev) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->time = time; - __entry->data = data; - __entry->ev = ev; - ), - TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", - __get_str(dev), __entry->time, __entry->data, __entry->ev) -); - -TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, - TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry), - TP_ARGS(dev, wraps, n_entry, p_entry), - TP_STRUCT__entry( - DEV_ENTRY - - __field(u32, wraps) - __field(u32, n_entry) - __field(u32, p_entry) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->wraps = wraps; - __entry->n_entry = n_entry; - __entry->p_entry = p_entry; - ), - TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X", - __get_str(dev), __entry->wraps, __entry->n_entry, - __entry->p_entry) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM iwlwifi_msg - -#define MAX_MSG_LEN 110 - -DECLARE_EVENT_CLASS(iwlwifi_msg_event, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf), - TP_STRUCT__entry( - __dynamic_array(char, msg, MAX_MSG_LEN) - ), - TP_fast_assign( - WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), - MAX_MSG_LEN, vaf->fmt, - *vaf->va) >= MAX_MSG_LEN); - ), - TP_printk("%s", __get_str(msg)) -); - -DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -TRACE_EVENT(iwlwifi_dbg, - TP_PROTO(u32 level, bool in_interrupt, const char *function, - struct va_format *vaf), - TP_ARGS(level, in_interrupt, function, vaf), - TP_STRUCT__entry( - __field(u32, level) - __field(u8, in_interrupt) - __string(function, function) - __dynamic_array(char, msg, MAX_MSG_LEN) - ), - TP_fast_assign( - __entry->level = level; - __entry->in_interrupt = in_interrupt; - __assign_str(function, function); - WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), - MAX_MSG_LEN, vaf->fmt, - *vaf->va) >= MAX_MSG_LEN); - ), - TP_printk("%s", __get_str(msg)) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM iwlwifi_data - -TRACE_EVENT(iwlwifi_dev_tx_data, - TP_PROTO(const struct device *dev, - struct sk_buff *skb, - void *data, size_t data_len), - TP_ARGS(dev, skb, data, data_len), - TP_STRUCT__entry( - DEV_ENTRY - - __dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0) - ), - TP_fast_assign( - DEV_ASSIGN; - if (iwl_trace_data(skb)) - memcpy(__get_dynamic_array(data), data, data_len); - ), - TP_printk("[%s] TX frame data", __get_str(dev)) -); - -TRACE_EVENT(iwlwifi_dev_rx_data, - TP_PROTO(const struct device *dev, - const struct iwl_trans *trans, - void *rxbuf, size_t len), - TP_ARGS(dev, trans, rxbuf, len), - TP_STRUCT__entry( - DEV_ENTRY - - __dynamic_array(u8, data, - len - iwl_rx_trace_len(trans, rxbuf, len)) - ), - TP_fast_assign( - size_t offs = iwl_rx_trace_len(trans, rxbuf, len); - DEV_ASSIGN; - if (offs < len) - memcpy(__get_dynamic_array(data), - ((u8 *)rxbuf) + offs, len - offs); - ), - TP_printk("[%s] RX frame data", __get_str(dev)) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM iwlwifi - -TRACE_EVENT(iwlwifi_dev_hcmd, - TP_PROTO(const struct device *dev, - struct iwl_host_cmd *cmd, u16 total_size, - struct iwl_cmd_header *hdr), - TP_ARGS(dev, cmd, total_size, hdr), - TP_STRUCT__entry( - DEV_ENTRY - __dynamic_array(u8, hcmd, total_size) - __field(u32, flags) - ), - TP_fast_assign( - int i, offset = sizeof(*hdr); - - DEV_ASSIGN; - __entry->flags = cmd->flags; - memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr)); - - for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { - if (!cmd->len[i]) - continue; - memcpy((u8 *)__get_dynamic_array(hcmd) + offset, - cmd->data[i], cmd->len[i]); - offset += cmd->len[i]; - } - ), - TP_printk("[%s] hcmd %#.2x (%ssync)", - __get_str(dev), ((u8 *)__get_dynamic_array(hcmd))[0], - __entry->flags & CMD_ASYNC ? "a" : "") -); - -TRACE_EVENT(iwlwifi_dev_rx, - TP_PROTO(const struct device *dev, const struct iwl_trans *trans, - void *rxbuf, size_t len), - TP_ARGS(dev, trans, rxbuf, len), - TP_STRUCT__entry( - DEV_ENTRY - __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, rxbuf, len)) - ), - TP_fast_assign( - DEV_ASSIGN; - memcpy(__get_dynamic_array(rxbuf), rxbuf, - iwl_rx_trace_len(trans, rxbuf, len)); - ), - TP_printk("[%s] RX cmd %#.2x", - __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) -); - -TRACE_EVENT(iwlwifi_dev_tx, - TP_PROTO(const struct device *dev, struct sk_buff *skb, - void *tfd, size_t tfdlen, - void *buf0, size_t buf0_len, - void *buf1, size_t buf1_len), - TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), - TP_STRUCT__entry( - DEV_ENTRY - - __field(size_t, framelen) - __dynamic_array(u8, tfd, tfdlen) - - /* - * Do not insert between or below these items, - * we want to keep the frame together (except - * for the possible padding). - */ - __dynamic_array(u8, buf0, buf0_len) - __dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->framelen = buf0_len + buf1_len; - memcpy(__get_dynamic_array(tfd), tfd, tfdlen); - memcpy(__get_dynamic_array(buf0), buf0, buf0_len); - if (!iwl_trace_data(skb)) - memcpy(__get_dynamic_array(buf1), buf1, buf1_len); - ), - TP_printk("[%s] TX %.2x (%zu bytes)", - __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], - __entry->framelen) -); - -TRACE_EVENT(iwlwifi_dev_ucode_error, - TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, - u32 data1, u32 data2, u32 line, u32 blink1, - u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, - u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, - u32 brd_ver), - TP_ARGS(dev, desc, tsf_low, data1, data2, line, - blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, - gp3, ucode_ver, hw_ver, brd_ver), - TP_STRUCT__entry( - DEV_ENTRY - __field(u32, desc) - __field(u32, tsf_low) - __field(u32, data1) - __field(u32, data2) - __field(u32, line) - __field(u32, blink1) - __field(u32, blink2) - __field(u32, ilink1) - __field(u32, ilink2) - __field(u32, bcon_time) - __field(u32, gp1) - __field(u32, gp2) - __field(u32, gp3) - __field(u32, ucode_ver) - __field(u32, hw_ver) - __field(u32, brd_ver) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->desc = desc; - __entry->tsf_low = tsf_low; - __entry->data1 = data1; - __entry->data2 = data2; - __entry->line = line; - __entry->blink1 = blink1; - __entry->blink2 = blink2; - __entry->ilink1 = ilink1; - __entry->ilink2 = ilink2; - __entry->bcon_time = bcon_time; - __entry->gp1 = gp1; - __entry->gp2 = gp2; - __entry->gp3 = gp3; - __entry->ucode_ver = ucode_ver; - __entry->hw_ver = hw_ver; - __entry->brd_ver = brd_ver; - ), - TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " - "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " - "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " - "hw 0x%08X brd 0x%08X", - __get_str(dev), __entry->desc, __entry->tsf_low, - __entry->data1, - __entry->data2, __entry->line, __entry->blink1, - __entry->blink2, __entry->ilink1, __entry->ilink2, - __entry->bcon_time, __entry->gp1, __entry->gp2, - __entry->gp3, __entry->ucode_ver, __entry->hw_ver, - __entry->brd_ver) -); - -TRACE_EVENT(iwlwifi_dev_ucode_event, - TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), - TP_ARGS(dev, time, data, ev), - TP_STRUCT__entry( - DEV_ENTRY - - __field(u32, time) - __field(u32, data) - __field(u32, ev) - ), - TP_fast_assign( - DEV_ASSIGN; - __entry->time = time; - __entry->data = data; - __entry->ev = ev; - ), - TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", - __get_str(dev), __entry->time, __entry->data, __entry->ev) -); #endif /* __IWLWIFI_DEVICE_TRACE */ - -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE iwl-devtrace -#include <trace/define_trace.h> diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h index dde3959b7a33..59c05653b2ea 100644 --- a/drivers/usb/host/xhci-trace.h +++ b/drivers/usb/host/xhci-trace.h @@ -14,6 +14,13 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM xhci-hcd +/* + * The TRACE_SYSTEM_VAR defaults to TRACE_SYSTEM, but must be a + * legitimate C variable. It is not exported to user space. + */ +#undef TRACE_SYSTEM_VAR +#define TRACE_SYSTEM_VAR xhci_hcd + #if !defined(__XHCI_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) #define __XHCI_TRACE_H diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index ac78910d7416..f8e8b34dc427 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -124,7 +124,10 @@ #define FTRACE_EVENTS() . = ALIGN(8); \ VMLINUX_SYMBOL(__start_ftrace_events) = .; \ *(_ftrace_events) \ - VMLINUX_SYMBOL(__stop_ftrace_events) = .; + VMLINUX_SYMBOL(__stop_ftrace_events) = .; \ + VMLINUX_SYMBOL(__start_ftrace_enum_maps) = .; \ + *(_ftrace_enum_map) \ + VMLINUX_SYMBOL(__stop_ftrace_enum_maps) = .; #else #define FTRACE_EVENTS() #endif diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index c674ee8f7fca..112cf49d9576 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -202,7 +202,7 @@ enum trace_reg { struct ftrace_event_call; struct ftrace_event_class { - char *system; + const char *system; void *probe; #ifdef CONFIG_PERF_EVENTS void *perf_probe; @@ -285,7 +285,7 @@ struct ftrace_event_call { struct tracepoint *tp; }; struct trace_event event; - const char *print_fmt; + char *print_fmt; struct event_filter *filter; void *mod; void *data; diff --git a/include/linux/module.h b/include/linux/module.h index b03485bcb82a..c883b86ea964 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -338,6 +338,8 @@ struct module { #ifdef CONFIG_EVENT_TRACING struct ftrace_event_call **trace_events; unsigned int num_trace_events; + struct trace_enum_map **trace_enums; + unsigned int num_trace_enums; #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD unsigned int num_ftrace_callsites; diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index c72851328ca9..a5f7f3ecafa3 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -36,6 +36,12 @@ struct tracepoint { struct tracepoint_func __rcu *funcs; }; +struct trace_enum_map { + const char *system; + const char *enum_string; + unsigned long enum_value; +}; + extern int tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data); extern int @@ -87,6 +93,8 @@ extern void syscall_unregfunc(void); #define PARAMS(args...) args +#define TRACE_DEFINE_ENUM(x) + #endif /* _LINUX_TRACEPOINT_H */ /* diff --git a/include/trace/events/9p.h b/include/trace/events/9p.h index a0666362c111..633ee9ee9778 100644 --- a/include/trace/events/9p.h +++ b/include/trace/events/9p.h @@ -6,76 +6,95 @@ #include <linux/tracepoint.h> +#define P9_MSG_T \ + EM( P9_TLERROR, "P9_TLERROR" ) \ + EM( P9_RLERROR, "P9_RLERROR" ) \ + EM( P9_TSTATFS, "P9_TSTATFS" ) \ + EM( P9_RSTATFS, "P9_RSTATFS" ) \ + EM( P9_TLOPEN, "P9_TLOPEN" ) \ + EM( P9_RLOPEN, "P9_RLOPEN" ) \ + EM( P9_TLCREATE, "P9_TLCREATE" ) \ + EM( P9_RLCREATE, "P9_RLCREATE" ) \ + EM( P9_TSYMLINK, "P9_TSYMLINK" ) \ + EM( P9_RSYMLINK, "P9_RSYMLINK" ) \ + EM( P9_TMKNOD, "P9_TMKNOD" ) \ + EM( P9_RMKNOD, "P9_RMKNOD" ) \ + EM( P9_TRENAME, "P9_TRENAME" ) \ + EM( P9_RRENAME, "P9_RRENAME" ) \ + EM( P9_TREADLINK, "P9_TREADLINK" ) \ + EM( P9_RREADLINK, "P9_RREADLINK" ) \ + EM( P9_TGETATTR, "P9_TGETATTR" ) \ + EM( P9_RGETATTR, "P9_RGETATTR" ) \ + EM( P9_TSETATTR, "P9_TSETATTR" ) \ + EM( P9_RSETATTR, "P9_RSETATTR" ) \ + EM( P9_TXATTRWALK, "P9_TXATTRWALK" ) \ + EM( P9_RXATTRWALK, "P9_RXATTRWALK" ) \ + EM( P9_TXATTRCREATE, "P9_TXATTRCREATE" ) \ + EM( P9_RXATTRCREATE, "P9_RXATTRCREATE" ) \ + EM( P9_TREADDIR, "P9_TREADDIR" ) \ + EM( P9_RREADDIR, "P9_RREADDIR" ) \ + EM( P9_TFSYNC, "P9_TFSYNC" ) \ + EM( P9_RFSYNC, "P9_RFSYNC" ) \ + EM( P9_TLOCK, "P9_TLOCK" ) \ + EM( P9_RLOCK, "P9_RLOCK" ) \ + EM( P9_TGETLOCK, "P9_TGETLOCK" ) \ + EM( P9_RGETLOCK, "P9_RGETLOCK" ) \ + EM( P9_TLINK, "P9_TLINK" ) \ + EM( P9_RLINK, "P9_RLINK" ) \ + EM( P9_TMKDIR, "P9_TMKDIR" ) \ + EM( P9_RMKDIR, "P9_RMKDIR" ) \ + EM( P9_TRENAMEAT, "P9_TRENAMEAT" ) \ + EM( P9_RRENAMEAT, "P9_RRENAMEAT" ) \ + EM( P9_TUNLINKAT, "P9_TUNLINKAT" ) \ + EM( P9_RUNLINKAT, "P9_RUNLINKAT" ) \ + EM( P9_TVERSION, "P9_TVERSION" ) \ + EM( P9_RVERSION, "P9_RVERSION" ) \ + EM( P9_TAUTH, "P9_TAUTH" ) \ + EM( P9_RAUTH, "P9_RAUTH" ) \ + EM( P9_TATTACH, "P9_TATTACH" ) \ + EM( P9_RATTACH, "P9_RATTACH" ) \ + EM( P9_TERROR, "P9_TERROR" ) \ + EM( P9_RERROR, "P9_RERROR" ) \ + EM( P9_TFLUSH, "P9_TFLUSH" ) \ + EM( P9_RFLUSH, "P9_RFLUSH" ) \ + EM( P9_TWALK, "P9_TWALK" ) \ + EM( P9_RWALK, "P9_RWALK" ) \ + EM( P9_TOPEN, "P9_TOPEN" ) \ + EM( P9_ROPEN, "P9_ROPEN" ) \ + EM( P9_TCREATE, "P9_TCREATE" ) \ + EM( P9_RCREATE, "P9_RCREATE" ) \ + EM( P9_TREAD, "P9_TREAD" ) \ + EM( P9_RREAD, "P9_RREAD" ) \ + EM( P9_TWRITE, "P9_TWRITE" ) \ + EM( P9_RWRITE, "P9_RWRITE" ) \ + EM( P9_TCLUNK, "P9_TCLUNK" ) \ + EM( P9_RCLUNK, "P9_RCLUNK" ) \ + EM( P9_TREMOVE, "P9_TREMOVE" ) \ + EM( P9_RREMOVE, "P9_RREMOVE" ) \ + EM( P9_TSTAT, "P9_TSTAT" ) \ + EM( P9_RSTAT, "P9_RSTAT" ) \ + EM( P9_TWSTAT, "P9_TWSTAT" ) \ + EMe(P9_RWSTAT, "P9_RWSTAT" ) + +/* Define EM() to export the enums to userspace via TRACE_DEFINE_ENUM() */ +#undef EM +#undef EMe +#define EM(a, b) TRACE_DEFINE_ENUM(a); +#define EMe(a, b) TRACE_DEFINE_ENUM(a); + +P9_MSG_T + +/* + * Now redefine the EM() and EMe() macros to map the enums to the strings + * that will be printed in the output. + */ +#undef EM +#undef EMe +#define EM(a, b) { a, b }, +#define EMe(a, b) { a, b } + #define show_9p_op(type) \ - __print_symbolic(type, \ - { P9_TLERROR, "P9_TLERROR" }, \ - { P9_RLERROR, "P9_RLERROR" }, \ - { P9_TSTATFS, "P9_TSTATFS" }, \ - { P9_RSTATFS, "P9_RSTATFS" }, \ - { P9_TLOPEN, "P9_TLOPEN" }, \ - { P9_RLOPEN, "P9_RLOPEN" }, \ - { P9_TLCREATE, "P9_TLCREATE" }, \ - { P9_RLCREATE, "P9_RLCREATE" }, \ - { P9_TSYMLINK, "P9_TSYMLINK" }, \ - { P9_RSYMLINK, "P9_RSYMLINK" }, \ - { P9_TMKNOD, "P9_TMKNOD" }, \ - { P9_RMKNOD, "P9_RMKNOD" }, \ - { P9_TRENAME, "P9_TRENAME" }, \ - { P9_RRENAME, "P9_RRENAME" }, \ - { P9_TREADLINK, "P9_TREADLINK" }, \ - { P9_RREADLINK, "P9_RREADLINK" }, \ - { P9_TGETATTR, "P9_TGETATTR" }, \ - { P9_RGETATTR, "P9_RGETATTR" }, \ - { P9_TSETATTR, "P9_TSETATTR" }, \ - { P9_RSETATTR, "P9_RSETATTR" }, \ - { P9_TXATTRWALK, "P9_TXATTRWALK" }, \ - { P9_RXATTRWALK, "P9_RXATTRWALK" }, \ - { P9_TXATTRCREATE, "P9_TXATTRCREATE" }, \ - { P9_RXATTRCREATE, "P9_RXATTRCREATE" }, \ - { P9_TREADDIR, "P9_TREADDIR" }, \ - { P9_RREADDIR, "P9_RREADDIR" }, \ - { P9_TFSYNC, "P9_TFSYNC" }, \ - { P9_RFSYNC, "P9_RFSYNC" }, \ - { P9_TLOCK, "P9_TLOCK" }, \ - { P9_RLOCK, "P9_RLOCK" }, \ - { P9_TGETLOCK, "P9_TGETLOCK" }, \ - { P9_RGETLOCK, "P9_RGETLOCK" }, \ - { P9_TLINK, "P9_TLINK" }, \ - { P9_RLINK, "P9_RLINK" }, \ - { P9_TMKDIR, "P9_TMKDIR" }, \ - { P9_RMKDIR, "P9_RMKDIR" }, \ - { P9_TRENAMEAT, "P9_TRENAMEAT" }, \ - { P9_RRENAMEAT, "P9_RRENAMEAT" }, \ - { P9_TUNLINKAT, "P9_TUNLINKAT" }, \ - { P9_RUNLINKAT, "P9_RUNLINKAT" }, \ - { P9_TVERSION, "P9_TVERSION" }, \ - { P9_RVERSION, "P9_RVERSION" }, \ - { P9_TAUTH, "P9_TAUTH" }, \ - { P9_RAUTH, "P9_RAUTH" }, \ - { P9_TATTACH, "P9_TATTACH" }, \ - { P9_RATTACH, "P9_RATTACH" }, \ - { P9_TERROR, "P9_TERROR" }, \ - { P9_RERROR, "P9_RERROR" }, \ - { P9_TFLUSH, "P9_TFLUSH" }, \ - { P9_RFLUSH, "P9_RFLUSH" }, \ - { P9_TWALK, "P9_TWALK" }, \ - { P9_RWALK, "P9_RWALK" }, \ - { P9_TOPEN, "P9_TOPEN" }, \ - { P9_ROPEN, "P9_ROPEN" }, \ - { P9_TCREATE, "P9_TCREATE" }, \ - { P9_RCREATE, "P9_RCREATE" }, \ - { P9_TREAD, "P9_TREAD" }, \ - { P9_RREAD, "P9_RREAD" }, \ - { P9_TWRITE, "P9_TWRITE" }, \ - { P9_RWRITE, "P9_RWRITE" }, \ - { P9_TCLUNK, "P9_TCLUNK" }, \ - { P9_RCLUNK, "P9_RCLUNK" }, \ - { P9_TREMOVE, "P9_TREMOVE" }, \ - { P9_RREMOVE, "P9_RREMOVE" }, \ - { P9_TSTAT, "P9_TSTAT" }, \ - { P9_RSTAT, "P9_RSTAT" }, \ - { P9_TWSTAT, "P9_TWSTAT" }, \ - { P9_RWSTAT, "P9_RWSTAT" }) + __print_symbolic(type, P9_MSG_T) TRACE_EVENT(9p_client_req, TP_PROTO(struct p9_client *clnt, int8_t type, int tag), diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index 1faecea101f3..572e6503394a 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -962,7 +962,7 @@ TRACE_EVENT(alloc_extent_state, __entry->ip = IP ), - TP_printk("state=%p; mask = %s; caller = %pF", __entry->state, + TP_printk("state=%p; mask = %s; caller = %pS", __entry->state, show_gfp_flags(__entry->mask), (void *)__entry->ip) ); @@ -982,7 +982,7 @@ TRACE_EVENT(free_extent_state, __entry->ip = IP ), - TP_printk(" state=%p; caller = %pF", __entry->state, + TP_printk(" state=%p; caller = %pS", __entry->state, (void *)__entry->ip) ); diff --git a/include/trace/events/ext3.h b/include/trace/events/ext3.h index 6797b9de90ed..7f20707849bb 100644 --- a/include/trace/events/ext3.h +++ b/include/trace/events/ext3.h @@ -144,7 +144,7 @@ TRACE_EVENT(ext3_mark_inode_dirty, __entry->ip = IP; ), - TP_printk("dev %d,%d ino %lu caller %pF", + TP_printk("dev %d,%d ino %lu caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, (void *)__entry->ip) ); diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index 6e5abd6d38a2..47fca36ee426 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -240,7 +240,7 @@ TRACE_EVENT(ext4_mark_inode_dirty, __entry->ip = IP; ), - TP_printk("dev %d,%d ino %lu caller %pF", + TP_printk("dev %d,%d ino %lu caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, (void *)__entry->ip) ); @@ -1762,7 +1762,7 @@ TRACE_EVENT(ext4_journal_start, __entry->rsv_blocks = rsv_blocks; ), - TP_printk("dev %d,%d blocks, %d rsv_blocks, %d caller %pF", + TP_printk("dev %d,%d blocks, %d rsv_blocks, %d caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->blocks, __entry->rsv_blocks, (void *)__entry->ip) ); @@ -1784,7 +1784,7 @@ TRACE_EVENT(ext4_journal_start_reserved, __entry->blocks = blocks; ), - TP_printk("dev %d,%d blocks, %d caller %pF", + TP_printk("dev %d,%d blocks, %d caller %pS", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->blocks, (void *)__entry->ip) ); diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 5422dbfaf97d..36f4536b6149 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -9,6 +9,36 @@ #define show_dev(entry) MAJOR(entry->dev), MINOR(entry->dev) #define show_dev_ino(entry) show_dev(entry), (unsigned long)entry->ino +TRACE_DEFINE_ENUM(NODE); +TRACE_DEFINE_ENUM(DATA); +TRACE_DEFINE_ENUM(META); +TRACE_DEFINE_ENUM(META_FLUSH); +TRACE_DEFINE_ENUM(CURSEG_HOT_DATA); +TRACE_DEFINE_ENUM(CURSEG_WARM_DATA); +TRACE_DEFINE_ENUM(CURSEG_COLD_DATA); +TRACE_DEFINE_ENUM(CURSEG_HOT_NODE); +TRACE_DEFINE_ENUM(CURSEG_WARM_NODE); +TRACE_DEFINE_ENUM(CURSEG_COLD_NODE); +TRACE_DEFINE_ENUM(NO_CHECK_TYPE); +TRACE_DEFINE_ENUM(GC_GREEDY); +TRACE_DEFINE_ENUM(GC_CB); +TRACE_DEFINE_ENUM(FG_GC); +TRACE_DEFINE_ENUM(BG_GC); +TRACE_DEFINE_ENUM(LFS); +TRACE_DEFINE_ENUM(SSR); +TRACE_DEFINE_ENUM(__REQ_RAHEAD); +TRACE_DEFINE_ENUM(__REQ_WRITE); +TRACE_DEFINE_ENUM(__REQ_SYNC); +TRACE_DEFINE_ENUM(__REQ_NOIDLE); +TRACE_DEFINE_ENUM(__REQ_FLUSH); +TRACE_DEFINE_ENUM(__REQ_FUA); +TRACE_DEFINE_ENUM(__REQ_PRIO); +TRACE_DEFINE_ENUM(__REQ_META); +TRACE_DEFINE_ENUM(CP_UMOUNT); +TRACE_DEFINE_ENUM(CP_FASTBOOT); +TRACE_DEFINE_ENUM(CP_SYNC); +TRACE_DEFINE_ENUM(CP_DISCARD); + #define show_block_type(type) \ __print_symbolic(type, \ { NODE, "NODE" }, \ diff --git a/include/trace/events/intel-sst.h b/include/trace/events/intel-sst.h index 76c72d3f1902..edc24e6dea1b 100644 --- a/include/trace/events/intel-sst.h +++ b/include/trace/events/intel-sst.h @@ -1,6 +1,13 @@ #undef TRACE_SYSTEM #define TRACE_SYSTEM intel-sst +/* + * The TRACE_SYSTEM_VAR defaults to TRACE_SYSTEM, but must be a + * legitimate C variable. It is not exported to user space. + */ +#undef TRACE_SYSTEM_VAR +#define TRACE_SYSTEM_VAR intel_sst + #if !defined(_TRACE_INTEL_SST_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_INTEL_SST_H diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index 3608bebd3d9c..ff8f6c091a15 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h @@ -9,19 +9,34 @@ struct irqaction; struct softirq_action; -#define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq } +#define SOFTIRQ_NAME_LIST \ + softirq_name(HI) \ + softirq_name(TIMER) \ + softirq_name(NET_TX) \ + softirq_name(NET_RX) \ + softirq_name(BLOCK) \ + softirq_name(BLOCK_IOPOLL) \ + softirq_name(TASKLET) \ + softirq_name(SCHED) \ + softirq_name(HRTIMER) \ + softirq_name_end(RCU) + +#undef softirq_name +#undef softirq_name_end + +#define softirq_name(sirq) TRACE_DEFINE_ENUM(sirq##_SOFTIRQ); +#define softirq_name_end(sirq) TRACE_DEFINE_ENUM(sirq##_SOFTIRQ); + +SOFTIRQ_NAME_LIST + +#undef softirq_name +#undef softirq_name_end + +#define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }, +#define softirq_name_end(sirq) { sirq##_SOFTIRQ, #sirq } + #define show_softirq_name(val) \ - __print_symbolic(val, \ - softirq_name(HI), \ - softirq_name(TIMER), \ - softirq_name(NET_TX), \ - softirq_name(NET_RX), \ - softirq_name(BLOCK), \ - softirq_name(BLOCK_IOPOLL), \ - softirq_name(TASKLET), \ - softirq_name(SCHED), \ - softirq_name(HRTIMER), \ - softirq_name(RCU)) + __print_symbolic(val, SOFTIRQ_NAME_LIST) /** * irq_handler_entry - called immediately before the irq action handler diff --git a/include/trace/events/migrate.h b/include/trace/events/migrate.h index dd2b5467d905..539b25a76111 100644 --- a/include/trace/events/migrate.h +++ b/include/trace/events/migrate.h @@ -7,18 +7,40 @@ #include <linux/tracepoint.h> #define MIGRATE_MODE \ - {MIGRATE_ASYNC, "MIGRATE_ASYNC"}, \ - {MIGRATE_SYNC_LIGHT, "MIGRATE_SYNC_LIGHT"}, \ - {MIGRATE_SYNC, "MIGRATE_SYNC"} + EM( MIGRATE_ASYNC, "MIGRATE_ASYNC") \ + EM( MIGRATE_SYNC_LIGHT, "MIGRATE_SYNC_LIGHT") \ + EMe(MIGRATE_SYNC, "MIGRATE_SYNC") + #define MIGRATE_REASON \ - {MR_COMPACTION, "compaction"}, \ - {MR_MEMORY_FAILURE, "memory_failure"}, \ - {MR_MEMORY_HOTPLUG, "memory_hotplug"}, \ - {MR_SYSCALL, "syscall_or_cpuset"}, \ - {MR_MEMPOLICY_MBIND, "mempolicy_mbind"}, \ - {MR_NUMA_MISPLACED, "numa_misplaced"}, \ - {MR_CMA, "cma"} + EM( MR_COMPACTION, "compaction") \ + EM( MR_MEMORY_FAILURE, "memory_failure") \ + EM( MR_MEMORY_HOTPLUG, "memory_hotplug") \ + EM( MR_SYSCALL, "syscall_or_cpuset") \ + EM( MR_MEMPOLICY_MBIND, "mempolicy_mbind") \ + EM( MR_NUMA_MISPLACED, "numa_misplaced") \ + EMe(MR_CMA, "cma") + +/* + * First define the enums in the above macros to be exported to userspace + * via TRACE_DEFINE_ENUM(). + */ +#undef EM +#undef EMe +#define EM(a, b) TRACE_DEFINE_ENUM(a); +#define EMe(a, b) TRACE_DEFINE_ENUM(a); + +MIGRATE_MODE +MIGRATE_REASON + +/* + * Now redefine the EM() and EMe() macros to map the enums to the strings + * that will be printed in the output. + */ +#undef EM +#undef EMe +#define EM(a, b) {a, b}, +#define EMe(a, b) {a, b} TRACE_EVENT(mm_migrate_pages, diff --git a/include/trace/events/module.h b/include/trace/events/module.h index 81c4c183d348..28c45997e451 100644 --- a/include/trace/events/module.h +++ b/include/trace/events/module.h @@ -84,7 +84,7 @@ DECLARE_EVENT_CLASS(module_refcnt, __assign_str(name, mod->name); ), - TP_printk("%s call_site=%pf refcnt=%d", + TP_printk("%s call_site=%ps refcnt=%d", __get_str(name), (void *)__entry->ip, __entry->refcnt) ); @@ -121,7 +121,7 @@ TRACE_EVENT(module_request, __assign_str(name, name); ), - TP_printk("%s wait=%d call_site=%pf", + TP_printk("%s wait=%d call_site=%ps", __get_str(name), (int)__entry->wait, (void *)__entry->ip) ); diff --git a/include/trace/events/random.h b/include/trace/events/random.h index 805af6db41cc..4684de344c5d 100644 --- a/include/trace/events/random.h +++ b/include/trace/events/random.h @@ -22,7 +22,7 @@ TRACE_EVENT(add_device_randomness, __entry->IP = IP; ), - TP_printk("bytes %d caller %pF", + TP_printk("bytes %d caller %pS", __entry->bytes, (void *)__entry->IP) ); @@ -43,7 +43,7 @@ DECLARE_EVENT_CLASS(random__mix_pool_bytes, __entry->IP = IP; ), - TP_printk("%s pool: bytes %d caller %pF", + TP_printk("%s pool: bytes %d caller %pS", __entry->pool_name, __entry->bytes, (void *)__entry->IP) ); @@ -82,7 +82,7 @@ TRACE_EVENT(credit_entropy_bits, ), TP_printk("%s pool: bits %d entropy_count %d entropy_total %d " - "caller %pF", __entry->pool_name, __entry->bits, + "caller %pS", __entry->pool_name, __entry->bits, __entry->entropy_count, __entry->entropy_total, (void *)__entry->IP) ); @@ -207,7 +207,7 @@ DECLARE_EVENT_CLASS(random__get_random_bytes, __entry->IP = IP; ), - TP_printk("nbytes %d caller %pF", __entry->nbytes, (void *)__entry->IP) + TP_printk("nbytes %d caller %pS", __entry->nbytes, (void *)__entry->IP) ); DEFINE_EVENT(random__get_random_bytes, get_random_bytes, @@ -242,7 +242,7 @@ DECLARE_EVENT_CLASS(random__extract_entropy, __entry->IP = IP; ), - TP_printk("%s pool: nbytes %d entropy_count %d caller %pF", + TP_printk("%s pool: nbytes %d entropy_count %d caller %pS", __entry->pool_name, __entry->nbytes, __entry->entropy_count, (void *)__entry->IP) ); diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index b9c1dc6c825a..fd1a02cb3c82 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -179,27 +179,53 @@ DEFINE_EVENT(rpc_task_queued, rpc_task_wakeup, ); +/* + * First define the enums in the below macros to be exported to userspace + * via TRACE_DEFINE_ENUM(). + */ +#undef EM +#undef EMe +#define EM(a, b) TRACE_DEFINE_ENUM(a); +#define EMe(a, b) TRACE_DEFINE_ENUM(a); + +#define RPC_SHOW_SOCKET \ + EM( SS_FREE, "FREE" ) \ + EM( SS_UNCONNECTED, "UNCONNECTED" ) \ + EM( SS_CONNECTING, "CONNECTING," ) \ + EM( SS_CONNECTED, "CONNECTED," ) \ + EMe(SS_DISCONNECTING, "DISCONNECTING" ) + #define rpc_show_socket_state(state) \ - __print_symbolic(state, \ - { SS_FREE, "FREE" }, \ - { SS_UNCONNECTED, "UNCONNECTED" }, \ - { SS_CONNECTING, "CONNECTING," }, \ - { SS_CONNECTED, "CONNECTED," }, \ - { SS_DISCONNECTING, "DISCONNECTING" }) + __print_symbolic(state, RPC_SHOW_SOCKET) + +RPC_SHOW_SOCKET + +#define RPC_SHOW_SOCK \ + EM( TCP_ESTABLISHED, "ESTABLISHED" ) \ + EM( TCP_SYN_SENT, "SYN_SENT" ) \ + EM( TCP_SYN_RECV, "SYN_RECV" ) \ + EM( TCP_FIN_WAIT1, "FIN_WAIT1" ) \ + EM( TCP_FIN_WAIT2, "FIN_WAIT2" ) \ + EM( TCP_TIME_WAIT, "TIME_WAIT" ) \ + EM( TCP_CLOSE, "CLOSE" ) \ + EM( TCP_CLOSE_WAIT, "CLOSE_WAIT" ) \ + EM( TCP_LAST_ACK, "LAST_ACK" ) \ + EM( TCP_LISTEN, "LISTEN" ) \ + EMe( TCP_CLOSING, "CLOSING" ) #define rpc_show_sock_state(state) \ - __print_symbolic(state, \ - { TCP_ESTABLISHED, "ESTABLISHED" }, \ - { TCP_SYN_SENT, "SYN_SENT" }, \ - { TCP_SYN_RECV, "SYN_RECV" }, \ - { TCP_FIN_WAIT1, "FIN_WAIT1" }, \ - { TCP_FIN_WAIT2, "FIN_WAIT2" }, \ - { TCP_TIME_WAIT, "TIME_WAIT" }, \ - { TCP_CLOSE, "CLOSE" }, \ - { TCP_CLOSE_WAIT, "CLOSE_WAIT" }, \ - { TCP_LAST_ACK, "LAST_ACK" }, \ - { TCP_LISTEN, "LISTEN" }, \ - { TCP_CLOSING, "CLOSING" }) + __print_symbolic(state, RPC_SHOW_SOCK) + +RPC_SHOW_SOCK + +/* + * Now redefine the EM() and EMe() macros to map the enums to the strings + * that will be printed in the output. + */ +#undef EM +#undef EMe +#define EM(a, b) {a, b}, +#define EMe(a, b) {a, b} DECLARE_EVENT_CLASS(xs_socket_event, diff --git a/include/trace/events/tlb.h b/include/trace/events/tlb.h index 0e7635765153..4250f364a6ca 100644 --- a/include/trace/events/tlb.h +++ b/include/trace/events/tlb.h @@ -7,11 +7,31 @@ #include <linux/mm_types.h> #include <linux/tracepoint.h> -#define TLB_FLUSH_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" } +#define TLB_FLUSH_REASON \ + EM( TLB_FLUSH_ON_TASK_SWITCH, "flush on task switch" ) \ + EM( TLB_REMOTE_SHOOTDOWN, "remote shootdown" ) \ + EM( TLB_LOCAL_SHOOTDOWN, "local shootdown" ) \ + EMe( TLB_LOCAL_MM_SHOOTDOWN, "local mm shootdown" ) + +/* + * First define the enums in TLB_FLUSH_REASON to be exported to userspace + * via TRACE_DEFINE_ENUM(). + */ +#undef EM +#undef EMe +#define EM(a,b) TRACE_DEFINE_ENUM(a); +#define EMe(a,b) TRACE_DEFINE_ENUM(a); + +TLB_FLUSH_REASON + +/* + * Now redefine the EM() and EMe() macros to map the enums to the strings + * that will be printed in the output. + */ +#undef EM +#undef EMe +#define EM(a,b) { a, b }, +#define EMe(a,b) { a, b } TRACE_EVENT_CONDITION(tlb_flush, diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h index b9bb1f204693..20112170ff11 100644 --- a/include/trace/events/v4l2.h +++ b/include/trace/events/v4l2.h @@ -6,33 +6,58 @@ #include <linux/tracepoint.h> -#define show_type(type) \ - __print_symbolic(type, \ - { V4L2_BUF_TYPE_VIDEO_CAPTURE, "VIDEO_CAPTURE" }, \ - { V4L2_BUF_TYPE_VIDEO_OUTPUT, "VIDEO_OUTPUT" }, \ - { V4L2_BUF_TYPE_VIDEO_OVERLAY, "VIDEO_OVERLAY" }, \ - { V4L2_BUF_TYPE_VBI_CAPTURE, "VBI_CAPTURE" }, \ - { V4L2_BUF_TYPE_VBI_OUTPUT, "VBI_OUTPUT" }, \ - { V4L2_BUF_TYPE_SLICED_VBI_CAPTURE, "SLICED_VBI_CAPTURE" }, \ - { V4L2_BUF_TYPE_SLICED_VBI_OUTPUT, "SLICED_VBI_OUTPUT" }, \ - { V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, "VIDEO_OUTPUT_OVERLAY" },\ - { V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, "VIDEO_CAPTURE_MPLANE" },\ - { V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, "VIDEO_OUTPUT_MPLANE" }, \ - { V4L2_BUF_TYPE_SDR_CAPTURE, "SDR_CAPTURE" }, \ - { V4L2_BUF_TYPE_PRIVATE, "PRIVATE" }) +/* Enums require being exported to userspace, for user tool parsing */ +#undef EM +#undef EMe +#define EM(a, b) TRACE_DEFINE_ENUM(a); +#define EMe(a, b) TRACE_DEFINE_ENUM(a); + +#define show_type(type) \ + __print_symbolic(type, SHOW_TYPE) + +#define SHOW_TYPE \ + EM( V4L2_BUF_TYPE_VIDEO_CAPTURE, "VIDEO_CAPTURE" ) \ + EM( V4L2_BUF_TYPE_VIDEO_OUTPUT, "VIDEO_OUTPUT" ) \ + EM( V4L2_BUF_TYPE_VIDEO_OVERLAY, "VIDEO_OVERLAY" ) \ + EM( V4L2_BUF_TYPE_VBI_CAPTURE, "VBI_CAPTURE" ) \ + EM( V4L2_BUF_TYPE_VBI_OUTPUT, "VBI_OUTPUT" ) \ + EM( V4L2_BUF_TYPE_SLICED_VBI_CAPTURE, "SLICED_VBI_CAPTURE" ) \ + EM( V4L2_BUF_TYPE_SLICED_VBI_OUTPUT, "SLICED_VBI_OUTPUT" ) \ + EM( V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, "VIDEO_OUTPUT_OVERLAY" ) \ + EM( V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, "VIDEO_CAPTURE_MPLANE" ) \ + EM( V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, "VIDEO_OUTPUT_MPLANE" ) \ + EM( V4L2_BUF_TYPE_SDR_CAPTURE, "SDR_CAPTURE" ) \ + EMe(V4L2_BUF_TYPE_PRIVATE, "PRIVATE" ) + +SHOW_TYPE #define show_field(field) \ - __print_symbolic(field, \ - { V4L2_FIELD_ANY, "ANY" }, \ - { V4L2_FIELD_NONE, "NONE" }, \ - { V4L2_FIELD_TOP, "TOP" }, \ - { V4L2_FIELD_BOTTOM, "BOTTOM" }, \ - { V4L2_FIELD_INTERLACED, "INTERLACED" }, \ - { V4L2_FIELD_SEQ_TB, "SEQ_TB" }, \ - { V4L2_FIELD_SEQ_BT, "SEQ_BT" }, \ - { V4L2_FIELD_ALTERNATE, "ALTERNATE" }, \ - { V4L2_FIELD_INTERLACED_TB, "INTERLACED_TB" }, \ - { V4L2_FIELD_INTERLACED_BT, "INTERLACED_BT" }) + __print_symbolic(field, SHOW_FIELD) + +#define SHOW_FIELD \ + EM( V4L2_FIELD_ANY, "ANY" ) \ + EM( V4L2_FIELD_NONE, "NONE" ) \ + EM( V4L2_FIELD_TOP, "TOP" ) \ + EM( V4L2_FIELD_BOTTOM, "BOTTOM" ) \ + EM( V4L2_FIELD_INTERLACED, "INTERLACED" ) \ + EM( V4L2_FIELD_SEQ_TB, "SEQ_TB" ) \ + EM( V4L2_FIELD_SEQ_BT, "SEQ_BT" ) \ + EM( V4L2_FIELD_ALTERNATE, "ALTERNATE" ) \ + EM( V4L2_FIELD_INTERLACED_TB, "INTERLACED_TB" ) \ + EMe( V4L2_FIELD_INTERLACED_BT, "INTERLACED_BT" ) + +SHOW_FIELD + +/* + * Now redefine the EM() and EMe() macros to map the enums to the strings + * that will be printed in the output. + */ +#undef EM +#undef EMe +#define EM(a, b) {a, b}, +#define EMe(a, b) {a, b} + +/* V4L2_TC_TYPE_* are macros, not defines, they do not need processing */ #define show_timecode_type(type) \ __print_symbolic(type, \ diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index 5a14ead59696..880dd7437172 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h @@ -23,15 +23,32 @@ {I_REFERENCED, "I_REFERENCED"} \ ) +/* enums need to be exported to user space */ +#undef EM +#undef EMe +#define EM(a,b) TRACE_DEFINE_ENUM(a); +#define EMe(a,b) TRACE_DEFINE_ENUM(a); + #define WB_WORK_REASON \ - {WB_REASON_BACKGROUND, "background"}, \ - {WB_REASON_TRY_TO_FREE_PAGES, "try_to_free_pages"}, \ - {WB_REASON_SYNC, "sync"}, \ - {WB_REASON_PERIODIC, "periodic"}, \ - {WB_REASON_LAPTOP_TIMER, "laptop_timer"}, \ - {WB_REASON_FREE_MORE_MEM, "free_more_memory"}, \ - {WB_REASON_FS_FREE_SPACE, "fs_free_space"}, \ - {WB_REASON_FORKER_THREAD, "forker_thread"} + EM( WB_REASON_BACKGROUND, "background") \ + EM( WB_REASON_TRY_TO_FREE_PAGES, "try_to_free_pages") \ + EM( WB_REASON_SYNC, "sync") \ + EM( WB_REASON_PERIODIC, "periodic") \ + EM( WB_REASON_LAPTOP_TIMER, "laptop_timer") \ + EM( WB_REASON_FREE_MORE_MEM, "free_more_memory") \ + EM( WB_REASON_FS_FREE_SPACE, "fs_free_space") \ + EMe(WB_REASON_FORKER_THREAD, "forker_thread") + +WB_WORK_REASON + +/* + * Now redefine the EM() and EMe() macros to map the enums to the strings + * that will be printed in the output. + */ +#undef EM +#undef EMe +#define EM(a,b) { a, b }, +#define EMe(a,b) { a, b } struct wb_writeback_work; diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 41bf65f04dd9..37d4b10b111d 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -18,6 +18,34 @@ #include <linux/ftrace_event.h> +#ifndef TRACE_SYSTEM_VAR +#define TRACE_SYSTEM_VAR TRACE_SYSTEM +#endif + +#define __app__(x, y) str__##x##y +#define __app(x, y) __app__(x, y) + +#define TRACE_SYSTEM_STRING __app(TRACE_SYSTEM_VAR,__trace_system_name) + +#define TRACE_MAKE_SYSTEM_STR() \ + static const char TRACE_SYSTEM_STRING[] = \ + __stringify(TRACE_SYSTEM) + +TRACE_MAKE_SYSTEM_STR(); + +#undef TRACE_DEFINE_ENUM +#define TRACE_DEFINE_ENUM(a) \ + static struct trace_enum_map __used __initdata \ + __##TRACE_SYSTEM##_##a = \ + { \ + .system = TRACE_SYSTEM_STRING, \ + .enum_string = #a, \ + .enum_value = a \ + }; \ + static struct trace_enum_map __used \ + __attribute__((section("_ftrace_enum_map"))) \ + *TRACE_SYSTEM##_##a = &__##TRACE_SYSTEM##_##a + /* * DECLARE_EVENT_CLASS can be used to add a generic function * handlers for events. That is, if all events have the same @@ -105,7 +133,6 @@ #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) - /* * Stage 2 of the trace events. * @@ -122,6 +149,9 @@ * The size of an array is also encoded, in the higher 16 bits of <item>. */ +#undef TRACE_DEFINE_ENUM +#define TRACE_DEFINE_ENUM(a) + #undef __field #define __field(type, item) @@ -539,7 +569,7 @@ static inline notrace int ftrace_get_offsets_##call( \ * .trace = ftrace_raw_output_<call>, <-- stage 2 * }; * - * static const char print_fmt_<call>[] = <TP_printk>; + * static char print_fmt_<call>[] = <TP_printk>; * * static struct ftrace_event_class __used event_class_<template> = { * .system = "<system>", @@ -690,9 +720,9 @@ static inline void ftrace_test_probe_##call(void) \ #undef DECLARE_EVENT_CLASS #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ _TRACE_PERF_PROTO(call, PARAMS(proto)); \ -static const char print_fmt_##call[] = print; \ +static char print_fmt_##call[] = print; \ static struct ftrace_event_class __used __refdata event_class_##call = { \ - .system = __stringify(TRACE_SYSTEM), \ + .system = TRACE_SYSTEM_STRING, \ .define_fields = ftrace_define_fields_##call, \ .fields = LIST_HEAD_INIT(event_class_##call.fields),\ .raw_init = trace_event_raw_init, \ @@ -719,7 +749,7 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call #undef DEFINE_EVENT_PRINT #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ \ -static const char print_fmt_##call[] = print; \ +static char print_fmt_##call[] = print; \ \ static struct ftrace_event_call __used event_##call = { \ .class = &event_class_##template, \ @@ -735,6 +765,7 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) +#undef TRACE_SYSTEM_VAR #ifdef CONFIG_PERF_EVENTS diff --git a/kernel/module.c b/kernel/module.c index ec53f594e9c9..650b038ae520 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2770,6 +2770,9 @@ static int find_module_sections(struct module *mod, struct load_info *info) mod->trace_events = section_objs(info, "_ftrace_events", sizeof(*mod->trace_events), &mod->num_trace_events); + mod->trace_enums = section_objs(info, "_ftrace_enum_map", + sizeof(*mod->trace_enums), + &mod->num_trace_enums); #endif #ifdef CONFIG_TRACING mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt", diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index a5da09c899dd..fedbdd7d5d1e 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -599,6 +599,34 @@ config RING_BUFFER_STARTUP_TEST If unsure, say N +config TRACE_ENUM_MAP_FILE + bool "Show enum mappings for trace events" + depends on TRACING + help + The "print fmt" of the trace events will show the enum names instead + of their values. This can cause problems for user space tools that + use this string to parse the raw data as user space does not know + how to convert the string to its value. + + To fix this, there's a special macro in the kernel that can be used + to convert the enum into its value. If this macro is used, then the + print fmt strings will have the enums converted to their values. + + If something does not get converted properly, this option can be + used to show what enums the kernel tried to convert. + + This option is for debugging the enum conversions. A file is created + in the tracing directory called "enum_map" that will show the enum + names matched with their values and what trace event system they + belong too. + + Normally, the mapping of the strings to values will be freed after + boot up or module load. With this option, they will not be freed, as + they are needed for the "enum_map" file. Enabling this option will + increase the memory footprint of the running kernel. + + If unsure, say N + endif # FTRACE endif # TRACING_SUPPORT diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 5a2e0b53af30..02bece4a99ea 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -249,6 +249,19 @@ static void update_function_graph_func(void); static inline void update_function_graph_func(void) { } #endif + +static ftrace_func_t ftrace_ops_get_list_func(struct ftrace_ops *ops) +{ + /* + * If this is a dynamic ops or we force list func, + * then it needs to call the list anyway. + */ + if (ops->flags & FTRACE_OPS_FL_DYNAMIC || FTRACE_FORCE_LIST_FUNC) + return ftrace_ops_list_func; + + return ftrace_ops_get_func(ops); +} + static void update_ftrace_function(void) { ftrace_func_t func; @@ -270,7 +283,7 @@ static void update_ftrace_function(void) * then have the mcount trampoline call the function directly. */ } else if (ftrace_ops_list->next == &ftrace_list_end) { - func = ftrace_ops_get_func(ftrace_ops_list); + func = ftrace_ops_get_list_func(ftrace_ops_list); } else { /* Just use the default ftrace_ops */ @@ -5209,13 +5222,6 @@ static void ftrace_ops_recurs_func(unsigned long ip, unsigned long parent_ip, ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops) { /* - * If this is a dynamic ops or we force list func, - * then it needs to call the list anyway. - */ - if (ops->flags & FTRACE_OPS_FL_DYNAMIC || FTRACE_FORCE_LIST_FUNC) - return ftrace_ops_list_func; - - /* * If the func handles its own recursion, call it directly. * Otherwise call the recursion protected function that * will call the ftrace ops function. diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 5040d44fe5a3..0315d43176d8 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2679,7 +2679,7 @@ static DEFINE_PER_CPU(unsigned int, current_context); static __always_inline int trace_recursive_lock(void) { - unsigned int val = this_cpu_read(current_context); + unsigned int val = __this_cpu_read(current_context); int bit; if (in_interrupt()) { @@ -2696,18 +2696,14 @@ static __always_inline int trace_recursive_lock(void) return 1; val |= (1 << bit); - this_cpu_write(current_context, val); + __this_cpu_write(current_context, val); return 0; } static __always_inline void trace_recursive_unlock(void) { - unsigned int val = this_cpu_read(current_context); - - val--; - val &= this_cpu_read(current_context); - this_cpu_write(current_context, val); + __this_cpu_and(current_context, __this_cpu_read(current_context) - 1); } #else diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index bcfa2add6dda..91eecaaa43e0 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -125,6 +125,42 @@ enum ftrace_dump_mode ftrace_dump_on_oops; /* When set, tracing will stop when a WARN*() is hit */ int __disable_trace_on_warning; +#ifdef CONFIG_TRACE_ENUM_MAP_FILE +/* Map of enums to their values, for "enum_map" file */ +struct trace_enum_map_head { + struct module *mod; + unsigned long length; +}; + +union trace_enum_map_item; + +struct trace_enum_map_tail { + /* + * "end" is first and points to NULL as it must be different + * than "mod" or "enum_string" + */ + union trace_enum_map_item *next; + const char *end; /* points to NULL */ +}; + +static DEFINE_MUTEX(trace_enum_mutex); + +/* + * The trace_enum_maps are saved in an array with two extra elements, + * one at the beginning, and one at the end. The beginning item contains + * the count of the saved maps (head.length), and the module they + * belong to if not built in (head.mod). The ending item contains a + * pointer to the next array of saved enum_map items. + */ +union trace_enum_map_item { + struct trace_enum_map map; + struct trace_enum_map_head head; + struct trace_enum_map_tail tail; +}; + +static union trace_enum_map_item *trace_enum_maps; +#endif /* CONFIG_TRACE_ENUM_MAP_FILE */ + static int tracing_set_tracer(struct trace_array *tr, const char *buf); #define MAX_TRACER_SIZE 100 @@ -3910,6 +3946,182 @@ static const struct file_operations tracing_saved_cmdlines_size_fops = { .write = tracing_saved_cmdlines_size_write, }; +#ifdef CONFIG_TRACE_ENUM_MAP_FILE +static union trace_enum_map_item * +update_enum_map(union trace_enum_map_item *ptr) +{ + if (!ptr->map.enum_string) { + if (ptr->tail.next) { + ptr = ptr->tail.next; + /* Set ptr to the next real item (skip head) */ + ptr++; + } else + return NULL; + } + return ptr; +} + +static void *enum_map_next(struct seq_file *m, void *v, loff_t *pos) +{ + union trace_enum_map_item *ptr = v; + + /* + * Paranoid! If ptr points to end, we don't want to increment past it. + * This really should never happen. + */ + ptr = update_enum_map(ptr); + if (WARN_ON_ONCE(!ptr)) + return NULL; + + ptr++; + + (*pos)++; + + ptr = update_enum_map(ptr); + + return ptr; +} + +static void *enum_map_start(struct seq_file *m, loff_t *pos) +{ + union trace_enum_map_item *v; + loff_t l = 0; + + mutex_lock(&trace_enum_mutex); + + v = trace_enum_maps; + if (v) + v++; + + while (v && l < *pos) { + v = enum_map_next(m, v, &l); + } + + return v; +} + +static void enum_map_stop(struct seq_file *m, void *v) +{ + mutex_unlock(&trace_enum_mutex); +} + +static int enum_map_show(struct seq_file *m, void *v) +{ + union trace_enum_map_item *ptr = v; + + seq_printf(m, "%s %ld (%s)\n", + ptr->map.enum_string, ptr->map.enum_value, + ptr->map.system); + + return 0; +} + +static const struct seq_operations tracing_enum_map_seq_ops = { + .start = enum_map_start, + .next = enum_map_next, + .stop = enum_map_stop, + .show = enum_map_show, +}; + +static int tracing_enum_map_open(struct inode *inode, struct file *filp) +{ + if (tracing_disabled) + return -ENODEV; + + return seq_open(filp, &tracing_enum_map_seq_ops); +} + +static const struct file_operations tracing_enum_map_fops = { + .open = tracing_enum_map_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static inline union trace_enum_map_item * +trace_enum_jmp_to_tail(union trace_enum_map_item *ptr) +{ + /* Return tail of array given the head */ + return ptr + ptr->head.length + 1; +} + +static void +trace_insert_enum_map_file(struct module *mod, struct trace_enum_map **start, + int len) +{ + struct trace_enum_map **stop; + struct trace_enum_map **map; + union trace_enum_map_item *map_array; + union trace_enum_map_item *ptr; + + stop = start + len; + + /* + * The trace_enum_maps contains the map plus a head and tail item, + * where the head holds the module and length of array, and the + * tail holds a pointer to the next list. + */ + map_array = kmalloc(sizeof(*map_array) * (len + 2), GFP_KERNEL); + if (!map_array) { + pr_warning("Unable to allocate trace enum mapping\n"); + return; + } + + mutex_lock(&trace_enum_mutex); + + if (!trace_enum_maps) + trace_enum_maps = map_array; + else { + ptr = trace_enum_maps; + for (;;) { + ptr = trace_enum_jmp_to_tail(ptr); + if (!ptr->tail.next) + break; + ptr = ptr->tail.next; + + } + ptr->tail.next = map_array; + } + map_array->head.mod = mod; + map_array->head.length = len; + map_array++; + + for (map = start; (unsigned long)map < (unsigned long)stop; map++) { + map_array->map = **map; + map_array++; + } + memset(map_array, 0, sizeof(*map_array)); + + mutex_unlock(&trace_enum_mutex); +} + +static void trace_create_enum_file(struct dentry *d_tracer) +{ + trace_create_file("enum_map", 0444, d_tracer, + NULL, &tracing_enum_map_fops); +} + +#else /* CONFIG_TRACE_ENUM_MAP_FILE */ +static inline void trace_create_enum_file(struct dentry *d_tracer) { } +static inline void trace_insert_enum_map_file(struct module *mod, + struct trace_enum_map **start, int len) { } +#endif /* !CONFIG_TRACE_ENUM_MAP_FILE */ + +static void trace_insert_enum_map(struct module *mod, + struct trace_enum_map **start, int len) +{ + struct trace_enum_map **map; + + if (len <= 0) + return; + + map = start; + + trace_event_enum_update(map, len); + + trace_insert_enum_map_file(mod, start, len); +} + static ssize_t tracing_set_trace_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) @@ -6527,6 +6739,88 @@ struct dentry *tracing_init_dentry(void) return NULL; } +extern struct trace_enum_map *__start_ftrace_enum_maps[]; +extern struct trace_enum_map *__stop_ftrace_enum_maps[]; + +static void __init trace_enum_init(void) +{ + int len; + + len = __stop_ftrace_enum_maps - __start_ftrace_enum_maps; + trace_insert_enum_map(NULL, __start_ftrace_enum_maps, len); +} + +#ifdef CONFIG_MODULES +static void trace_module_add_enums(struct module *mod) +{ + if (!mod->num_trace_enums) + return; + + /* + * Modules with bad taint do not have events created, do + * not bother with enums either. + */ + if (trace_module_has_bad_taint(mod)) + return; + + trace_insert_enum_map(mod, mod->trace_enums, mod->num_trace_enums); +} + +#ifdef CONFIG_TRACE_ENUM_MAP_FILE +static void trace_module_remove_enums(struct module *mod) +{ + union trace_enum_map_item *map; + union trace_enum_map_item **last = &trace_enum_maps; + + if (!mod->num_trace_enums) + return; + + mutex_lock(&trace_enum_mutex); + + map = trace_enum_maps; + + while (map) { + if (map->head.mod == mod) + break; + map = trace_enum_jmp_to_tail(map); + last = &map->tail.next; + map = map->tail.next; + } + if (!map) + goto out; + + *last = trace_enum_jmp_to_tail(map)->tail.next; + kfree(map); + out: + mutex_unlock(&trace_enum_mutex); +} +#else +static inline void trace_module_remove_enums(struct module *mod) { } +#endif /* CONFIG_TRACE_ENUM_MAP_FILE */ + +static int trace_module_notify(struct notifier_block *self, + unsigned long val, void *data) +{ + struct module *mod = data; + + switch (val) { + case MODULE_STATE_COMING: + trace_module_add_enums(mod); + break; + case MODULE_STATE_GOING: + trace_module_remove_enums(mod); + break; + } + + return 0; +} + +static struct notifier_block trace_module_nb = { + .notifier_call = trace_module_notify, + .priority = 0, +}; +#endif /* CONFIG_MODULES */ + static __init int tracer_init_tracefs(void) { struct dentry *d_tracer; @@ -6551,6 +6845,14 @@ static __init int tracer_init_tracefs(void) trace_create_file("saved_cmdlines_size", 0644, d_tracer, NULL, &tracing_saved_cmdlines_size_fops); + trace_enum_init(); + + trace_create_enum_file(d_tracer); + +#ifdef CONFIG_MODULES + register_module_notifier(&trace_module_nb); +#endif + #ifdef CONFIG_DYNAMIC_FTRACE trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, &ftrace_update_tot_cnt, &tracing_dyn_info_fops); @@ -6877,7 +7179,7 @@ void __init trace_init(void) tracepoint_printk = 0; } tracer_alloc_buffers(); - trace_event_init(); + trace_event_init(); } __init static int clear_boot_tracer(void) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index d951deddec89..d2612016de94 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1309,8 +1309,10 @@ static inline void init_ftrace_syscalls(void) { } #ifdef CONFIG_EVENT_TRACING void trace_event_init(void); +void trace_event_enum_update(struct trace_enum_map **map, int len); #else static inline void __init trace_event_init(void) { } +static inlin void trace_event_enum_update(struct trace_enum_map **map, int len) { } #endif extern struct trace_iterator *tracepoint_print_iter; diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index e2d027ac66a2..ee7b94a4810a 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -223,7 +223,7 @@ FTRACE_ENTRY(bprint, bprint_entry, __dynamic_array( u32, buf ) ), - F_printk("%pf: %s", + F_printk("%ps: %s", (void *)__entry->ip, __entry->fmt), FILTER_OTHER @@ -238,7 +238,7 @@ FTRACE_ENTRY(print, print_entry, __dynamic_array( char, buf ) ), - F_printk("%pf: %s", + F_printk("%ps: %s", (void *)__entry->ip, __entry->buf), FILTER_OTHER @@ -253,7 +253,7 @@ FTRACE_ENTRY(bputs, bputs_entry, __field( const char *, str ) ), - F_printk("%pf: %s", + F_printk("%ps: %s", (void *)__entry->ip, __entry->str), FILTER_OTHER diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 0d2e47370ee7..7da1dfeb322e 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -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 */ diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index 12e2b99be862..174a6a71146c 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c @@ -177,7 +177,7 @@ struct ftrace_event_call __used event_##call = { \ }, \ .event.type = etype, \ .print_fmt = print, \ - .flags = TRACE_EVENT_FL_IGNORE_ENABLE | TRACE_EVENT_FL_USE_CALL_FILTER, \ + .flags = TRACE_EVENT_FL_IGNORE_ENABLE, \ }; \ struct ftrace_event_call __used \ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call; diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index ed998fbf09ce..9ba3f43f580e 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -250,7 +250,7 @@ DEFINE_FETCH_symbol(string_size) #define fetch_file_offset_string_size NULL /* Fetch type information table */ -const struct fetch_type kprobes_fetch_type_table[] = { +static const struct fetch_type kprobes_fetch_type_table[] = { /* Special types */ [FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1, "__data_loc char[]"), @@ -760,7 +760,8 @@ static int create_trace_kprobe(int argc, char **argv) /* Parse fetch argument */ ret = traceprobe_parse_probe_arg(arg, &tk->tp.size, parg, - is_return, true); + is_return, true, + kprobes_fetch_type_table); if (ret) { pr_info("Parse error at argument[%d]. (%d)\n", i, ret); goto error; diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index b983b2fd2ca1..1769a81da8a7 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -356,17 +356,14 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, /* Recursive argument parser */ static int parse_probe_arg(char *arg, const struct fetch_type *t, - struct fetch_param *f, bool is_return, bool is_kprobe) + struct fetch_param *f, bool is_return, bool is_kprobe, + const struct fetch_type *ftbl) { - const struct fetch_type *ftbl; unsigned long param; long offset; char *tmp; int ret = 0; - ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table; - BUG_ON(ftbl == NULL); - switch (arg[0]) { case '$': ret = parse_probe_vars(arg + 1, t, f, is_return, is_kprobe); @@ -447,7 +444,7 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t, dprm->fetch_size = get_fetch_size_function(t, dprm->fetch, ftbl); ret = parse_probe_arg(arg, t2, &dprm->orig, is_return, - is_kprobe); + is_kprobe, ftbl); if (ret) kfree(dprm); else { @@ -505,15 +502,12 @@ static int __parse_bitfield_probe_arg(const char *bf, /* String length checking wrapper */ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, - struct probe_arg *parg, bool is_return, bool is_kprobe) + struct probe_arg *parg, bool is_return, bool is_kprobe, + const struct fetch_type *ftbl) { - const struct fetch_type *ftbl; const char *t; int ret; - ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table; - BUG_ON(ftbl == NULL); - if (strlen(arg) > MAX_ARGSTR_LEN) { pr_info("Argument is too long.: %s\n", arg); return -ENOSPC; @@ -535,7 +529,8 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, } parg->offset = *size; *size += parg->type->size; - ret = parse_probe_arg(arg, parg->type, &parg->fetch, is_return, is_kprobe); + ret = parse_probe_arg(arg, parg->type, &parg->fetch, is_return, + is_kprobe, ftbl); if (ret >= 0 && t != NULL) ret = __parse_bitfield_probe_arg(t, parg->type, &parg->fetch); diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 19aff635841a..ab283e146b70 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -229,13 +229,6 @@ ASSIGN_FETCH_FUNC(file_offset, ftype), \ #define FETCH_TYPE_STRING 0 #define FETCH_TYPE_STRSIZE 1 -/* - * Fetch type information table. - * It's declared as a weak symbol due to conditional compilation. - */ -extern __weak const struct fetch_type kprobes_fetch_type_table[]; -extern __weak const struct fetch_type uprobes_fetch_type_table[]; - #ifdef CONFIG_KPROBE_EVENT struct symbol_cache; unsigned long update_symbol_cache(struct symbol_cache *sc); @@ -333,7 +326,8 @@ find_event_file_link(struct trace_probe *tp, struct ftrace_event_file *file) } extern int traceprobe_parse_probe_arg(char *arg, ssize_t *size, - struct probe_arg *parg, bool is_return, bool is_kprobe); + struct probe_arg *parg, bool is_return, bool is_kprobe, + const struct fetch_type *ftbl); extern int traceprobe_conflict_field_name(const char *name, struct probe_arg *args, int narg); diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 7dc1c8abecd6..74865465e0b7 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -196,7 +196,7 @@ DEFINE_FETCH_file_offset(string) DEFINE_FETCH_file_offset(string_size) /* Fetch type information table */ -const struct fetch_type uprobes_fetch_type_table[] = { +static const struct fetch_type uprobes_fetch_type_table[] = { /* Special types */ [FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1, "__data_loc char[]"), @@ -535,7 +535,8 @@ static int create_trace_uprobe(int argc, char **argv) /* Parse fetch argument */ ret = traceprobe_parse_probe_arg(arg, &tu->tp.size, parg, - is_return, false); + is_return, false, + uprobes_fetch_type_table); if (ret) { pr_info("Parse error at argument[%d]. (%d)\n", i, ret); goto error; diff --git a/net/mac80211/trace.c b/net/mac80211/trace.c index 386e45d8a958..edfe0c170a1c 100644 --- a/net/mac80211/trace.c +++ b/net/mac80211/trace.c @@ -8,6 +8,7 @@ #include "debug.h" #define CREATE_TRACE_POINTS #include "trace.h" +#include "trace_msg.h" #ifdef CONFIG_MAC80211_MESSAGE_TRACING void __sdata_info(const char *fmt, ...) diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 263a9561eb26..755a5388dbca 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -2312,44 +2312,6 @@ TRACE_EVENT(drv_tdls_recv_channel_switch, ) ); -#ifdef CONFIG_MAC80211_MESSAGE_TRACING -#undef TRACE_SYSTEM -#define TRACE_SYSTEM mac80211_msg - -#define MAX_MSG_LEN 100 - -DECLARE_EVENT_CLASS(mac80211_msg_event, - TP_PROTO(struct va_format *vaf), - - TP_ARGS(vaf), - - TP_STRUCT__entry( - __dynamic_array(char, msg, MAX_MSG_LEN) - ), - - TP_fast_assign( - WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), - MAX_MSG_LEN, vaf->fmt, - *vaf->va) >= MAX_MSG_LEN); - ), - - TP_printk("%s", __get_str(msg)) -); - -DEFINE_EVENT(mac80211_msg_event, mac80211_info, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); -DEFINE_EVENT(mac80211_msg_event, mac80211_dbg, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); -DEFINE_EVENT(mac80211_msg_event, mac80211_err, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); -#endif - #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH diff --git a/net/mac80211/trace_msg.h b/net/mac80211/trace_msg.h new file mode 100644 index 000000000000..768f7c22a190 --- /dev/null +++ b/net/mac80211/trace_msg.h @@ -0,0 +1,53 @@ +#ifdef CONFIG_MAC80211_MESSAGE_TRACING + +#if !defined(__MAC80211_MSG_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ) +#define __MAC80211_MSG_DRIVER_TRACE + +#include <linux/tracepoint.h> +#include <net/mac80211.h> +#include "ieee80211_i.h" + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mac80211_msg + +#define MAX_MSG_LEN 100 + +DECLARE_EVENT_CLASS(mac80211_msg_event, + TP_PROTO(struct va_format *vaf), + + TP_ARGS(vaf), + + TP_STRUCT__entry( + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + + TP_fast_assign( + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + + TP_printk("%s", __get_str(msg)) +); + +DEFINE_EVENT(mac80211_msg_event, mac80211_info, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); +DEFINE_EVENT(mac80211_msg_event, mac80211_dbg, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); +DEFINE_EVENT(mac80211_msg_event, mac80211_err, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); +#endif /* !__MAC80211_MSG_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace_msg +#include <trace/define_trace.h> + +#endif diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h index a2c8b02b6359..8965d1bb8811 100644 --- a/samples/trace_events/trace-events-sample.h +++ b/samples/trace_events/trace-events-sample.h @@ -22,7 +22,25 @@ * protection, just like TRACE_INCLUDE_FILE. */ #undef TRACE_SYSTEM -#define TRACE_SYSTEM sample +#define TRACE_SYSTEM sample-trace + +/* + * TRACE_SYSTEM is expected to be a C valid variable (alpha-numeric + * and underscore), although it may start with numbers. If for some + * reason it is not, you need to add the following lines: + */ +#undef TRACE_SYSTEM_VAR +#define TRACE_SYSTEM_VAR sample_trace +/* + * But the above is only needed if TRACE_SYSTEM is not alpha-numeric + * and underscored. By default, TRACE_SYSTEM_VAR will be equal to + * TRACE_SYSTEM. As TRACE_SYSTEM_VAR must be alpha-numeric, if + * TRACE_SYSTEM is not, then TRACE_SYSTEM_VAR must be defined with + * only alpha-numeric and underscores. + * + * The TRACE_SYSTEM_VAR is only used internally and not visible to + * user space. + */ /* * Notice that this file is not protected like a normal header. @@ -180,8 +198,30 @@ static inline int __length_of(const int *list) ; return i; } + +enum { + TRACE_SAMPLE_FOO = 2, + TRACE_SAMPLE_BAR = 4, + TRACE_SAMPLE_ZOO = 8, +}; #endif +/* + * If enums are used in the TP_printk(), their names will be shown in + * format files and not their values. This can cause problems with user + * space programs that parse the format files to know how to translate + * the raw binary trace output into human readable text. + * + * To help out user space programs, any enum that is used in the TP_printk() + * should be defined by TRACE_DEFINE_ENUM() macro. All that is needed to + * be done is to add this macro with the enum within it in the trace + * header file, and it will be converted in the output. + */ + +TRACE_DEFINE_ENUM(TRACE_SAMPLE_FOO); +TRACE_DEFINE_ENUM(TRACE_SAMPLE_BAR); +TRACE_DEFINE_ENUM(TRACE_SAMPLE_ZOO); + TRACE_EVENT(foo_bar, TP_PROTO(const char *foo, int bar, const int *lst, @@ -206,7 +246,47 @@ TRACE_EVENT(foo_bar, __assign_bitmask(cpus, cpumask_bits(mask), num_possible_cpus()); ), - TP_printk("foo %s %d %s %s (%s)", __entry->foo, __entry->bar, + TP_printk("foo %s %d %s %s %s %s (%s)", __entry->foo, __entry->bar, + +/* + * Notice here the use of some helper functions. This includes: + * + * __print_symbolic( variable, { value, "string" }, ... ), + * + * The variable is tested against each value of the { } pair. If + * the variable matches one of the values, then it will print the + * string in that pair. If non are matched, it returns a string + * version of the number (if __entry->bar == 7 then "7" is returned). + */ + __print_symbolic(__entry->bar, + { 0, "zero" }, + { TRACE_SAMPLE_FOO, "TWO" }, + { TRACE_SAMPLE_BAR, "FOUR" }, + { TRACE_SAMPLE_ZOO, "EIGHT" }, + { 10, "TEN" } + ), + +/* + * __print_flags( variable, "delim", { value, "flag" }, ... ), + * + * This is similar to __print_symbolic, except that it tests the bits + * of the value. If ((FLAG & variable) == FLAG) then the string is + * printed. If more than one flag matches, then each one that does is + * also printed with delim in between them. + * If not all bits are accounted for, then the not found bits will be + * added in hex format: 0x506 will show BIT2|BIT4|0x500 + */ + __print_flags(__entry->bar, "|", + { 1, "BIT1" }, + { 2, "BIT2" }, + { 4, "BIT3" }, + { 8, "BIT4" } + ), +/* + * __print_array( array, len, element_size ) + * + * This prints out the array that is defined by __array in a nice format. + */ __print_array(__get_dynamic_array(list), __get_dynamic_array_len(list), sizeof(int)), diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index afe20ed9fac8..2c0bd8f2aad0 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -3976,7 +3976,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc if (asprintf(&arg->atom.atom, "%lld", ip) < 0) goto out_free; - /* skip the first "%pf: " */ + /* skip the first "%ps: " */ for (ptr = fmt + 5, bptr = data + field->offset; bptr < data + size && *ptr; ptr++) { int ls = 0; |