Commit 51686546 authored by Suravee Suthikulpanit's avatar Suravee Suthikulpanit Committed by Ingo Molnar

x86/events/amd/iommu: Fix sysfs perf attribute groups

Introduce static amd_iommu_attr_groups to simplify the
sysfs attributes initialization code.
Signed-off-by: default avatarSuravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Jörg Rödel <joro@8bytes.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: iommu@lists.linux-foundation.org
Link: http://lkml.kernel.org/r/1487926102-13073-9-git-send-email-Suravee.Suthikulpanit@amd.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 1650dfd1
...@@ -43,14 +43,8 @@ struct perf_amd_iommu { ...@@ -43,14 +43,8 @@ struct perf_amd_iommu {
u8 max_counters; u8 max_counters;
u64 cntr_assign_mask; u64 cntr_assign_mask;
raw_spinlock_t lock; raw_spinlock_t lock;
const struct attribute_group *attr_groups[4];
}; };
#define format_group attr_groups[0]
#define cpumask_group attr_groups[1]
#define events_group attr_groups[2]
#define null_group attr_groups[3]
/*--------------------------------------------- /*---------------------------------------------
* sysfs format attributes * sysfs format attributes
*---------------------------------------------*/ *---------------------------------------------*/
...@@ -81,6 +75,10 @@ static struct attribute_group amd_iommu_format_group = { ...@@ -81,6 +75,10 @@ static struct attribute_group amd_iommu_format_group = {
/*--------------------------------------------- /*---------------------------------------------
* sysfs events attributes * sysfs events attributes
*---------------------------------------------*/ *---------------------------------------------*/
static struct attribute_group amd_iommu_events_group = {
.name = "events",
};
struct amd_iommu_event_desc { struct amd_iommu_event_desc {
struct kobj_attribute attr; struct kobj_attribute attr;
const char *event; const char *event;
...@@ -384,76 +382,60 @@ static void perf_iommu_del(struct perf_event *event, int flags) ...@@ -384,76 +382,60 @@ static void perf_iommu_del(struct perf_event *event, int flags)
perf_event_update_userpage(event); perf_event_update_userpage(event);
} }
static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu) static __init int _init_events_attrs(void)
{ {
struct attribute **attrs;
struct attribute_group *attr_group;
int i = 0, j; int i = 0, j;
struct attribute **attrs;
while (amd_iommu_v2_event_descs[i].attr.attr.name) while (amd_iommu_v2_event_descs[i].attr.attr.name)
i++; i++;
attr_group = kzalloc(sizeof(struct attribute *) attrs = kzalloc(sizeof(struct attribute **) * (i + 1), GFP_KERNEL);
* (i + 1) + sizeof(*attr_group), GFP_KERNEL); if (!attrs)
if (!attr_group)
return -ENOMEM; return -ENOMEM;
attrs = (struct attribute **)(attr_group + 1);
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr; attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr;
attr_group->name = "events"; amd_iommu_events_group.attrs = attrs;
attr_group->attrs = attrs;
perf_iommu->events_group = attr_group;
return 0; return 0;
} }
static __init void amd_iommu_pc_exit(void) static __init void amd_iommu_pc_exit(void)
{ {
if (__perf_iommu.events_group != NULL) { kfree(amd_iommu_events_group.attrs);
kfree(__perf_iommu.events_group);
__perf_iommu.events_group = NULL;
}
} }
static __init int _init_perf_amd_iommu( const struct attribute_group *amd_iommu_attr_groups[] = {
struct perf_amd_iommu *perf_iommu, char *name) &amd_iommu_format_group,
&amd_iommu_cpumask_group,
&amd_iommu_events_group,
NULL,
};
static __init int
_init_perf_amd_iommu(struct perf_amd_iommu *perf_iommu, char *name)
{ {
int ret; int ret;
raw_spin_lock_init(&perf_iommu->lock); raw_spin_lock_init(&perf_iommu->lock);
perf_iommu->format_group = &amd_iommu_format_group;
/* Init cpumask attributes to only core 0 */ /* Init cpumask attributes to only core 0 */
cpumask_set_cpu(0, &iommu_cpumask); cpumask_set_cpu(0, &iommu_cpumask);
perf_iommu->cpumask_group = &amd_iommu_cpumask_group;
ret = _init_events_attrs(perf_iommu);
if (ret) {
pr_err("Error initializing AMD IOMMU perf events.\n");
return ret;
}
perf_iommu->max_banks = amd_iommu_pc_get_max_banks(0); perf_iommu->max_banks = amd_iommu_pc_get_max_banks(0);
perf_iommu->max_counters = amd_iommu_pc_get_max_counters(0); perf_iommu->max_counters = amd_iommu_pc_get_max_counters(0);
if (!perf_iommu->max_banks || !perf_iommu->max_counters) if (!perf_iommu->max_banks || !perf_iommu->max_counters)
return -EINVAL; return -EINVAL;
perf_iommu->null_group = NULL; perf_iommu->pmu.attr_groups = amd_iommu_attr_groups;
perf_iommu->pmu.attr_groups = perf_iommu->attr_groups;
ret = perf_pmu_register(&perf_iommu->pmu, name, -1); ret = perf_pmu_register(&perf_iommu->pmu, name, -1);
if (ret) { if (ret)
pr_err("Error initializing AMD IOMMU perf counters.\n"); pr_err("Error initializing AMD IOMMU perf counters.\n");
amd_iommu_pc_exit(); else
} else {
pr_info("Detected AMD IOMMU (%d banks, %d counters/bank).\n", pr_info("Detected AMD IOMMU (%d banks, %d counters/bank).\n",
amd_iommu_pc_get_max_banks(0), amd_iommu_pc_get_max_banks(0),
amd_iommu_pc_get_max_counters(0)); amd_iommu_pc_get_max_counters(0));
}
return ret; return ret;
} }
...@@ -467,24 +449,25 @@ static struct perf_amd_iommu __perf_iommu = { ...@@ -467,24 +449,25 @@ static struct perf_amd_iommu __perf_iommu = {
.stop = perf_iommu_stop, .stop = perf_iommu_stop,
.read = perf_iommu_read, .read = perf_iommu_read,
}, },
.max_banks = 0x00,
.max_counters = 0x00,
.cntr_assign_mask = 0ULL,
.format_group = NULL,
.cpumask_group = NULL,
.events_group = NULL,
.null_group = NULL,
}; };
static __init int amd_iommu_pc_init(void) static __init int amd_iommu_pc_init(void)
{ {
int ret;
/* Make sure the IOMMU PC resource is available */ /* Make sure the IOMMU PC resource is available */
if (!amd_iommu_pc_supported()) if (!amd_iommu_pc_supported())
return -ENODEV; return -ENODEV;
_init_perf_amd_iommu(&__perf_iommu, "amd_iommu"); ret = _init_events_attrs();
if (ret)
return ret;
return 0; ret = _init_perf_amd_iommu(&__perf_iommu, "amd_iommu");
if (ret)
amd_iommu_pc_exit();
return ret;
} }
device_initcall(amd_iommu_pc_init); device_initcall(amd_iommu_pc_init);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment