[PATCH V4] trace/events: add chip name and hwirq to irq entry tracepoint
Add chip name and hw-irq number to the trace_irq_handler_entry() tracepoint. When tracing interrupt events the chip-name and hw-irq numbers are stable and known in advance. This makes them a better choice as a filtering criteria for the trace buffer dump. On the flipside, the os-irq numbers are dynamically allocated which makes them difficult to use for the same purpose. Dump messages will look like: ...irq_handler_entry: irq=22 name=msm_serial0 chip_name=GIC hwirq=140 Suggested-by: Stephen Boyd sb...@codeaurora.org Reviewed-by: Andy Gross agr...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- Changes since V3: - use field variable in trace structure to assign value for chip name and hwirq rather than printing directly to the trace buffer. --- Changes since V2: - fixed dump message in commit text to reflect Chip name instead of domain. --- Changes since V1: - added reviewed by Andy Gross --- include/trace/events/irq.h | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index 3608beb..0898506 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h @@ -23,6 +23,17 @@ struct softirq_action; softirq_name(HRTIMER), \ softirq_name(RCU)) + +#define show_chip_name(irq)\ + (irq_get_irq_data(irq) \ +? irq_get_irq_data(irq)-chip-name\ +: NULL) + +#define show_hwirq(irq)\ + (irq_get_irq_data(irq) \ +? irq_get_irq_data(irq)-hwirq \ +: -ENODEV) + /** * irq_handler_entry - called immediately before the irq action handler * @irq: irq number @@ -41,16 +52,21 @@ TRACE_EVENT(irq_handler_entry, TP_ARGS(irq, action), TP_STRUCT__entry( - __field(int,irq ) - __string( name, action-name) + __field( int, irq ) + __field( unsigned long, hwirq) + __string( name, action-name ) + __string( chip, show_chip_name(irq) ) ), TP_fast_assign( __entry-irq = irq; + __entry-hwirq = show_hwirq(irq); __assign_str(name, action-name); + __assign_str(chip, show_chip_name(irq)); ), - TP_printk(irq=%d name=%s, __entry-irq, __get_str(name)) + TP_printk(irq=%d name=%s chip=%s hwirq=%ld, __entry-irq, + __get_str(name), __get_str(chip), __entry-hwirq) ); /** -- 1.8.5.2 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3] trace/events: add chip name and hwirq to irq entry tracepoint
Add chip name and hw-irq number to the trace_irq_handler_entry() tracepoint. When tracing interrupt events the chip-name and hw-irq numbers are stable and known in advance. This makes them a better choice as a filtering criteria for the trace buffer dump. On the flipside, the os-irq numbers are dynamically allocated which makes them difficult to use for the same purpose. Dump messages will look like: ...irq_handler_entry: irq=22 name=msm_serial0 chip_name=GIC hwirq=140 Suggested-by: Stephen Boyd sb...@codeaurora.org Reviewed-by: Andy Gross agr...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- Changes since V2: - fixed dump message in commit text to reflect Chip name instead of domain. --- Changes since V1: - added reviewed by Andy Gross --- include/trace/events/irq.h | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index 3608beb..5370075 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h @@ -23,6 +23,17 @@ struct softirq_action; softirq_name(HRTIMER), \ softirq_name(RCU)) + +#define show_chip_name(irq)\ + (irq_get_irq_data(irq) \ +? irq_get_irq_data(irq)-chip-name\ +: NULL) + +#define show_hwirq(irq)\ + (irq_get_irq_data(irq) \ +? irq_get_irq_data(irq)-hwirq \ +: -ENODEV) + /** * irq_handler_entry - called immediately before the irq action handler * @irq: irq number @@ -50,7 +61,9 @@ TRACE_EVENT(irq_handler_entry, __assign_str(name, action-name); ), - TP_printk(irq=%d name=%s, __entry-irq, __get_str(name)) + TP_printk(irq=%d name=%s chip_name=%s hwirq=%ld, __entry-irq, + __get_str(name), show_chip_name(__entry-irq), + show_hwirq(__entry-irq)) ); /** -- 1.8.5.2 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] trace/events: add chip name and hwirq to irq entry tracepoint
On Mon, 22 Jun 2015, Ankit Gupta wrote: Add chip name and hw-irq number to the trace_irq_handler_entry() tracepoint. When tracing interrupt events the chip-name and hw-irq numbers are stable and known in advance. This makes them a better choice as a filtering criteria for the trace buffer dump. On the flipside, the os-irq numbers are dynamically allocated which makes them difficult to use for the same purpose. Dump messages will look like: ...irq_handler_entry: irq=22 name=msm_serial0 domain=GIC hwirq=140 I can't see the domain name being captured/printed in the code below. -TP_printk(irq=%d name=%s, __entry-irq, __get_str(name)) +TP_printk(irq=%d name=%s chip_name=%s hwirq=%ld, __entry-irq, + __get_str(name), show_chip_name(__entry-irq), + show_hwirq(__entry-irq)) ); Thanks Thomas for your comment. Its actually printing a chipname and not the domain. Will correct the dump message in the next patch. It will print as follow. ...irq_handler_entry: irq=22 name=msm_serial0 Chip=GIC hwirq=140 Thanks, tglx -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] trace/events: add chip name and hwirq to irq entry tracepoint
Add chip name and hw-irq number to the trace_irq_handler_entry() tracepoint. When tracing interrupt events the chip-name and hw-irq numbers are stable and known in advance. This makes them a better choice as a filtering criteria for the trace buffer dump. On the flipside, the os-irq numbers are dynamically allocated which makes them difficult to use for the same purpose. Dump messages will look like: ...irq_handler_entry: irq=22 name=msm_serial0 domain=GIC hwirq=140 Suggested-by: Stephen Boyd sb...@codeaurora.org Reviewed-by: Andy Gross agr...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- Changes since V1: - added reviewed by Andy Gross --- include/trace/events/irq.h | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index 3608beb..5370075 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h @@ -23,6 +23,17 @@ struct softirq_action; softirq_name(HRTIMER), \ softirq_name(RCU)) + +#define show_chip_name(irq)\ + (irq_get_irq_data(irq) \ +? irq_get_irq_data(irq)-chip-name\ +: NULL) + +#define show_hwirq(irq)\ + (irq_get_irq_data(irq) \ +? irq_get_irq_data(irq)-hwirq \ +: -ENODEV) + /** * irq_handler_entry - called immediately before the irq action handler * @irq: irq number @@ -50,7 +61,9 @@ TRACE_EVENT(irq_handler_entry, __assign_str(name, action-name); ), - TP_printk(irq=%d name=%s, __entry-irq, __get_str(name)) + TP_printk(irq=%d name=%s chip_name=%s hwirq=%ld, __entry-irq, + __get_str(name), show_chip_name(__entry-irq), + show_hwirq(__entry-irq)) ); /** -- 1.8.5.2 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
[PATCH RESEND V3] spmi: add command tracepoints for SPMI
Add tracepoints to retrieve information about read, write and non-data commands. For performance measurement support tracepoints are added at the beginning and at the end of transfers. Following is a list showing the new tracepoint events. The cmd parameter here represents the opcode, SID, and full 16-bit address. spmi_write_begin: cmd and data buffer. spmi_write_end : cmd and return value. spmi_read_begin : cmd. spmi_read_end : cmd, return value and data buffer. spmi_cmd: cmd. The reason that cmd appears at both the beginning and at the end event is that SPMI drivers can request commands concurrently. cmd helps in matching the corresponding events. SPMI tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_read_begin: opc=56 sid=00 addr=0x ... spmi_read_end: opc=56 sid=00 addr=0x ret=0 len=02 buf=0x[01-40] ... spmi_write_begin: opc=48 sid=00 addr=0x len=3 buf=0x[ff-ff-ff] Suggested-by: Sagar Dharia sdha...@codeaurora.org Acked-by: Steven Rostedt rost...@goodmis.org Reviewed-by: Stephen Boyd sb...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- Changes since v2: - use full names in events: wr-write, rd-read, beg-begin. - Edited the commit text to reflect full names of event. --- Changes since V1: - Change from ':' to = in printk in spmi.h. - Added extra line between declaration and Code in spmi.c. - Added use and example of spmi dump message in commit text. --- drivers/spmi/spmi.c | 22 +++- include/trace/events/spmi.h | 135 2 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 include/trace/events/spmi.h diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 1d92f51..36fe010 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -21,6 +21,8 @@ #include linux/pm_runtime.h #include dt-bindings/spmi/spmi.h +#define CREATE_TRACE_POINTS +#include trace/events/spmi.h static DEFINE_IDA(ctrl_ida); @@ -95,28 +97,42 @@ EXPORT_SYMBOL_GPL(spmi_device_remove); static inline int spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid) { + int ret; + if (!ctrl || !ctrl-cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-cmd(ctrl, opcode, sid); + ret = ctrl-cmd(ctrl, opcode, sid); + trace_spmi_cmd(opcode, sid, ret); + return ret; } static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl-read_cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_begin(opcode, sid, addr); + ret = ctrl-read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_end(opcode, sid, addr, ret, len, buf); + return ret; } static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, const u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl-write_cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_begin(opcode, sid, addr, len, buf); + ret = ctrl-write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_end(opcode, sid, addr, ret); + return ret; } /** diff --git a/include/trace/events/spmi.h b/include/trace/events/spmi.h new file mode 100644 index 000..62f005e --- /dev/null +++ b/include/trace/events/spmi.h @@ -0,0 +1,135 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM spmi + +#if !defined(_TRACE_SPMI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SPMI_H + +#include linux/spmi.h +#include linux/tracepoint.h + +/* + * drivers/spmi/spmi.c + */ + +TRACE_EVENT(spmi_write_begin, + TP_PROTO(u8 opcode, u8 sid, u16 addr, u8 len, const u8 *buf), + TP_ARGS(opcode, sid, addr, len, buf), + + TP_STRUCT__entry( + __field ( u8, opcode) + __field ( u8, sid ) + __field ( u16,addr ) + __field ( u8, len ) + __dynamic_array ( u8, buf, len + 1 ) + ), + + TP_fast_assign( + __entry-opcode = opcode; + __entry-sid= sid; + __entry-addr = addr; + __entry-len= len + 1; + memcpy(__get_dynamic_array(buf), buf, len + 1); + ), + + TP_printk(opc=%d sid=%02d addr=0x%04x len=%d buf=0x[%*phD], + (int)__entry-opcode, (int)__entry-sid, + (int)__entry-addr, (int)__entry-len
[PATCH v2] spmi-pmic-arb: add irq tracepoints to the pmic-arb driver
The spmi-pmic-arb is also an interrupt controller. It gets a single aggregate irq and disseminates it to individual pmic-peripheral drivers. Each pmic-peripheral has a unique apid number, and can have multiple interrupt capable functions. The registered apid range shows the lowest and highest apid numbers of pmic-peripheral drivers which request irqs. Pid is the base address of that peripheral. For performance measurement, tracepoints are added at the beginning of the aggregate irq and at the end of the individual pmic-peripheral irqs. Following is a list showing the new tracepoint events: spmi_pmic_arb_aggregate_irq_start: aggregate irq number and registered apid range. spmi_pmic_arb_apid_irq_end: apid, irq, func_num, sid and pid. SPMI Interrupts tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi-pmic-arb/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_pmic_arb_aggregate_irq_start: irq=150 registered apid range=(3,189) ... spmi_pmic_arb_apid_irq_end: apid=3 irq=1 func_num=0 sid=0 pid=0x8 Suggested-by: Sagar Dharia sdha...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- drivers/spmi/spmi-pmic-arb.c | 13 +--- include/trace/events/spmi-pmic-arb.h | 62 2 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 include/trace/events/spmi-pmic-arb.h diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 20559ab..56100e2 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -23,6 +23,9 @@ #include linux/slab.h #include linux/spmi.h +#define CREATE_TRACE_POINTS +#include trace/events/spmi-pmic-arb.h + /* PMIC Arbiter configuration registers */ #define PMIC_ARB_VERSION 0x #define PMIC_ARB_INT_EN0x0004 @@ -375,16 +378,15 @@ static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid) unsigned int irq; u32 status; int id; + u16 ppid = pa-apid_to_ppid[apid]; status = readl_relaxed(pa-intr + SPMI_PIC_IRQ_STATUS(apid)); while (status) { id = ffs(status) - 1; status = ~(1 id); - irq = irq_find_mapping(pa-domain, - pa-apid_to_ppid[apid] 16 -| id 8 -| apid); + irq = irq_find_mapping(pa-domain, ppid 16 | id 8 | apid); generic_handle_irq(irq); + trace_spmi_pmic_arb_apid_irq_end(apid, irq, id, ppid); } } @@ -399,7 +401,8 @@ static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc) int i, id; chained_irq_enter(chip, desc); - + trace_spmi_pmic_arb_aggregate_irq_start(irq, pa-min_apid, + pa-max_apid); for (i = first; i = last; ++i) { status = readl_relaxed(intr + SPMI_PIC_OWNER_ACC_STATUS(pa-ee, i)); diff --git a/include/trace/events/spmi-pmic-arb.h b/include/trace/events/spmi-pmic-arb.h new file mode 100644 index 000..c7fd402 --- /dev/null +++ b/include/trace/events/spmi-pmic-arb.h @@ -0,0 +1,62 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM spmi-pmic-arb + +#if !defined(_TRACE_SPMI_PMIC_ARB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SPMI_PMIC_ARB_H + +#include linux/spmi.h +#include linux/tracepoint.h + +/* + * drivers/spmi/spmi-pmic-arb.c + */ + +TRACE_EVENT(spmi_pmic_arb_aggregate_irq_start, + TP_PROTO(unsigned int irq, u16 first, u16 last), + TP_ARGS(irq, first, last), + + TP_STRUCT__entry( + __field ( unsigned int, irq ) + __field ( u16,first ) + __field ( u16,last ) + ), + + TP_fast_assign( + __entry-irq= irq; + __entry-first = first; + __entry-last = last; + ), + + TP_printk(irq=%d registered apid range=(%d,%d), + (int)__entry-irq, (int)__entry-first, (int)__entry-last) +); + +TRACE_EVENT(spmi_pmic_arb_apid_irq_end, + TP_PROTO(u8 apid, unsigned int irq, u8 func_num, u16 ppid), + TP_ARGS(apid, irq, func_num, ppid), + + TP_STRUCT__entry( + __field ( u8, apid ) + __field ( unsigned int, irq ) + __field ( u8, func_num ) + __field ( u8, sid ) + __field ( u8, pid ) + ), + + TP_fast_assign( + __entry-apid = apid; + __entry-irq = irq; + __entry-func_num = func_num; + __entry-sid
Re: [PATCH v2] spmi-pmic-arb: add irq tracepoints to the pmic-arb driver
The spmi-pmic-arb is also an interrupt controller. It gets a single aggregate irq and disseminates it to individual pmic-peripheral drivers. Each pmic-peripheral has a unique apid number, and can have multiple interrupt capable functions. The registered apid range shows the lowest and highest apid numbers of pmic-peripheral drivers which request irqs. Pid is the base address of that peripheral. For performance measurement, tracepoints are added at the beginning of the aggregate irq and at the end of the individual pmic-peripheral irqs. Following is a list showing the new tracepoint events: spmi_pmic_arb_aggregate_irq_start: aggregate irq number and registered apid range. spmi_pmic_arb_apid_irq_end: apid, irq, func_num, sid and pid. SPMI Interrupts tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi-pmic-arb/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_pmic_arb_aggregate_irq_start: irq=150 registered apid range=(3,189) ... spmi_pmic_arb_apid_irq_end: apid=3 irq=1 func_num=0 sid=0 pid=0x8 Suggested-by: Sagar Dharia sdha...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- --- Changes since V1: - pass ppid from driver to evaluate pid and sid in trace file itself. - type of apid range change from int to u16 as max range can be 512. - type of func_num change from int to u8, as max it can be 8. --- drivers/spmi/spmi-pmic-arb.c | 13 +--- include/trace/events/spmi-pmic-arb.h | 62 2 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 include/trace/events/spmi-pmic-arb.h diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 20559ab..56100e2 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -23,6 +23,9 @@ #include linux/slab.h #include linux/spmi.h +#define CREATE_TRACE_POINTS +#include trace/events/spmi-pmic-arb.h + /* PMIC Arbiter configuration registers */ #define PMIC_ARB_VERSION 0x #define PMIC_ARB_INT_EN 0x0004 @@ -375,16 +378,15 @@ static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid) unsigned int irq; u32 status; int id; + u16 ppid = pa-apid_to_ppid[apid]; status = readl_relaxed(pa-intr + SPMI_PIC_IRQ_STATUS(apid)); while (status) { id = ffs(status) - 1; status = ~(1 id); - irq = irq_find_mapping(pa-domain, -pa-apid_to_ppid[apid] 16 - | id 8 - | apid); + irq = irq_find_mapping(pa-domain, ppid 16 | id 8 | apid); generic_handle_irq(irq); + trace_spmi_pmic_arb_apid_irq_end(apid, irq, id, ppid); } } @@ -399,7 +401,8 @@ static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc) int i, id; chained_irq_enter(chip, desc); - + trace_spmi_pmic_arb_aggregate_irq_start(irq, pa-min_apid, + pa-max_apid); for (i = first; i = last; ++i) { status = readl_relaxed(intr + SPMI_PIC_OWNER_ACC_STATUS(pa-ee, i)); diff --git a/include/trace/events/spmi-pmic-arb.h b/include/trace/events/spmi-pmic-arb.h new file mode 100644 index 000..c7fd402 --- /dev/null +++ b/include/trace/events/spmi-pmic-arb.h @@ -0,0 +1,62 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM spmi-pmic-arb + +#if !defined(_TRACE_SPMI_PMIC_ARB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SPMI_PMIC_ARB_H + +#include linux/spmi.h +#include linux/tracepoint.h + +/* + * drivers/spmi/spmi-pmic-arb.c + */ + +TRACE_EVENT(spmi_pmic_arb_aggregate_irq_start, + TP_PROTO(unsigned int irq, u16 first, u16 last), + TP_ARGS(irq, first, last), + + TP_STRUCT__entry( + __field ( unsigned int, irq ) + __field ( u16,first ) + __field ( u16,last ) + ), + + TP_fast_assign( + __entry-irq= irq; + __entry-first = first; + __entry-last = last; + ), + + TP_printk(irq=%d registered apid range=(%d,%d), + (int)__entry-irq, (int)__entry-first, (int)__entry-last) +); + +TRACE_EVENT(spmi_pmic_arb_apid_irq_end, + TP_PROTO(u8 apid, unsigned int irq, u8 func_num, u16 ppid), + TP_ARGS(apid, irq, func_num, ppid), + + TP_STRUCT__entry( + __field ( u8, apid ) + __field ( unsigned int, irq ) + __field ( u8, func_num ) + __field ( u8, sid
Re: [PATCH] spmi-pmic-arb: add irq tracepoints to the pmic-arb driver
On 05/26/2015 04:39 PM, Ankit Gupta wrote: The spmi-pmic-arb is also an interrupt controller. It gets a single aggregate irq and disseminates it to individual pmic-peripheral drivers. Each pmic-peripheral has a unique apid number, and can have multiple interrupt capable functions. The registered apid range shows the lowest and highest apid numbers of pmic-peripheral drivers which request irqs. Pid is the base address of that peripheral. For performance measurement, tracepoints are added at the beginning of the aggregate irq and at the end of the individual pmic-peripheral irqs. Following is a list showing the new tracepoint events: spmi_pmic_arb_aggregate_irq_start: aggregate irq number and registered apid range. spmi_pmic_arb_apid_irq_end: apid, irq, func_num, sid and pid. SPMI Interrupts tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi-pmic-arb/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_pmic_arb_aggregate_irq_start: irq=150 registered apid range=(3,189) ... spmi_pmic_arb_apid_irq_end: apid=3 irq=1 func_num=0 sid=0 pid=0x8 Suggested-by: Sagar Dharia sdha...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- How is this any better than irq tracepoints that we already have for generic irqs? It is better than generic irq tracepoints because it provides bus specific information (sid and address(pid) of slave write), driver specific information (apid (pmic-peripheral) and func_num) and statistics (apid range). Recall that *slave* read/write cannot be traced by the spmi framework ftrace. -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] spmi-pmic-arb: add irq tracepoints to the pmic-arb driver
On Tue, 26 May 2015 17:39:15 -0600 Ankit Gupta ankgu...@codeaurora.org wrote: The spmi-pmic-arb is also an interrupt controller. It gets a single aggregate irq and disseminates it to individual pmic-peripheral drivers. Each pmic-peripheral has a unique apid number, and can have multiple interrupt capable functions. The registered apid range shows the lowest and highest apid numbers of pmic-peripheral drivers which request irqs. Pid is the base address of that peripheral. For performance measurement, tracepoints are added at the beginning of the aggregate irq and at the end of the individual pmic-peripheral irqs. Following is a list showing the new tracepoint events: spmi_pmic_arb_aggregate_irq_start: aggregate irq number and registered apid range. spmi_pmic_arb_apid_irq_end: apid, irq, func_num, sid and pid. SPMI Interrupts tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi-pmic-arb/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_pmic_arb_aggregate_irq_start: irq=150 registered apid range=(3,189) ... spmi_pmic_arb_apid_irq_end: apid=3 irq=1 func_num=0 sid=0 pid=0x8 Suggested-by: Sagar Dharia sdha...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- drivers/spmi/spmi-pmic-arb.c | 15 ++--- include/trace/events/spmi-pmic-arb.h | 62 2 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 include/trace/events/spmi-pmic-arb.h diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 20559ab..342a71d 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -23,6 +23,9 @@ #include linux/slab.h #include linux/spmi.h +#define CREATE_TRACE_POINTS +#include trace/events/spmi-pmic-arb.h + /* PMIC Arbiter configuration registers */ #define PMIC_ARB_VERSION0x #define PMIC_ARB_INT_EN 0x0004 @@ -375,16 +378,17 @@ static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid) unsigned int irq; u32 status; int id; +u16 ppid = pa-apid_to_ppid[apid]; +u8 sid = (ppid 8) 0x0F; +u8 pid = ppid 0xFF; status = readl_relaxed(pa-intr + SPMI_PIC_IRQ_STATUS(apid)); while (status) { id = ffs(status) - 1; status = ~(1 id); -irq = irq_find_mapping(pa-domain, - pa-apid_to_ppid[apid] 16 - | id 8 - | apid); +irq = irq_find_mapping(pa-domain, ppid 16 | id 8 | apid); generic_handle_irq(irq); +trace_spmi_pmic_arb_apid_irq_end(apid, irq, id, sid, pid); It looks like sid is only used for the tracepoint processing. Instead of doing the work up above (ppid 8) 0x0F that would only be used in the unlikely event that you happen to be tracing, what about moving the work below into the tracepoint, by passing in ppid, and having: __entry-sid = (ppid 8) 0x0F; That way you would save some CPU cycles when not tracing. -- Steve Will do it. } } @@ -399,7 +403,8 @@ static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc) int i, id; chained_irq_enter(chip, desc); - +trace_spmi_pmic_arb_aggregate_irq_start(irq, pa-min_apid, +pa-max_apid); for (i = first; i = last; ++i) { status = readl_relaxed(intr + SPMI_PIC_OWNER_ACC_STATUS(pa-ee, i)); diff --git a/include/trace/events/spmi-pmic-arb.h b/include/trace/events/spmi-pmic-arb.h new file mode 100644 index 000..6c4dbca --- /dev/null +++ b/include/trace/events/spmi-pmic-arb.h @@ -0,0 +1,62 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM spmi-pmic-arb + +#if !defined(_TRACE_SPMI_PMIC_ARB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SPMI_PMIC_ARB_H + +#include linux/spmi.h +#include linux/tracepoint.h + +/* + * drivers/spmi/spmi-pmic-arb.c + */ + +TRACE_EVENT(spmi_pmic_arb_aggregate_irq_start, +TP_PROTO(unsigned int irq, int first, int last), +TP_ARGS(irq, first, last), + +TP_STRUCT__entry( +__field ( unsigned int, irq ) +__field ( int,first ) +__field ( int,last ) +), + +TP_fast_assign( +__entry-irq= irq; +__entry-first = first; +__entry-last = last; +), + +TP_printk(irq=%d registered apid range=(%d,%d), + (int)__entry-irq, __entry-first, __entry-last) +); + +TRACE_EVENT(spmi_pmic_arb_apid_irq_end, +TP_PROTO(u8 apid, unsigned int irq, int func_num, u8 sid, u8 pid), +TP_ARGS(apid, irq
[PATCH V3] spmi: add command tracepoints for SPMI
Add tracepoints to retrieve information about read, write and non-data commands. For performance measurement support tracepoints are added at the beginning and at the end of transfers. Following is a list showing the new tracepoint events. The cmd parameter here represents the opcode, SID, and full 16-bit address. spmi_write_begin: cmd and data buffer. spmi_write_end : cmd and return value. spmi_read_begin : cmd. spmi_read_end : cmd, return value and data buffer. spmi_cmd: cmd. The reason that cmd appears at both the beginning and at the end event is that SPMI drivers can request commands concurrently. cmd helps in matching the corresponding events. SPMI tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_read_begin: opc=56 sid=00 addr=0x ... spmi_read_end: opc=56 sid=00 addr=0x ret=0 len=02 buf=0x[01-40] ... spmi_write_begin: opc=48 sid=00 addr=0x len=3 buf=0x[ff-ff-ff] Suggested-by: Sagar Dharia sdha...@codeaurora.org Acked-by: Steven Rostedt rost...@goodmis.org Reviewed-by: Stephen Boyd sb...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- Changes since V2: - change back len type from size_t to u8. --- Changes since V1: - signed-off-by author moved to the end. - changes len type from u8 to size_t. --- drivers/spmi/spmi.c | 22 +++- include/trace/events/spmi.h | 135 2 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 include/trace/events/spmi.h diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 1d92f51..36fe010 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -21,6 +21,8 @@ #include linux/pm_runtime.h #include dt-bindings/spmi/spmi.h +#define CREATE_TRACE_POINTS +#include trace/events/spmi.h static DEFINE_IDA(ctrl_ida); @@ -95,28 +97,42 @@ EXPORT_SYMBOL_GPL(spmi_device_remove); static inline int spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid) { + int ret; + if (!ctrl || !ctrl-cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-cmd(ctrl, opcode, sid); + ret = ctrl-cmd(ctrl, opcode, sid); + trace_spmi_cmd(opcode, sid, ret); + return ret; } static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl-read_cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_begin(opcode, sid, addr); + ret = ctrl-read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_end(opcode, sid, addr, ret, len, buf); + return ret; } static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, const u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl-write_cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_begin(opcode, sid, addr, len, buf); + ret = ctrl-write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_end(opcode, sid, addr, ret); + return ret; } /** diff --git a/include/trace/events/spmi.h b/include/trace/events/spmi.h new file mode 100644 index 000..62f005e --- /dev/null +++ b/include/trace/events/spmi.h @@ -0,0 +1,135 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM spmi + +#if !defined(_TRACE_SPMI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SPMI_H + +#include linux/spmi.h +#include linux/tracepoint.h + +/* + * drivers/spmi/spmi.c + */ + +TRACE_EVENT(spmi_write_begin, + TP_PROTO(u8 opcode, u8 sid, u16 addr, u8 len, const u8 *buf), + TP_ARGS(opcode, sid, addr, len, buf), + + TP_STRUCT__entry( + __field ( u8, opcode) + __field ( u8, sid ) + __field ( u16,addr ) + __field ( u8, len ) + __dynamic_array ( u8, buf, len + 1 ) + ), + + TP_fast_assign( + __entry-opcode = opcode; + __entry-sid= sid; + __entry-addr = addr; + __entry-len= len + 1; + memcpy(__get_dynamic_array(buf), buf, len + 1); + ), + + TP_printk(opc=%d sid=%02d addr=0x%04x len=%d buf=0x[%*phD], + (int)__entry-opcode, (int)__entry-sid, + (int)__entry-addr, (int)__entry-len, + (int)__entry-len, __get_dynamic_array(buf)) +); + +TRACE_EVENT(spmi_write_end, + TP_PROTO(u8 opcode, u8 sid, u16 addr, int ret
[PATCH] spmi-pmic-arb: add irq tracepoints to the pmic-arb driver
The spmi-pmic-arb is also an interrupt controller. It gets a single aggregate irq and disseminates it to individual pmic-peripheral drivers. Each pmic-peripheral has a unique apid number, and can have multiple interrupt capable functions. The registered apid range shows the lowest and highest apid numbers of pmic-peripheral drivers which request irqs. Pid is the base address of that peripheral. For performance measurement, tracepoints are added at the beginning of the aggregate irq and at the end of the individual pmic-peripheral irqs. Following is a list showing the new tracepoint events: spmi_pmic_arb_aggregate_irq_start: aggregate irq number and registered apid range. spmi_pmic_arb_apid_irq_end: apid, irq, func_num, sid and pid. SPMI Interrupts tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi-pmic-arb/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_pmic_arb_aggregate_irq_start: irq=150 registered apid range=(3,189) ... spmi_pmic_arb_apid_irq_end: apid=3 irq=1 func_num=0 sid=0 pid=0x8 Suggested-by: Sagar Dharia sdha...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Signed-off-by: Ankit Gupta ankgu...@codeaurora.org --- drivers/spmi/spmi-pmic-arb.c | 15 ++--- include/trace/events/spmi-pmic-arb.h | 62 2 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 include/trace/events/spmi-pmic-arb.h diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 20559ab..342a71d 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -23,6 +23,9 @@ #include linux/slab.h #include linux/spmi.h +#define CREATE_TRACE_POINTS +#include trace/events/spmi-pmic-arb.h + /* PMIC Arbiter configuration registers */ #define PMIC_ARB_VERSION 0x #define PMIC_ARB_INT_EN0x0004 @@ -375,16 +378,17 @@ static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid) unsigned int irq; u32 status; int id; + u16 ppid = pa-apid_to_ppid[apid]; + u8 sid = (ppid 8) 0x0F; + u8 pid = ppid 0xFF; status = readl_relaxed(pa-intr + SPMI_PIC_IRQ_STATUS(apid)); while (status) { id = ffs(status) - 1; status = ~(1 id); - irq = irq_find_mapping(pa-domain, - pa-apid_to_ppid[apid] 16 -| id 8 -| apid); + irq = irq_find_mapping(pa-domain, ppid 16 | id 8 | apid); generic_handle_irq(irq); + trace_spmi_pmic_arb_apid_irq_end(apid, irq, id, sid, pid); } } @@ -399,7 +403,8 @@ static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc) int i, id; chained_irq_enter(chip, desc); - + trace_spmi_pmic_arb_aggregate_irq_start(irq, pa-min_apid, + pa-max_apid); for (i = first; i = last; ++i) { status = readl_relaxed(intr + SPMI_PIC_OWNER_ACC_STATUS(pa-ee, i)); diff --git a/include/trace/events/spmi-pmic-arb.h b/include/trace/events/spmi-pmic-arb.h new file mode 100644 index 000..6c4dbca --- /dev/null +++ b/include/trace/events/spmi-pmic-arb.h @@ -0,0 +1,62 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM spmi-pmic-arb + +#if !defined(_TRACE_SPMI_PMIC_ARB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SPMI_PMIC_ARB_H + +#include linux/spmi.h +#include linux/tracepoint.h + +/* + * drivers/spmi/spmi-pmic-arb.c + */ + +TRACE_EVENT(spmi_pmic_arb_aggregate_irq_start, + TP_PROTO(unsigned int irq, int first, int last), + TP_ARGS(irq, first, last), + + TP_STRUCT__entry( + __field ( unsigned int, irq ) + __field ( int,first ) + __field ( int,last ) + ), + + TP_fast_assign( + __entry-irq= irq; + __entry-first = first; + __entry-last = last; + ), + + TP_printk(irq=%d registered apid range=(%d,%d), + (int)__entry-irq, __entry-first, __entry-last) +); + +TRACE_EVENT(spmi_pmic_arb_apid_irq_end, + TP_PROTO(u8 apid, unsigned int irq, int func_num, u8 sid, u8 pid), + TP_ARGS(apid, irq, func_num, sid, pid), + + TP_STRUCT__entry( + __field ( u8, apid ) + __field ( unsigned int, irq ) + __field ( int, func_num ) + __field ( u8, sid ) + __field ( u8, pid ) + ), + + TP_fast_assign( + __entry-apid = apid; + __entry-irq = irq
Re: [PATCH] spmi: add command tracepoints for SPMI
On 05/20, Ankit Gupta wrote: On Tue, 19 May 2015 17:36:41 -0700 Stephen Boyd sb...@codeaurora.org wrote: On 05/18/15 14:51, Ankit Gupta wrote: + +TRACE_EVENT(spmi_read_end, +TP_PROTO(u8 opcode, u8 sid, u16 addr, int ret, u8 len, Should len be size_t instead of u8? It would at least match the implementation of spmi_controller::read_cmd(). Same comment for the write side. -Stephen I see no reason to spend to 4-8 bytes when spmi spec allows for maximum buffer size of 16. Do you suggest changing the API of read_cmd()? Is that a maximum buffer size of 16 bytes? I'd prefer consistency with the API that's being traced, that's all. Changing it to u8 to save a few bytes probably doesn't make any difference if the architecture passes function arguments in CPU registers which are 32 or 64 bits wide or if the function can be inlined enough by the compiler to where the len parameter is kept in a register. Thanks Stephen for your comments. Will change it to size_t. -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] spmi: add command tracepoints for SPMI
On 05/18/15 14:51, Ankit Gupta wrote: Add tracepoints to retrieve information about read, write and non-data commands. For performance measurement support tracepoints are added at the beginning and at the end of transfers. Following is a list showing the new tracepoint events. The cmd parameter here represents the opcode, SID, and full 16-bit address. spmi_write_begin: cmd and data buffer. spmi_write_end : cmd and return value. spmi_read_begin : cmd. spmi_read_end : cmd, return value and data buffer. spmi_cmd: cmd. The reason that cmd appears at both the beginning and at the end event is that SPMI drivers can request commands concurrently. cmd helps in matching the corresponding events. SPMI tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_read_begin: opc=56 sid=00 addr=0x ... spmi_read_end: opc=56 sid=00 addr=0x ret=0 len=02 buf=0x[01-40] ... spmi_write_begin: opc=48 sid=00 addr=0x len=3 buf=0x[ff-ff-ff] Signed-off-by: Ankit Gupta ankgu...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Suggested-by: Sagar Dharia sdha...@codeaurora.org --- Assuming you fix sign-off-chain: Reviewed-by: Stephen Boyd sb...@codeaurora.org Sorry, Missed your this email, will upload a new patch with just change of sign-off order. Thanks -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] spmi: add command tracepoints for SPMI
On Tue, 19 May 2015 17:36:41 -0700 Stephen Boyd sb...@codeaurora.org wrote: +Steven Rostedt On 05/18/15 14:51, Ankit Gupta wrote: Add tracepoints to retrieve information about read, write and non-data commands. For performance measurement support tracepoints are added at the beginning and at the end of transfers. Following is a list showing the new tracepoint events. The cmd parameter here represents the opcode, SID, and full 16-bit address. spmi_write_begin: cmd and data buffer. spmi_write_end : cmd and return value. spmi_read_begin : cmd. spmi_read_end : cmd, return value and data buffer. spmi_cmd: cmd. The reason that cmd appears at both the beginning and at the end event is that SPMI drivers can request commands concurrently. cmd helps in matching the corresponding events. SPMI tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_read_begin: opc=56 sid=00 addr=0x ... spmi_read_end: opc=56 sid=00 addr=0x ret=0 len=02 buf=0x[01-40] ... spmi_write_begin: opc=48 sid=00 addr=0x len=3 buf=0x[ff-ff-ff] Signed-off-by: Ankit Gupta ankgu...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Suggested-by: Sagar Dharia sdha...@codeaurora.org --- Your Signed-off-by should be last. Will change that. drivers/spmi/spmi.c | 22 ++- include/trace/events/spmi.h | 136 2 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 include/trace/events/spmi.h diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 1d92f51..36fe010 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -21,6 +21,8 @@ #include linux/pm_runtime.h #include dt-bindings/spmi/spmi.h +#define CREATE_TRACE_POINTS +#include trace/events/spmi.h static DEFINE_IDA(ctrl_ida); @@ -95,28 +97,42 @@ EXPORT_SYMBOL_GPL(spmi_device_remove); static inline int spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid) { + int ret; + if (!ctrl || !ctrl-cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-cmd(ctrl, opcode, sid); + ret = ctrl-cmd(ctrl, opcode, sid); + trace_spmi_cmd(opcode, sid, ret); + return ret; } static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl-read_cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_begin(opcode, sid, addr); + ret = ctrl-read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_end(opcode, sid, addr, ret, len, buf); + return ret; } static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, const u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl-write_cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_begin(opcode, sid, addr, len, buf); + ret = ctrl-write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_end(opcode, sid, addr, ret); + return ret; } /** diff --git a/include/trace/events/spmi.h b/include/trace/events/spmi.h new file mode 100644 index 000..241fd1e --- /dev/null +++ b/include/trace/events/spmi.h @@ -0,0 +1,136 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM spmi + +#if !defined(_TRACE_SPMI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SPMI_H + +#include linux/spmi.h +#include linux/tracepoint.h + +/* + * drivers/spmi/spmi.c + */ + +TRACE_EVENT(spmi_write_begin, + TP_PROTO(u8 opcode, u8 sid, u16 addr, u8 len, const u8 *buf), + TP_ARGS(opcode, sid, addr, len, buf), + + TP_STRUCT__entry( + __field ( u8, opcode) + __field ( u8, sid ) + __field ( u16,addr ) + __field ( u8, len ) + __dynamic_array ( u8, buf, len + 1 ) + ), + + TP_fast_assign( + __entry-opcode = opcode; + __entry-sid= sid; + __entry-addr = addr; + __entry-len= len + 1; + memcpy(__get_dynamic_array(buf), buf, len + 1); + ), + + TP_printk(opc=%d sid=%02d addr=0x%04x len=%d buf=0x[%*phD], + (int)__entry-opcode, (int)__entry-sid, + (int)__entry-addr, (int)__entry-len, + (int)__entry-len, __get_dynamic_array(buf)) +); + +TRACE_EVENT(spmi_write_end, + TP_PROTO(u8 opcode, u8 sid, u16 addr, int ret), + TP_ARGS(opcode, sid, addr, ret
[PATCH] spmi: add command tracepoints for SPMI
Add tracepoints to retrieve information about read, write and non-data commands. For performance measurement support tracepoints are added at the beginning and at the end of transfers. Following is a list showing the new tracepoint events. The cmd parameter here represents the opcode, SID, and full 16-bit address. spmi_write_begin: cmd and data buffer. spmi_write_end : cmd and return value. spmi_read_begin : cmd. spmi_read_end : cmd, return value and data buffer. spmi_cmd: cmd. The reason that cmd appears at both the beginning and at the end event is that SPMI drivers can request commands concurrently. cmd helps in matching the corresponding events. SPMI tracepoints can be enabled like: echo 1 /sys/kernel/debug/tracing/events/spmi/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... spmi_read_begin: opc=56 sid=00 addr=0x ... spmi_read_end: opc=56 sid=00 addr=0x ret=0 len=02 buf=0x[01-40] ... spmi_write_begin: opc=48 sid=00 addr=0x len=3 buf=0x[ff-ff-ff] Signed-off-by: Ankit Gupta ankgu...@codeaurora.org Signed-off-by: Gilad Avidov gavi...@codeaurora.org Suggested-by: Sagar Dharia sdha...@codeaurora.org --- drivers/spmi/spmi.c | 22 ++- include/trace/events/spmi.h | 136 2 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 include/trace/events/spmi.h diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 1d92f51..36fe010 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -21,6 +21,8 @@ #include linux/pm_runtime.h #include dt-bindings/spmi/spmi.h +#define CREATE_TRACE_POINTS +#include trace/events/spmi.h static DEFINE_IDA(ctrl_ida); @@ -95,28 +97,42 @@ EXPORT_SYMBOL_GPL(spmi_device_remove); static inline int spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid) { + int ret; + if (!ctrl || !ctrl-cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-cmd(ctrl, opcode, sid); + ret = ctrl-cmd(ctrl, opcode, sid); + trace_spmi_cmd(opcode, sid, ret); + return ret; } static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl-read_cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_begin(opcode, sid, addr); + ret = ctrl-read_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_read_end(opcode, sid, addr, ret, len, buf); + return ret; } static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, const u8 *buf, size_t len) { + int ret; + if (!ctrl || !ctrl-write_cmd || ctrl-dev.type != spmi_ctrl_type) return -EINVAL; - return ctrl-write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_begin(opcode, sid, addr, len, buf); + ret = ctrl-write_cmd(ctrl, opcode, sid, addr, buf, len); + trace_spmi_write_end(opcode, sid, addr, ret); + return ret; } /** diff --git a/include/trace/events/spmi.h b/include/trace/events/spmi.h new file mode 100644 index 000..241fd1e --- /dev/null +++ b/include/trace/events/spmi.h @@ -0,0 +1,136 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM spmi + +#if !defined(_TRACE_SPMI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SPMI_H + +#include linux/spmi.h +#include linux/tracepoint.h + +/* + * drivers/spmi/spmi.c + */ + +TRACE_EVENT(spmi_write_begin, + TP_PROTO(u8 opcode, u8 sid, u16 addr, u8 len, const u8 *buf), + TP_ARGS(opcode, sid, addr, len, buf), + + TP_STRUCT__entry( + __field ( u8, opcode) + __field ( u8, sid ) + __field ( u16,addr ) + __field ( u8, len ) + __dynamic_array ( u8, buf, len + 1 ) + ), + + TP_fast_assign( + __entry-opcode = opcode; + __entry-sid= sid; + __entry-addr = addr; + __entry-len= len + 1; + memcpy(__get_dynamic_array(buf), buf, len + 1); + ), + + TP_printk(opc=%d sid=%02d addr=0x%04x len=%d buf=0x[%*phD], + (int)__entry-opcode, (int)__entry-sid, + (int)__entry-addr, (int)__entry-len, + (int)__entry-len, __get_dynamic_array(buf)) +); + +TRACE_EVENT(spmi_write_end, + TP_PROTO(u8 opcode, u8 sid, u16 addr, int ret), + TP_ARGS(opcode, sid, addr, ret), + + TP_STRUCT__entry( + __field ( u8, opcode) + __field ( u8, sid ) + __field ( u16,addr