2014-01-30 16:18:06

by Adrien Vergé

[permalink] [raw]
Subject: [PATCH V3 0/5] ARM CoreSight: ETM: Fix a vmalloc/vfree failure and enhance tracing control

Hi Russell,

Different ARM users have shown their interest in this patch, so I made
a third version that is compatible with PID namespaces.

Mainly:
- It fixes a "vmalloc: allocation failure: 0 bytes" when reading an
ETB buffer that is empty.
- It extends current support of CoreSight ETM, that is currently
very limited.

ETM is a dedicated hardware that provides program tracing, a
cycle-precise and low-overhead solution that software tools such as
'perf record' cannot provide.

Usage of ETM tracing facility is presently limited to start and stop
tracing. This set of patches enables management of address combinations
and PIDs that trigger tracing, thus allowing to trace specific
functions and processes. ETM management was done via sysfs entries
(trace_info, trace_running...), this code adds trace_addrrange and
trace_pid to let the user read/write custom values.

Changes in V2:
- Fix a vmalloc/vfree failure when ETB is empty
- Use device attributes rather than raw kobjects
- Make PID_IN_CONTEXTIDR incompatible with PID_NS in Kconfig
- Use pid_t instead of long

Changes in V3:
- Support tracing processes by their PID in PID namespaces
- Reset PID_IN_CONTEXTIDR and PID_NS independent

This series of patches applies to v3.13.

Adrien Vergé (5):
ARM CoreSight: ETM: Fix a memory allocation failure
ARM CoreSight: ETM: Use device attributes
ARM CoreSight: ETM: Rename 'comparator' to 'address comparator'
ARM CoreSight: ETM: Add address control support
ARM CoreSight: ETM: Add PID control support

arch/arm/include/asm/hardware/coresight.h | 9 +-
arch/arm/kernel/etm.c | 257 ++++++++++++++++++++++++------
2 files changed, 216 insertions(+), 50 deletions(-)

--
1.8.5.3


2014-01-30 16:11:51

by Adrien Vergé

[permalink] [raw]
Subject: [PATCH V3 1/5] ARM CoreSight: ETM: Fix a memory allocation failure

When an application reads the ETB buffer too often, it can be empty.
In this case, it results in a "vmalloc: allocation failure: 0 bytes",
a backtrace in dmesg and a vfree on an incorrect address.

This patch allocates and frees the trace buffer only when necessary.

Signed-off-by: Adrien Vergé <[email protected]>
---
arch/arm/kernel/etm.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 8ff0ecd..5192693 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -275,7 +275,7 @@ static ssize_t etb_read(struct file *file, char __user *data,
long length;
struct tracectx *t = file->private_data;
u32 first = 0;
- u32 *buf;
+ u32 *buf = NULL;

mutex_lock(&t->mutex);

@@ -293,12 +293,14 @@ static ssize_t etb_read(struct file *file, char __user *data,
etb_writel(t, first, ETBR_READADDR);

length = min(total * 4, (int)len);
- buf = vmalloc(length);
+ if (length != 0)
+ buf = vmalloc(length);

dev_dbg(t->dev, "ETB buffer length: %d\n", total);
dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
- for (i = 0; i < length / 4; i++)
- buf[i] = etb_readl(t, ETBR_READMEM);
+ if (buf)
+ for (i = 0; i < length / 4; i++)
+ buf[i] = etb_readl(t, ETBR_READMEM);

/* the only way to deassert overflow bit in ETB status is this */
etb_writel(t, 1, ETBR_CTRL);
@@ -311,7 +313,8 @@ static ssize_t etb_read(struct file *file, char __user *data,
etb_lock(t);

length -= copy_to_user(data, buf, length);
- vfree(buf);
+ if (buf)
+ vfree(buf);

out:
mutex_unlock(&t->mutex);
--
1.8.5.3

2014-01-30 16:11:56

by Adrien Vergé

[permalink] [raw]
Subject: [PATCH V3 3/5] ARM CoreSight: ETM: Rename 'comparator' to 'address comparator'

Since there are different types of comparators, and other kinds will
be used (such as Context ID comparators), rename them properly.

Signed-off-by: Adrien Vergé <[email protected]>
---
arch/arm/include/asm/hardware/coresight.h | 4 ++--
arch/arm/kernel/etm.c | 19 ++++++++++---------
2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index ad774f3..8c50cf6 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -95,8 +95,8 @@
#define ETMAAT_NSONLY (1 << 10)
#define ETMAAT_SONLY (2 << 10)

-#define ETMR_COMP_VAL(x) (0x40 + (x) * 4)
-#define ETMR_COMP_ACC_TYPE(x) (0x80 + (x) * 4)
+#define ETMR_ADDRCOMP_VAL(x) (0x40 + (x) * 4)
+#define ETMR_ADDRCOMP_ACC_TYPE(x) (0x80 + (x) * 4)

/* ETM status register, "ETM Architecture", 3.3.2 */
#define ETMR_STATUS (0x10)
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 7a3ee66..b3e6713 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -39,7 +39,7 @@ struct tracectx {
void __iomem *etb_regs;
void __iomem *etm_regs;
unsigned long flags;
- int ncmppairs;
+ int naddrcmppairs;
int etm_portsz;
struct device *dev;
struct clk *emu_clk;
@@ -59,7 +59,7 @@ static int etm_setup_address_range(struct tracectx *t, int n,
u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
ETMAAT_NOVALCMP;

- if (n < 1 || n > t->ncmppairs)
+ if (n < 1 || n > t->naddrcmppairs)
return -EINVAL;

/* comparators and ranges are numbered starting with 1 as opposed
@@ -72,12 +72,12 @@ static int etm_setup_address_range(struct tracectx *t, int n,
flags |= ETMAAT_IEXEC;

/* first comparator for the range */
- etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
- etm_writel(t, start, ETMR_COMP_VAL(n * 2));
+ etm_writel(t, flags, ETMR_ADDRCOMP_ACC_TYPE(n * 2));
+ etm_writel(t, start, ETMR_ADDRCOMP_VAL(n * 2));

/* second comparator is right next to it */
- etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
- etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
+ etm_writel(t, flags, ETMR_ADDRCOMP_ACC_TYPE(n * 2 + 1));
+ etm_writel(t, end, ETMR_ADDRCOMP_VAL(n * 2 + 1));

flags = exclude ? ETMTE_INCLEXCL : 0;
etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
@@ -478,7 +478,8 @@ static ssize_t trace_info_show(struct device *dev,
etm_st = etm_readl(&tracer, ETMR_STATUS);
etm_lock(&tracer);

- return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
+ return sprintf(buf, "Trace buffer len: %d\n"
+ "Addr comparator pairs: %d\n"
"ETBR_WRITEADDR:\t%08x\n"
"ETBR_READADDR:\t%08x\n"
"ETBR_STATUS:\t%08x\n"
@@ -486,7 +487,7 @@ static ssize_t trace_info_show(struct device *dev,
"ETMR_CTRL:\t%08x\n"
"ETMR_STATUS:\t%08x\n",
datalen,
- tracer.ncmppairs,
+ tracer.naddrcmppairs,
etb_wa,
etb_ra,
etb_st,
@@ -562,7 +563,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
/* dummy first read */
(void)etm_readl(&tracer, ETMMR_OSSRR);

- t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
+ t->naddrcmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
etm_writel(t, 0x440, ETMR_CTRL);
etm_lock(t);

--
1.8.5.3

2014-01-30 16:11:59

by Adrien Vergé

[permalink] [raw]
Subject: [PATCH V3 4/5] ARM CoreSight: ETM: Add address control support

In the same manner as for enabling tracing, an entry is created
in sysfs to set the address range that triggers tracing.

Signed-off-by: Adrien Vergé <[email protected]>
---
arch/arm/kernel/etm.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 49 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index b3e6713..fa42e32 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -44,6 +44,8 @@ struct tracectx {
struct device *dev;
struct clk *emu_clk;
struct mutex mutex;
+ unsigned long addrrange_start;
+ unsigned long addrrange_end;
};

static struct tracectx tracer;
@@ -53,6 +55,13 @@ static inline bool trace_isrunning(struct tracectx *t)
return !!(t->flags & TRACER_RUNNING);
}

+/*
+ * Setups ETM to trace only when:
+ * - address between start and end
+ * or address not between start and end (if exclude)
+ * - trace executed instructions
+ * or trace loads and stores (if data)
+ */
static int etm_setup_address_range(struct tracectx *t, int n,
unsigned long start, unsigned long end, int exclude, int data)
{
@@ -115,8 +124,8 @@ static int trace_start(struct tracectx *t)
return -EFAULT;
}

- etm_setup_address_range(t, 1, (unsigned long)_stext,
- (unsigned long)_etext, 0, 0);
+ etm_setup_address_range(t, 1, t->addrrange_start, t->addrrange_end,
+ 0, 0);
etm_writel(t, 0, ETMR_TRACEENCTRL2);
etm_writel(t, 0, ETMR_TRACESSCTRL);
etm_writel(t, 0x6f, ETMR_TRACEENEVT);
@@ -530,6 +539,36 @@ static ssize_t trace_mode_store(struct device *dev,

DEVICE_ATTR(trace_mode, S_IRUGO|S_IWUSR, trace_mode_show, trace_mode_store);

+static ssize_t trace_addrrange_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%08lx - %08lx\n", tracer.addrrange_start,
+ tracer.addrrange_end);
+}
+
+static ssize_t trace_addrrange_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned long start, end;
+
+ if (tracer.flags & TRACER_RUNNING)
+ return -EBUSY;
+
+ if (sscanf(buf, "%08lx - %08lx", &start, &end) != 2)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ tracer.addrrange_start = start;
+ tracer.addrrange_end = end;
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+DEVICE_ATTR(trace_addrrange, S_IRUGO|S_IWUSR,
+ trace_addrrange_show, trace_addrrange_store);
+
static int etm_probe(struct amba_device *dev, const struct amba_id *id)
{
struct tracectx *t = &tracer;
@@ -557,6 +596,8 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
t->dev = &dev->dev;
t->flags = TRACER_CYCLE_ACC;
t->etm_portsz = 1;
+ t->addrrange_start = (unsigned long) _stext;
+ t->addrrange_end = (unsigned long) _etext;

etm_unlock(t);
(void)etm_readl(t, ETMMR_PDSR);
@@ -571,7 +612,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
if (ret)
goto out_unmap;

- /* failing to create any of these two is not fatal */
+ /* failing to create any of these three is not fatal */
ret = device_create_file(&dev->dev, &dev_attr_trace_info);
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
@@ -580,6 +621,10 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");

+ ret = device_create_file(&dev->dev, &dev_attr_trace_addrrange);
+ if (ret)
+ dev_dbg(&dev->dev, "Failed to create trace_addrrange in sysfs\n");
+
dev_dbg(t->dev, "ETM AMBA driver initialized.\n");

out:
@@ -609,6 +654,7 @@ static int etm_remove(struct amba_device *dev)
device_remove_file(&dev->dev, &dev_attr_trace_running);
device_remove_file(&dev->dev, &dev_attr_trace_info);
device_remove_file(&dev->dev, &dev_attr_trace_mode);
+ device_remove_file(&dev->dev, &dev_attr_trace_addrrange);

return 0;
}
--
1.8.5.3

2014-01-30 16:12:10

by Adrien Vergé

[permalink] [raw]
Subject: [PATCH V3 5/5] ARM CoreSight: ETM: Add PID control support

In the same manner as for enabling tracing, an entry is created in
sysfs to set the PID that triggers tracing. This change is effective
only if CONFIG_PID_IN_CONTEXTIDR is set.

When using PID namespaces, the virtual PID given by the user is
converted to the globally unique ID (task_pid_nr) that is present
in the Context ID register.

Signed-off-by: Adrien Vergé <[email protected]>
---
arch/arm/include/asm/hardware/coresight.h | 5 ++
arch/arm/kernel/etm.c | 131 ++++++++++++++++++++++++++++--
2 files changed, 129 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index 8c50cf6..2051af0 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -98,6 +98,11 @@
#define ETMR_ADDRCOMP_VAL(x) (0x40 + (x) * 4)
#define ETMR_ADDRCOMP_ACC_TYPE(x) (0x80 + (x) * 4)

+#ifdef CONFIG_PID_IN_CONTEXTIDR
+#define ETMR_CTXIDCOMP_VAL(x) (0x1b0 + (x) * 4)
+#define ETMR_CTXIDCOMP_MASK (0x1bc)
+#endif
+
/* ETM status register, "ETM Architecture", 3.3.2 */
#define ETMR_STATUS (0x10)
#define ETMST_OVERFLOW BIT(0)
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index fa42e32..e8db9e2 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -25,6 +25,7 @@
#include <linux/vmalloc.h>
#include <linux/mutex.h>
#include <linux/module.h>
+#include <linux/sched.h>
#include <asm/hardware/coresight.h>
#include <asm/sections.h>

@@ -40,12 +41,17 @@ struct tracectx {
void __iomem *etm_regs;
unsigned long flags;
int naddrcmppairs;
+ int nctxidcmp;
int etm_portsz;
struct device *dev;
struct clk *emu_clk;
struct mutex mutex;
unsigned long addrrange_start;
unsigned long addrrange_end;
+ pid_t pid; /* globally unique PID */
+#ifdef CONFIG_PID_NS
+ pid_t vpid; /* virtual PID as seen in namespace */
+#endif
};

static struct tracectx tracer;
@@ -55,18 +61,42 @@ static inline bool trace_isrunning(struct tracectx *t)
return !!(t->flags & TRACER_RUNNING);
}

+#if defined(CONFIG_PID_IN_CONTEXTIDR) && defined(CONFIG_PID_NS)
+/*
+ * Returns the globally unique ID of a task referenced
+ * with its virtual namespace PID
+ */
+static inline pid_t pid_vnr_to_pid_nr(pid_t vpid)
+{
+ struct task_struct *task = find_task_by_vpid(vpid);
+
+ if (!task) {
+ printk(KERN_WARNING "CoreSight ETM: cannot track PID %d: "
+ "no such PID in current namespace\n",
+ vpid);
+ return -EINVAL;
+ }
+
+ return task_pid_nr(task);
+}
+#endif
+
/*
* Setups ETM to trace only when:
* - address between start and end
* or address not between start and end (if exclude)
+ * - in user-space when process id equals pid,
+ * in kernel-space (if pid == 0),
+ * always (if pid == -1)
* - trace executed instructions
* or trace loads and stores (if data)
*/
-static int etm_setup_address_range(struct tracectx *t, int n,
- unsigned long start, unsigned long end, int exclude, int data)
+static int etm_setup(struct tracectx *t, int n,
+ unsigned long start, unsigned long end, int exclude,
+ pid_t pid,
+ int data)
{
- u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
- ETMAAT_NOVALCMP;
+ u32 flags = ETMAAT_ARM | ETMAAT_NSONLY | ETMAAT_NOVALCMP;

if (n < 1 || n > t->naddrcmppairs)
return -EINVAL;
@@ -75,6 +105,23 @@ static int etm_setup_address_range(struct tracectx *t, int n,
* to bits in a word */
n--;

+#ifdef CONFIG_PID_IN_CONTEXTIDR
+ if (pid < 0) {
+ /* ignore Context ID */
+ flags |= ETMAAT_IGNCONTEXTID;
+ } else {
+ flags |= ETMAAT_VALUE1;
+
+ /* Set up the first Context ID comparator.
+ Process ID is found in the 24 first bits of Context ID
+ (provided by CONFIG_PID_IN_CONTEXTIDR) */
+ etm_writel(t, pid << 8, ETMR_CTXIDCOMP_VAL(0));
+ etm_writel(t, 0xff, ETMR_CTXIDCOMP_MASK);
+ }
+#else
+ flags |= ETMAAT_IGNCONTEXTID;
+#endif
+
if (data)
flags |= ETMAAT_DLOADSTORE;
else
@@ -124,8 +171,10 @@ static int trace_start(struct tracectx *t)
return -EFAULT;
}

- etm_setup_address_range(t, 1, t->addrrange_start, t->addrrange_end,
- 0, 0);
+ etm_setup(t, 1,
+ t->addrrange_start, t->addrrange_end, 0,
+ t->pid,
+ 0);
etm_writel(t, 0, ETMR_TRACEENCTRL2);
etm_writel(t, 0, ETMR_TRACESSCTRL);
etm_writel(t, 0x6f, ETMR_TRACEENEVT);
@@ -489,6 +538,7 @@ static ssize_t trace_info_show(struct device *dev,

return sprintf(buf, "Trace buffer len: %d\n"
"Addr comparator pairs: %d\n"
+ "Ctx ID comparators: %d\n"
"ETBR_WRITEADDR:\t%08x\n"
"ETBR_READADDR:\t%08x\n"
"ETBR_STATUS:\t%08x\n"
@@ -497,6 +547,7 @@ static ssize_t trace_info_show(struct device *dev,
"ETMR_STATUS:\t%08x\n",
datalen,
tracer.naddrcmppairs,
+ tracer.nctxidcmp,
etb_wa,
etb_ra,
etb_st,
@@ -569,6 +620,61 @@ static ssize_t trace_addrrange_store(struct device *dev,
DEVICE_ATTR(trace_addrrange, S_IRUGO|S_IWUSR,
trace_addrrange_show, trace_addrrange_store);

+#ifdef CONFIG_PID_IN_CONTEXTIDR
+static ssize_t trace_pid_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+#ifdef CONFIG_PID_NS
+ return sprintf(buf, "%d\n", tracer.vpid);
+#else
+ return sprintf(buf, "%d\n", tracer.pid);
+#endif
+}
+
+static ssize_t trace_pid_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ pid_t pid;
+#ifdef CONFIG_PID_NS
+ pid_t vpid;
+#endif
+
+ if (tracer.flags & TRACER_RUNNING)
+ return -EBUSY;
+
+ if (sscanf(buf, "%i", &pid) != 1)
+ return -EINVAL;
+
+#ifdef CONFIG_PID_NS
+ /* the value written to the Context ID register is the global PID */
+ vpid = pid;
+
+ /* -1 means trace everything,
+ 0 means kernel tracing,
+ > 0 process tracing */
+ if (pid > 0) {
+ pid = pid_vnr_to_pid_nr(vpid);
+
+ if (pid < 0)
+ return pid;
+ }
+#endif
+
+ mutex_lock(&tracer.mutex);
+ tracer.pid = pid;
+#ifdef CONFIG_PID_NS
+ tracer.vpid = vpid;
+#endif
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+DEVICE_ATTR(trace_pid, S_IRUGO|S_IWUSR, trace_pid_show, trace_pid_store);
+#endif
+
static int etm_probe(struct amba_device *dev, const struct amba_id *id)
{
struct tracectx *t = &tracer;
@@ -598,6 +704,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
t->etm_portsz = 1;
t->addrrange_start = (unsigned long) _stext;
t->addrrange_end = (unsigned long) _etext;
+ t->pid = -1; /* trace everything */

etm_unlock(t);
(void)etm_readl(t, ETMMR_PDSR);
@@ -605,6 +712,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
(void)etm_readl(&tracer, ETMMR_OSSRR);

t->naddrcmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
+ t->nctxidcmp = (etm_readl(t, ETMR_CONFCODE) >> 24) & 0x3;
etm_writel(t, 0x440, ETMR_CTRL);
etm_lock(t);

@@ -612,7 +720,7 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
if (ret)
goto out_unmap;

- /* failing to create any of these three is not fatal */
+ /* failing to create any of these four is not fatal */
ret = device_create_file(&dev->dev, &dev_attr_trace_info);
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
@@ -625,6 +733,12 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_addrrange in sysfs\n");

+#ifdef CONFIG_PID_IN_CONTEXTIDR
+ ret = device_create_file(&dev->dev, &dev_attr_trace_pid);
+ if (ret)
+ dev_dbg(&dev->dev, "Failed to create trace_pid in sysfs\n");
+#endif
+
dev_dbg(t->dev, "ETM AMBA driver initialized.\n");

out:
@@ -655,6 +769,9 @@ static int etm_remove(struct amba_device *dev)
device_remove_file(&dev->dev, &dev_attr_trace_info);
device_remove_file(&dev->dev, &dev_attr_trace_mode);
device_remove_file(&dev->dev, &dev_attr_trace_addrrange);
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+ device_remove_file(&dev->dev, &dev_attr_trace_pid);
+#endif

return 0;
}
--
1.8.5.3

2014-01-30 16:12:54

by Adrien Vergé

[permalink] [raw]
Subject: [PATCH V3 2/5] ARM CoreSight: ETM: Use device attributes

Replace all kobjects attributes with device attributes.
User experience isn't changed since the same files are created in sysfs.

Signed-off-by: Adrien Vergé <[email protected]>
---
arch/arm/kernel/etm.c | 48 +++++++++++++++++++++---------------------------
1 file changed, 21 insertions(+), 27 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 5192693..7a3ee66 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -433,15 +433,14 @@ static struct amba_driver etb_driver = {
};

/* use a sysfs file "trace_running" to start/stop tracing */
-static ssize_t trace_running_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static ssize_t trace_running_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%x\n", trace_isrunning(&tracer));
}

-static ssize_t trace_running_store(struct kobject *kobj,
- struct kobj_attribute *attr,
+static ssize_t trace_running_store(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t n)
{
unsigned int value;
@@ -457,12 +456,11 @@ static ssize_t trace_running_store(struct kobject *kobj,
return ret ? : n;
}

-static struct kobj_attribute trace_running_attr =
- __ATTR(trace_running, 0644, trace_running_show, trace_running_store);
+DEVICE_ATTR(trace_running, S_IRUGO|S_IWUSR,
+ trace_running_show, trace_running_store);

-static ssize_t trace_info_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static ssize_t trace_info_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
int datalen;
@@ -498,21 +496,19 @@ static ssize_t trace_info_show(struct kobject *kobj,
);
}

-static struct kobj_attribute trace_info_attr =
- __ATTR(trace_info, 0444, trace_info_show, NULL);
+DEVICE_ATTR(trace_info, S_IRUGO, trace_info_show, NULL);

-static ssize_t trace_mode_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static ssize_t trace_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d %d\n",
!!(tracer.flags & TRACER_CYCLE_ACC),
tracer.etm_portsz);
}

-static ssize_t trace_mode_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t trace_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
{
unsigned int cycacc, portsz;

@@ -531,8 +527,7 @@ static ssize_t trace_mode_store(struct kobject *kobj,
return n;
}

-static struct kobj_attribute trace_mode_attr =
- __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
+DEVICE_ATTR(trace_mode, S_IRUGO|S_IWUSR, trace_mode_show, trace_mode_store);

static int etm_probe(struct amba_device *dev, const struct amba_id *id)
{
@@ -571,17 +566,16 @@ static int etm_probe(struct amba_device *dev, const struct amba_id *id)
etm_writel(t, 0x440, ETMR_CTRL);
etm_lock(t);

- ret = sysfs_create_file(&dev->dev.kobj,
- &trace_running_attr.attr);
+ ret = device_create_file(&dev->dev, &dev_attr_trace_running);
if (ret)
goto out_unmap;

/* failing to create any of these two is not fatal */
- ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr);
+ ret = device_create_file(&dev->dev, &dev_attr_trace_info);
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");

- ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr);
+ ret = device_create_file(&dev->dev, &dev_attr_trace_mode);
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");

@@ -611,9 +605,9 @@ static int etm_remove(struct amba_device *dev)

amba_release_regions(dev);

- sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
- sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
- sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
+ device_remove_file(&dev->dev, &dev_attr_trace_running);
+ device_remove_file(&dev->dev, &dev_attr_trace_info);
+ device_remove_file(&dev->dev, &dev_attr_trace_mode);

return 0;
}
--
1.8.5.3

2014-02-03 10:48:08

by Will Deacon

[permalink] [raw]
Subject: Re: [PATCH V3 5/5] ARM CoreSight: ETM: Add PID control support

On Thu, Jan 30, 2014 at 04:11:10PM +0000, Adrien Verg? wrote:
> In the same manner as for enabling tracing, an entry is created in
> sysfs to set the PID that triggers tracing. This change is effective
> only if CONFIG_PID_IN_CONTEXTIDR is set.
>
> When using PID namespaces, the virtual PID given by the user is
> converted to the globally unique ID (task_pid_nr) that is present
> in the Context ID register.

Hmm, I wonder whether debugfs would be more suitable for this?

Will