提交 2e4f17d2 编写于 作者: P Paul Mundt

sh: oprofile: Fix up and extend op_name_from_perf_id().

op_name_from_perf_id() currently returns a local variable, which isn't
terribly productive. As we only handle a single PMU case for now, simply
allocate and free the string from the arch init/exit context and have
op_name_from_perf_id() hand back the cached string.

This also takes UTS_MACHINE in to account, given that we build for
multiple architectures.
Signed-off-by: NPaul Mundt <lethal@linux-sh.org>
上级 667b279b
...@@ -225,7 +225,7 @@ static void sh7750_pmu_enable_all(void) ...@@ -225,7 +225,7 @@ static void sh7750_pmu_enable_all(void)
} }
static struct sh_pmu sh7750_pmu = { static struct sh_pmu sh7750_pmu = {
.name = "SH7750", .name = "sh7750",
.num_events = 2, .num_events = 2,
.event_map = sh7750_event_map, .event_map = sh7750_event_map,
.max_events = ARRAY_SIZE(sh7750_general_events), .max_events = ARRAY_SIZE(sh7750_general_events),
......
...@@ -259,7 +259,7 @@ static void sh4a_pmu_enable_all(void) ...@@ -259,7 +259,7 @@ static void sh4a_pmu_enable_all(void)
} }
static struct sh_pmu sh4a_pmu = { static struct sh_pmu sh4a_pmu = {
.name = "SH-4A", .name = "sh4a",
.num_events = 2, .num_events = 2,
.event_map = sh4a_event_map, .event_map = sh4a_event_map,
.max_events = ARRAY_SIZE(sh4a_general_events), .max_events = ARRAY_SIZE(sh4a_general_events),
......
obj-$(CONFIG_OPROFILE) += oprofile.o obj-$(CONFIG_OPROFILE) += oprofile.o
CFLAGS_common.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \ oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \ event_buffer.o oprofile_files.o \
......
/* /*
* arch/sh/oprofile/init.c * arch/sh/oprofile/init.c
* *
* Copyright (C) 2003 - 2008 Paul Mundt * Copyright (C) 2003 - 2010 Paul Mundt
* *
* Based on arch/mips/oprofile/common.c: * Based on arch/mips/oprofile/common.c:
* *
...@@ -18,38 +18,41 @@ ...@@ -18,38 +18,41 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <linux/slab.h>
#include <asm/processor.h> #include <asm/processor.h>
#ifdef CONFIG_HW_PERF_EVENTS #ifdef CONFIG_HW_PERF_EVENTS
extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth); extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth);
/*
* This will need to be reworked when multiple PMUs are supported.
*/
static char *sh_pmu_op_name;
char *op_name_from_perf_id(void) char *op_name_from_perf_id(void)
{ {
const char *pmu; return sh_pmu_op_name;
char buf[20];
int size;
pmu = perf_pmu_name();
if (!pmu)
return NULL;
size = snprintf(buf, sizeof(buf), "sh/%s", pmu);
if (size > -1 && size < sizeof(buf))
return buf;
return NULL;
} }
int __init oprofile_arch_init(struct oprofile_operations *ops) int __init oprofile_arch_init(struct oprofile_operations *ops)
{ {
ops->backtrace = sh_backtrace; ops->backtrace = sh_backtrace;
if (perf_num_counters() == 0)
return -ENODEV;
sh_pmu_op_name = kasprintf(GFP_KERNEL, "%s/%s",
UTS_MACHINE, perf_pmu_name());
if (unlikely(!sh_pmu_op_name))
return -ENOMEM;
return oprofile_perf_init(ops); return oprofile_perf_init(ops);
} }
void __exit oprofile_arch_exit(void) void __exit oprofile_arch_exit(void)
{ {
oprofile_perf_exit(); oprofile_perf_exit();
kfree(sh_pmu_op_name);
} }
#else #else
int __init oprofile_arch_init(struct oprofile_operations *ops) int __init oprofile_arch_init(struct oprofile_operations *ops)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册