Skip to content

Commit 2a7a7e6

Browse files
Ravi BangoriaPeter Zijlstra
authored andcommitted
perf/amd/ibs: Use ->is_visible callback for dynamic attributes
Currently, some attributes are added at build time whereas others at boot time depending on IBS pmu capabilities. Instead, we can just add all attribute groups at build time but hide individual group at boot time using more appropriate ->is_visible() callback. Also, struct perf_ibs has bunch of fields for pmu attributes which just pass on the pointer, does not do anything else. Remove them. Signed-off-by: Ravi Bangoria <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 39b2ca7 commit 2a7a7e6

File tree

1 file changed

+54
-24
lines changed

1 file changed

+54
-24
lines changed

arch/x86/events/amd/ibs.c

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,6 @@ struct perf_ibs {
9494
unsigned int fetch_ignore_if_zero_rip : 1;
9595
struct cpu_perf_ibs __percpu *pcpu;
9696

97-
struct attribute **format_attrs;
98-
struct attribute_group format_group;
99-
const struct attribute_group *attr_groups[2];
100-
10197
u64 (*get_count)(u64 config);
10298
};
10399

@@ -528,16 +524,61 @@ static void perf_ibs_del(struct perf_event *event, int flags)
528524

529525
static void perf_ibs_read(struct perf_event *event) { }
530526

527+
/*
528+
* We need to initialize with empty group if all attributes in the
529+
* group are dynamic.
530+
*/
531+
static struct attribute *attrs_empty[] = {
532+
NULL,
533+
};
534+
535+
static struct attribute_group empty_format_group = {
536+
.name = "format",
537+
.attrs = attrs_empty,
538+
};
539+
540+
static const struct attribute_group *empty_attr_groups[] = {
541+
&empty_format_group,
542+
NULL,
543+
};
544+
531545
PMU_FORMAT_ATTR(rand_en, "config:57");
532546
PMU_FORMAT_ATTR(cnt_ctl, "config:19");
533547

534-
static struct attribute *ibs_fetch_format_attrs[] = {
548+
static struct attribute *rand_en_attrs[] = {
535549
&format_attr_rand_en.attr,
536550
NULL,
537551
};
538552

539-
static struct attribute *ibs_op_format_attrs[] = {
540-
NULL, /* &format_attr_cnt_ctl.attr if IBS_CAPS_OPCNT */
553+
static struct attribute_group group_rand_en = {
554+
.name = "format",
555+
.attrs = rand_en_attrs,
556+
};
557+
558+
static const struct attribute_group *fetch_attr_groups[] = {
559+
&group_rand_en,
560+
NULL,
561+
};
562+
563+
static umode_t
564+
cnt_ctl_is_visible(struct kobject *kobj, struct attribute *attr, int i)
565+
{
566+
return ibs_caps & IBS_CAPS_OPCNT ? attr->mode : 0;
567+
}
568+
569+
static struct attribute *cnt_ctl_attrs[] = {
570+
&format_attr_cnt_ctl.attr,
571+
NULL,
572+
};
573+
574+
static struct attribute_group group_cnt_ctl = {
575+
.name = "format",
576+
.attrs = cnt_ctl_attrs,
577+
.is_visible = cnt_ctl_is_visible,
578+
};
579+
580+
static const struct attribute_group *op_attr_update[] = {
581+
&group_cnt_ctl,
541582
NULL,
542583
};
543584

@@ -561,7 +602,6 @@ static struct perf_ibs perf_ibs_fetch = {
561602
.max_period = IBS_FETCH_MAX_CNT << 4,
562603
.offset_mask = { MSR_AMD64_IBSFETCH_REG_MASK },
563604
.offset_max = MSR_AMD64_IBSFETCH_REG_COUNT,
564-
.format_attrs = ibs_fetch_format_attrs,
565605

566606
.get_count = get_ibs_fetch_count,
567607
};
@@ -587,7 +627,6 @@ static struct perf_ibs perf_ibs_op = {
587627
.max_period = IBS_OP_MAX_CNT << 4,
588628
.offset_mask = { MSR_AMD64_IBSOP_REG_MASK },
589629
.offset_max = MSR_AMD64_IBSOP_REG_COUNT,
590-
.format_attrs = ibs_op_format_attrs,
591630

592631
.get_count = get_ibs_op_count,
593632
};
@@ -757,17 +796,6 @@ static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
757796

758797
perf_ibs->pcpu = pcpu;
759798

760-
/* register attributes */
761-
if (perf_ibs->format_attrs[0]) {
762-
memset(&perf_ibs->format_group, 0, sizeof(perf_ibs->format_group));
763-
perf_ibs->format_group.name = "format";
764-
perf_ibs->format_group.attrs = perf_ibs->format_attrs;
765-
766-
memset(&perf_ibs->attr_groups, 0, sizeof(perf_ibs->attr_groups));
767-
perf_ibs->attr_groups[0] = &perf_ibs->format_group;
768-
perf_ibs->pmu.attr_groups = perf_ibs->attr_groups;
769-
}
770-
771799
ret = perf_pmu_register(&perf_ibs->pmu, name, -1);
772800
if (ret) {
773801
perf_ibs->pcpu = NULL;
@@ -779,7 +807,6 @@ static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
779807

780808
static __init int perf_event_ibs_init(void)
781809
{
782-
struct attribute **attr = ibs_op_format_attrs;
783810
int ret;
784811

785812
/*
@@ -792,21 +819,24 @@ static __init int perf_event_ibs_init(void)
792819
if (boot_cpu_data.x86 == 0x19 && boot_cpu_data.x86_model < 0x10)
793820
perf_ibs_fetch.fetch_ignore_if_zero_rip = 1;
794821

822+
perf_ibs_fetch.pmu.attr_groups = fetch_attr_groups;
823+
795824
ret = perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
796825
if (ret)
797826
return ret;
798827

799-
if (ibs_caps & IBS_CAPS_OPCNT) {
828+
if (ibs_caps & IBS_CAPS_OPCNT)
800829
perf_ibs_op.config_mask |= IBS_OP_CNT_CTL;
801-
*attr++ = &format_attr_cnt_ctl.attr;
802-
}
803830

804831
if (ibs_caps & IBS_CAPS_OPCNTEXT) {
805832
perf_ibs_op.max_period |= IBS_OP_MAX_CNT_EXT_MASK;
806833
perf_ibs_op.config_mask |= IBS_OP_MAX_CNT_EXT_MASK;
807834
perf_ibs_op.cnt_mask |= IBS_OP_MAX_CNT_EXT_MASK;
808835
}
809836

837+
perf_ibs_op.pmu.attr_groups = empty_attr_groups;
838+
perf_ibs_op.pmu.attr_update = op_attr_update;
839+
810840
ret = perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
811841
if (ret)
812842
goto err_op;

0 commit comments

Comments
 (0)