* [PATCH 1/2] i2c: Add message transfer tracepoints for I2C [ver #2]
@ 2014-03-06 13:35 David Howells
2014-03-06 13:36 ` [PATCH 2/2] i2c: Add message transfer tracepoints for SMBUS " David Howells
[not found] ` <20140306133559.29345.61422.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
0 siblings, 2 replies; 4+ messages in thread
From: David Howells @ 2014-03-06 13:35 UTC (permalink / raw)
To: wolfram; +Cc: khali, dhowells, linux-i2c, rostedt, linux-kernel
Add tracepoints into the I2C message transfer function to retrieve the message
sent or received. The following config options must be turned on to make use
of the facility:
CONFIG_FTRACE
CONFIG_ENABLE_DEFAULT_TRACERS
The I2C tracepoint can be enabled thusly:
echo 1 >/sys/kernel/debug/tracing/events/i2c/i2c_transfer/enable
and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace
that look like:
... i2c_write: i2c-5 #0 a=044 f=0000 l=2 [02-14]
... i2c_read: i2c-5 #1 a=044 f=0001 l=4
... i2c_reply: i2c-5 #1 a=044 f=0001 l=4 [33-00-00-00]
... i2c_result: i2c-5 n=2 ret=2
formatted as:
i2c-<adapter-nr>
#<message-array-index>
a=<addr>
f=<flags>
l=<datalen>
n=<message-array-size>
ret=<result>
[<data>]
The operation is done between the i2c_write/i2c_read lines and the i2c_reply
and i2c_result lines so that if the hardware hangs, the trace buffer can be
consulted to determine the problematic operation.
The adapters to be traced can be selected by something like:
echo adapter_nr==1 >/sys/kernel/debug/tracing/events/i2c/filter
These changes are based on code from Steven Rostedt.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
---
drivers/i2c/i2c-core.c | 37 +++++++++++
include/trace/events/i2c.h | 150 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 187 insertions(+)
create mode 100644 include/trace/events/i2c.h
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index d74c0b34248e..c8b97490461d 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -48,10 +48,13 @@
#include <linux/rwsem.h>
#include <linux/pm_runtime.h>
#include <linux/acpi.h>
+#include <linux/jump_label.h>
#include <asm/uaccess.h>
#include "i2c-core.h"
+#define CREATE_TRACE_POINTS
+#include <trace/events/i2c.h>
/* core_lock protects i2c_adapter_idr, and guarantees
that device detection, deletion of detected devices, and attach_adapter
@@ -62,6 +65,18 @@ static DEFINE_IDR(i2c_adapter_idr);
static struct device_type i2c_client_type;
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
+static struct static_key i2c_trace_msg = STATIC_KEY_INIT_FALSE;
+
+void i2c_transfer_trace_reg(void)
+{
+ static_key_slow_inc(&i2c_trace_msg);
+}
+
+void i2c_transfer_trace_unreg(void)
+{
+ static_key_slow_dec(&i2c_trace_msg);
+}
+
/* ------------------------------------------------------------------------- */
static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
@@ -1680,6 +1695,7 @@ static void __exit i2c_exit(void)
class_compat_unregister(i2c_adapter_compat_class);
#endif
bus_unregister(&i2c_bus_type);
+ tracepoint_synchronize_unregister();
}
/* We must initialize early, because some subsystems register i2c drivers
@@ -1710,6 +1726,19 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
unsigned long orig_jiffies;
int ret, try;
+ /* i2c_trace_msg gets enabled when tracepoint i2c_transfer gets
+ * enabled. This is an efficient way of keeping the for-loop from
+ * being executed when not needed.
+ */
+ if (static_key_false(&i2c_trace_msg)) {
+ int i;
+ for (i = 0; i < num; i++)
+ if (msgs[i].flags & I2C_M_RD)
+ trace_i2c_read(adap, &msgs[i], i);
+ else
+ trace_i2c_write(adap, &msgs[i], i);
+ }
+
/* Retry automatically on arbitration loss */
orig_jiffies = jiffies;
for (ret = 0, try = 0; try <= adap->retries; try++) {
@@ -1720,6 +1749,14 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
break;
}
+ if (static_key_false(&i2c_trace_msg)) {
+ int i;
+ for (i = 0; i < ret; i++)
+ if (msgs[i].flags & I2C_M_RD)
+ trace_i2c_reply(adap, &msgs[i], i);
+ trace_i2c_result(adap, i, ret);
+ }
+
return ret;
}
EXPORT_SYMBOL(__i2c_transfer);
diff --git a/include/trace/events/i2c.h b/include/trace/events/i2c.h
new file mode 100644
index 000000000000..4800207269a2
--- /dev/null
+++ b/include/trace/events/i2c.h
@@ -0,0 +1,150 @@
+/* I2C message transfer tracepoints
+ *
+ * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM i2c
+
+#if !defined(_TRACE_I2C_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_I2C_H
+
+#include <linux/i2c.h>
+#include <linux/tracepoint.h>
+
+/*
+ * drivers/i2c/i2c-core.c
+ */
+extern void i2c_transfer_trace_reg(void);
+extern void i2c_transfer_trace_unreg(void);
+
+/*
+ * __i2c_transfer() write request
+ */
+TRACE_EVENT_FN(i2c_write,
+ TP_PROTO(const struct i2c_adapter *adap, const struct i2c_msg *msg,
+ int num),
+ TP_ARGS(adap, msg, num),
+ TP_STRUCT__entry(
+ __field(int, adapter_nr )
+ __field(__u16, msg_nr )
+ __field(__u16, addr )
+ __field(__u16, flags )
+ __field(__u16, len )
+ __dynamic_array(__u8, buf, msg->len) ),
+ TP_fast_assign(
+ __entry->adapter_nr = adap->nr;
+ __entry->msg_nr = num;
+ __entry->addr = msg->addr;
+ __entry->flags = msg->flags;
+ __entry->len = msg->len;
+ memcpy(__get_dynamic_array(buf), msg->buf, msg->len);
+ ),
+ TP_printk("i2c-%d #%u a=%03x f=%04x l=%u [%*phD]",
+ __entry->adapter_nr,
+ __entry->msg_nr,
+ __entry->addr,
+ __entry->flags,
+ __entry->len,
+ __entry->len, __get_dynamic_array(buf)
+ ),
+ i2c_transfer_trace_reg,
+ i2c_transfer_trace_unreg);
+
+/*
+ * __i2c_transfer() read request
+ */
+TRACE_EVENT_FN(i2c_read,
+ TP_PROTO(const struct i2c_adapter *adap, const struct i2c_msg *msg,
+ int num),
+ TP_ARGS(adap, msg, num),
+ TP_STRUCT__entry(
+ __field(int, adapter_nr )
+ __field(__u16, msg_nr )
+ __field(__u16, addr )
+ __field(__u16, flags )
+ __field(__u16, len )
+ ),
+ TP_fast_assign(
+ __entry->adapter_nr = adap->nr;
+ __entry->msg_nr = num;
+ __entry->addr = msg->addr;
+ __entry->flags = msg->flags;
+ __entry->len = msg->len;
+ ),
+ TP_printk("i2c-%d #%u a=%03x f=%04x l=%u",
+ __entry->adapter_nr,
+ __entry->msg_nr,
+ __entry->addr,
+ __entry->flags,
+ __entry->len
+ ),
+ i2c_transfer_trace_reg,
+ i2c_transfer_trace_unreg);
+
+/*
+ * __i2c_transfer() read reply
+ */
+TRACE_EVENT_FN(i2c_reply,
+ TP_PROTO(const struct i2c_adapter *adap, const struct i2c_msg *msg,
+ int num),
+ TP_ARGS(adap, msg, num),
+ TP_STRUCT__entry(
+ __field(int, adapter_nr )
+ __field(__u16, msg_nr )
+ __field(__u16, addr )
+ __field(__u16, flags )
+ __field(__u16, len )
+ __dynamic_array(__u8, buf, msg->len) ),
+ TP_fast_assign(
+ __entry->adapter_nr = adap->nr;
+ __entry->msg_nr = num;
+ __entry->addr = msg->addr;
+ __entry->flags = msg->flags;
+ __entry->len = msg->len;
+ memcpy(__get_dynamic_array(buf), msg->buf, msg->len);
+ ),
+ TP_printk("i2c-%d #%u a=%03x f=%04x l=%u [%*phD]",
+ __entry->adapter_nr,
+ __entry->msg_nr,
+ __entry->addr,
+ __entry->flags,
+ __entry->len,
+ __entry->len, __get_dynamic_array(buf)
+ ),
+ i2c_transfer_trace_reg,
+ i2c_transfer_trace_unreg);
+
+/*
+ * __i2c_transfer() result
+ */
+TRACE_EVENT_FN(i2c_result,
+ TP_PROTO(const struct i2c_adapter *adap, int num, int ret),
+ TP_ARGS(adap, num, ret),
+ TP_STRUCT__entry(
+ __field(int, adapter_nr )
+ __field(__u16, nr_msgs )
+ __field(__s16, ret )
+ ),
+ TP_fast_assign(
+ __entry->adapter_nr = adap->nr;
+ __entry->nr_msgs = num;
+ __entry->ret = ret;
+ ),
+ TP_printk("i2c-%d n=%u ret=%d",
+ __entry->adapter_nr,
+ __entry->nr_msgs,
+ __entry->ret
+ ),
+ i2c_transfer_trace_reg,
+ i2c_transfer_trace_unreg);
+
+#endif /* _TRACE_I2C_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/2] i2c: Add message transfer tracepoints for SMBUS [ver #2] 2014-03-06 13:35 [PATCH 1/2] i2c: Add message transfer tracepoints for I2C [ver #2] David Howells @ 2014-03-06 13:36 ` David Howells [not found] ` <20140306133606.29345.97103.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org> [not found] ` <20140306133559.29345.61422.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org> 1 sibling, 1 reply; 4+ messages in thread From: David Howells @ 2014-03-06 13:36 UTC (permalink / raw) To: wolfram; +Cc: khali, dhowells, linux-i2c, rostedt, linux-kernel The SMBUS tracepoints can be enabled thusly: echo 1 >/sys/kernel/debug/tracing/events/i2c/enable and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace that look like: ... smbus_read: i2c-0 a=051 f=0000 c=fa BYTE_DATA ... smbus_reply: i2c-0 a=051 f=0000 c=fa BYTE_DATA l=1 [39] ... smbus_result: i2c-0 a=051 f=0000 c=fa BYTE_DATA rd res=0 formatted as: i2c-<adapter-nr> a=<addr> f=<flags> c=<command> <protocol-name> <rd|wr> res=<result> l=<data-len> [<data-block>] The adapters to be traced can be selected by something like: echo adapter_nr==1 >/sys/kernel/debug/tracing/events/i2c/filter Note that this shares the same filter and enablement as i2c. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Steven Rostedt <rostedt@goodmis.org> --- drivers/i2c/i2c-core.c | 23 ++++- include/trace/events/i2c.h | 224 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 243 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index c8b97490461d..619910632d26 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -2552,6 +2552,14 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, int try; s32 res; + /* If enabled, the following two tracepoints are conditional on + * read_write and protocol. + */ + trace_smbus_write(adapter, addr, flags, read_write, + command, protocol, data); + trace_smbus_read(adapter, addr, flags, read_write, + command, protocol); + flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB; if (adapter->algo->smbus_xfer) { @@ -2572,15 +2580,24 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, i2c_unlock_adapter(adapter); if (res != -EOPNOTSUPP || !adapter->algo->master_xfer) - return res; + goto trace; /* * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't * implement native support for the SMBus operation. */ } - return i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, - command, protocol, data); + res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, + command, protocol, data); + +trace: + /* If enabled, the reply tracepoint is conditional on read_write. */ + trace_smbus_reply(adapter, addr, flags, read_write, + command, protocol, data); + trace_smbus_result(adapter, addr, flags, read_write, + command, protocol, res); + + return res; } EXPORT_SYMBOL(i2c_smbus_xfer); diff --git a/include/trace/events/i2c.h b/include/trace/events/i2c.h index 4800207269a2..fe17187df65d 100644 --- a/include/trace/events/i2c.h +++ b/include/trace/events/i2c.h @@ -1,4 +1,4 @@ -/* I2C message transfer tracepoints +/* I2C and SMBUS message transfer tracepoints * * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) @@ -144,6 +144,228 @@ TRACE_EVENT_FN(i2c_result, i2c_transfer_trace_reg, i2c_transfer_trace_unreg); +/* + * i2c_smbus_xfer() write data or procedure call request + */ +TRACE_EVENT_CONDITION(smbus_write, + TP_PROTO(const struct i2c_adapter *adap, + u16 addr, unsigned short flags, + char read_write, u8 command, int protocol, + const union i2c_smbus_data *data), + TP_ARGS(adap, addr, flags, read_write, command, protocol, data), + TP_CONDITION(read_write == I2C_SMBUS_WRITE || + protocol == I2C_SMBUS_PROC_CALL || + protocol == I2C_SMBUS_BLOCK_PROC_CALL), + TP_STRUCT__entry( + __field(int, adapter_nr ) + __field(__u16, addr ) + __field(__u16, flags ) + __field(__u8, command ) + __field(__u8, len ) + __field(__u32, protocol ) + __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ), + TP_fast_assign( + __entry->adapter_nr = adap->nr; + __entry->addr = addr; + __entry->flags = flags; + __entry->command = command; + __entry->protocol = protocol; + + switch (protocol) { + case I2C_SMBUS_BYTE_DATA: + __entry->len = 1; + goto copy; + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_PROC_CALL: + __entry->len = 2; + goto copy; + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_BLOCK_PROC_CALL: + case I2C_SMBUS_I2C_BLOCK_DATA: + __entry->len = data->block[0] + 1; + copy: + memcpy(__entry->buf, data->block, __entry->len); + break; + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_I2C_BLOCK_BROKEN: + default: + __entry->len = 0; + } + ), + TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]", + __entry->adapter_nr, + __entry->addr, + __entry->flags, + __entry->command, + __print_symbolic(__entry->protocol, + { I2C_SMBUS_QUICK, "QUICK" }, + { I2C_SMBUS_BYTE, "BYTE" }, + { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, + { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, + { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, + { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, + { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, + { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, + { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }), + __entry->len, + __entry->len, __entry->buf + )); + +/* + * i2c_smbus_xfer() read data request + */ +TRACE_EVENT_CONDITION(smbus_read, + TP_PROTO(const struct i2c_adapter *adap, + u16 addr, unsigned short flags, + char read_write, u8 command, int protocol), + TP_ARGS(adap, addr, flags, read_write, command, protocol), + TP_CONDITION(!(read_write == I2C_SMBUS_WRITE || + protocol == I2C_SMBUS_PROC_CALL || + protocol == I2C_SMBUS_BLOCK_PROC_CALL)), + TP_STRUCT__entry( + __field(int, adapter_nr ) + __field(__u16, flags ) + __field(__u16, addr ) + __field(__u8, command ) + __field(__u32, protocol ) + __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ), + TP_fast_assign( + __entry->adapter_nr = adap->nr; + __entry->addr = addr; + __entry->flags = flags; + __entry->command = command; + __entry->protocol = protocol; + ), + TP_printk("i2c-%d a=%03x f=%04x c=%x %s", + __entry->adapter_nr, + __entry->addr, + __entry->flags, + __entry->command, + __print_symbolic(__entry->protocol, + { I2C_SMBUS_QUICK, "QUICK" }, + { I2C_SMBUS_BYTE, "BYTE" }, + { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, + { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, + { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, + { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, + { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, + { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, + { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }) + )); + +/* + * i2c_smbus_xfer() read data or procedure call reply + */ +TRACE_EVENT_CONDITION(smbus_reply, + TP_PROTO(const struct i2c_adapter *adap, + u16 addr, unsigned short flags, + char read_write, u8 command, int protocol, + const union i2c_smbus_data *data), + TP_ARGS(adap, addr, flags, read_write, command, protocol, data), + TP_CONDITION(read_write == I2C_SMBUS_READ), + TP_STRUCT__entry( + __field(int, adapter_nr ) + __field(__u16, addr ) + __field(__u16, flags ) + __field(__u8, command ) + __field(__u8, len ) + __field(__u32, protocol ) + __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ), + TP_fast_assign( + __entry->adapter_nr = adap->nr; + __entry->addr = addr; + __entry->flags = flags; + __entry->command = command; + __entry->protocol = protocol; + + switch (protocol) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + __entry->len = 1; + goto copy; + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_PROC_CALL: + __entry->len = 2; + goto copy; + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_BLOCK_PROC_CALL: + case I2C_SMBUS_I2C_BLOCK_DATA: + __entry->len = data->block[0] + 1; + copy: + memcpy(__entry->buf, data->block, __entry->len); + break; + case I2C_SMBUS_QUICK: + case I2C_SMBUS_I2C_BLOCK_BROKEN: + default: + __entry->len = 0; + } + ), + TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]", + __entry->adapter_nr, + __entry->addr, + __entry->flags, + __entry->command, + __print_symbolic(__entry->protocol, + { I2C_SMBUS_QUICK, "QUICK" }, + { I2C_SMBUS_BYTE, "BYTE" }, + { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, + { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, + { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, + { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, + { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, + { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, + { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }), + __entry->len, + __entry->len, __entry->buf + )); + +/* + * i2c_smbus_xfer() result + */ +TRACE_EVENT(smbus_result, + TP_PROTO(const struct i2c_adapter *adap, + u16 addr, unsigned short flags, + char read_write, u8 command, int protocol, + int res), + TP_ARGS(adap, addr, flags, read_write, command, protocol, res), + TP_STRUCT__entry( + __field(int, adapter_nr ) + __field(__u16, addr ) + __field(__u16, flags ) + __field(__u8, read_write ) + __field(__u8, command ) + __field(__s16, res ) + __field(__u32, protocol ) + ), + TP_fast_assign( + __entry->adapter_nr = adap->nr; + __entry->addr = addr; + __entry->flags = flags; + __entry->read_write = read_write; + __entry->command = command; + __entry->protocol = protocol; + __entry->res = res; + ), + TP_printk("i2c-%d a=%03x f=%04x c=%x %s %s res=%d", + __entry->adapter_nr, + __entry->addr, + __entry->flags, + __entry->command, + __print_symbolic(__entry->protocol, + { I2C_SMBUS_QUICK, "QUICK" }, + { I2C_SMBUS_BYTE, "BYTE" }, + { I2C_SMBUS_BYTE_DATA, "BYTE_DATA" }, + { I2C_SMBUS_WORD_DATA, "WORD_DATA" }, + { I2C_SMBUS_PROC_CALL, "PROC_CALL" }, + { I2C_SMBUS_BLOCK_DATA, "BLOCK_DATA" }, + { I2C_SMBUS_I2C_BLOCK_BROKEN, "I2C_BLOCK_BROKEN" }, + { I2C_SMBUS_BLOCK_PROC_CALL, "BLOCK_PROC_CALL" }, + { I2C_SMBUS_I2C_BLOCK_DATA, "I2C_BLOCK_DATA" }), + __entry->read_write == I2C_SMBUS_WRITE ? "wr" : "rd", + __entry->res + )); + #endif /* _TRACE_I2C_H */ /* This part must be outside protection */ ^ permalink raw reply related [flat|nested] 4+ messages in thread
[parent not found: <20140306133606.29345.97103.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>]
* Re: [PATCH 2/2] i2c: Add message transfer tracepoints for SMBUS [ver #2] [not found] ` <20140306133606.29345.97103.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org> @ 2014-03-13 21:15 ` Wolfram Sang 0 siblings, 0 replies; 4+ messages in thread From: Wolfram Sang @ 2014-03-13 21:15 UTC (permalink / raw) To: David Howells Cc: wolfram-z923LK4zBo2bacvFa/9K2g, khali-PUYAD+kWke1g9hUCZPvPmw, linux-i2c-u79uwXL29TY76Z2rM5mHXA, rostedt-nx8X9YLhiw1AfugRpC6u6w, linux-kernel-u79uwXL29TY76Z2rM5mHXA [-- Attachment #1: Type: text/plain, Size: 1074 bytes --] On Thu, Mar 06, 2014 at 01:36:06PM +0000, David Howells wrote: > The SMBUS tracepoints can be enabled thusly: > > echo 1 >/sys/kernel/debug/tracing/events/i2c/enable > > and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace > that look like: > > ... smbus_read: i2c-0 a=051 f=0000 c=fa BYTE_DATA > ... smbus_reply: i2c-0 a=051 f=0000 c=fa BYTE_DATA l=1 [39] > ... smbus_result: i2c-0 a=051 f=0000 c=fa BYTE_DATA rd res=0 > > formatted as: > > i2c-<adapter-nr> > a=<addr> > f=<flags> > c=<command> > <protocol-name> > <rd|wr> > res=<result> > l=<data-len> > [<data-block>] > > > The adapters to be traced can be selected by something like: > > echo adapter_nr==1 >/sys/kernel/debug/tracing/events/i2c/filter > > Note that this shares the same filter and enablement as i2c. > > Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> > Reviewed-by: Steven Rostedt <rostedt-nx8X9YLhiw1AfugRpC6u6w@public.gmane.org> Applied to for-next, thanks! [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <20140306133559.29345.61422.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>]
* Re: [PATCH 1/2] i2c: Add message transfer tracepoints for I2C [ver #2] [not found] ` <20140306133559.29345.61422.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org> @ 2014-03-13 21:15 ` Wolfram Sang 0 siblings, 0 replies; 4+ messages in thread From: Wolfram Sang @ 2014-03-13 21:15 UTC (permalink / raw) To: David Howells Cc: wolfram-z923LK4zBo2bacvFa/9K2g, khali-PUYAD+kWke1g9hUCZPvPmw, linux-i2c-u79uwXL29TY76Z2rM5mHXA, rostedt-nx8X9YLhiw1AfugRpC6u6w, linux-kernel-u79uwXL29TY76Z2rM5mHXA [-- Attachment #1: Type: text/plain, Size: 1598 bytes --] On Thu, Mar 06, 2014 at 01:35:59PM +0000, David Howells wrote: > Add tracepoints into the I2C message transfer function to retrieve the message > sent or received. The following config options must be turned on to make use > of the facility: > > CONFIG_FTRACE > CONFIG_ENABLE_DEFAULT_TRACERS > > The I2C tracepoint can be enabled thusly: > > echo 1 >/sys/kernel/debug/tracing/events/i2c/i2c_transfer/enable > > and will dump messages that can be viewed in /sys/kernel/debug/tracing/trace > that look like: > > ... i2c_write: i2c-5 #0 a=044 f=0000 l=2 [02-14] > ... i2c_read: i2c-5 #1 a=044 f=0001 l=4 > ... i2c_reply: i2c-5 #1 a=044 f=0001 l=4 [33-00-00-00] > ... i2c_result: i2c-5 n=2 ret=2 > > formatted as: > > i2c-<adapter-nr> > #<message-array-index> > a=<addr> > f=<flags> > l=<datalen> > n=<message-array-size> > ret=<result> > [<data>] > > The operation is done between the i2c_write/i2c_read lines and the i2c_reply > and i2c_result lines so that if the hardware hangs, the trace buffer can be > consulted to determine the problematic operation. > > The adapters to be traced can be selected by something like: > > echo adapter_nr==1 >/sys/kernel/debug/tracing/events/i2c/filter > > These changes are based on code from Steven Rostedt. > > Signed-off-by: Steven Rostedt <rostedt-nx8X9YLhiw1AfugRpC6u6w@public.gmane.org> > Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> > Reviewed-by: Steven Rostedt <rostedt-nx8X9YLhiw1AfugRpC6u6w@public.gmane.org> Applied to for-next, thanks! [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-03-13 21:15 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-06 13:35 [PATCH 1/2] i2c: Add message transfer tracepoints for I2C [ver #2] David Howells
2014-03-06 13:36 ` [PATCH 2/2] i2c: Add message transfer tracepoints for SMBUS " David Howells
[not found] ` <20140306133606.29345.97103.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2014-03-13 21:15 ` Wolfram Sang
[not found] ` <20140306133559.29345.61422.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2014-03-13 21:15 ` [PATCH 1/2] i2c: Add message transfer tracepoints for I2C " Wolfram Sang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).