Skip to content

Commit ba5d35b

Browse files
Ravi BangoriaPeter Zijlstra
authored andcommitted
perf/amd/ibs: Add support for L3 miss filtering
IBS L3 miss filtering works by tagging an instruction on IBS counter overflow and generating an NMI if the tagged instruction causes an L3 miss. Samples without an L3 miss are discarded and counter is reset with random value (between 1-15 for fetch pmu and 1-127 for op pmu). This helps in reducing sampling overhead when user is interested only in such samples. One of the use case of such filtered samples is to feed data to page-migration daemon in tiered memory systems. Add support for L3 miss filtering in IBS driver via new pmu attribute "l3missonly". Example usage: # perf record -a -e ibs_op/l3missonly=1/ --raw-samples sleep 5 Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220509044914.1473-4-ravi.bangoria@amd.com
1 parent 2a7a7e6 commit ba5d35b

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

arch/x86/events/amd/ibs.c

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -544,22 +544,46 @@ static const struct attribute_group *empty_attr_groups[] = {
544544

545545
PMU_FORMAT_ATTR(rand_en, "config:57");
546546
PMU_FORMAT_ATTR(cnt_ctl, "config:19");
547+
PMU_EVENT_ATTR_STRING(l3missonly, fetch_l3missonly, "config:59");
548+
PMU_EVENT_ATTR_STRING(l3missonly, op_l3missonly, "config:16");
549+
550+
static umode_t
551+
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
552+
{
553+
return ibs_caps & IBS_CAPS_ZEN4 ? attr->mode : 0;
554+
}
547555

548556
static struct attribute *rand_en_attrs[] = {
549557
&format_attr_rand_en.attr,
550558
NULL,
551559
};
552560

561+
static struct attribute *fetch_l3missonly_attrs[] = {
562+
&fetch_l3missonly.attr.attr,
563+
NULL,
564+
};
565+
553566
static struct attribute_group group_rand_en = {
554567
.name = "format",
555568
.attrs = rand_en_attrs,
556569
};
557570

571+
static struct attribute_group group_fetch_l3missonly = {
572+
.name = "format",
573+
.attrs = fetch_l3missonly_attrs,
574+
.is_visible = zen4_ibs_extensions_is_visible,
575+
};
576+
558577
static const struct attribute_group *fetch_attr_groups[] = {
559578
&group_rand_en,
560579
NULL,
561580
};
562581

582+
static const struct attribute_group *fetch_attr_update[] = {
583+
&group_fetch_l3missonly,
584+
NULL,
585+
};
586+
563587
static umode_t
564588
cnt_ctl_is_visible(struct kobject *kobj, struct attribute *attr, int i)
565589
{
@@ -571,14 +595,26 @@ static struct attribute *cnt_ctl_attrs[] = {
571595
NULL,
572596
};
573597

598+
static struct attribute *op_l3missonly_attrs[] = {
599+
&op_l3missonly.attr.attr,
600+
NULL,
601+
};
602+
574603
static struct attribute_group group_cnt_ctl = {
575604
.name = "format",
576605
.attrs = cnt_ctl_attrs,
577606
.is_visible = cnt_ctl_is_visible,
578607
};
579608

609+
static struct attribute_group group_op_l3missonly = {
610+
.name = "format",
611+
.attrs = op_l3missonly_attrs,
612+
.is_visible = zen4_ibs_extensions_is_visible,
613+
};
614+
580615
static const struct attribute_group *op_attr_update[] = {
581616
&group_cnt_ctl,
617+
&group_op_l3missonly,
582618
NULL,
583619
};
584620

@@ -805,10 +841,8 @@ static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
805841
return ret;
806842
}
807843

808-
static __init int perf_event_ibs_init(void)
844+
static __init int perf_ibs_fetch_init(void)
809845
{
810-
int ret;
811-
812846
/*
813847
* Some chips fail to reset the fetch count when it is written; instead
814848
* they need a 0-1 transition of IbsFetchEn.
@@ -819,12 +853,17 @@ static __init int perf_event_ibs_init(void)
819853
if (boot_cpu_data.x86 == 0x19 && boot_cpu_data.x86_model < 0x10)
820854
perf_ibs_fetch.fetch_ignore_if_zero_rip = 1;
821855

856+
if (ibs_caps & IBS_CAPS_ZEN4)
857+
perf_ibs_fetch.config_mask |= IBS_FETCH_L3MISSONLY;
858+
822859
perf_ibs_fetch.pmu.attr_groups = fetch_attr_groups;
860+
perf_ibs_fetch.pmu.attr_update = fetch_attr_update;
823861

824-
ret = perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
825-
if (ret)
826-
return ret;
862+
return perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
863+
}
827864

865+
static __init int perf_ibs_op_init(void)
866+
{
828867
if (ibs_caps & IBS_CAPS_OPCNT)
829868
perf_ibs_op.config_mask |= IBS_OP_CNT_CTL;
830869

@@ -834,10 +873,24 @@ static __init int perf_event_ibs_init(void)
834873
perf_ibs_op.cnt_mask |= IBS_OP_MAX_CNT_EXT_MASK;
835874
}
836875

876+
if (ibs_caps & IBS_CAPS_ZEN4)
877+
perf_ibs_op.config_mask |= IBS_OP_L3MISSONLY;
878+
837879
perf_ibs_op.pmu.attr_groups = empty_attr_groups;
838880
perf_ibs_op.pmu.attr_update = op_attr_update;
839881

840-
ret = perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
882+
return perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
883+
}
884+
885+
static __init int perf_event_ibs_init(void)
886+
{
887+
int ret;
888+
889+
ret = perf_ibs_fetch_init();
890+
if (ret)
891+
return ret;
892+
893+
ret = perf_ibs_op_init();
841894
if (ret)
842895
goto err_op;
843896

arch/x86/include/asm/perf_event.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ struct pebs_xmm {
410410
#define IBS_CAPS_OPBRNFUSE (1U<<8)
411411
#define IBS_CAPS_FETCHCTLEXTD (1U<<9)
412412
#define IBS_CAPS_OPDATA4 (1U<<10)
413+
#define IBS_CAPS_ZEN4 (1U<<11)
413414

414415
#define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \
415416
| IBS_CAPS_FETCHSAM \
@@ -423,6 +424,7 @@ struct pebs_xmm {
423424
#define IBSCTL_LVT_OFFSET_MASK 0x0F
424425

425426
/* IBS fetch bits/masks */
427+
#define IBS_FETCH_L3MISSONLY (1ULL<<59)
426428
#define IBS_FETCH_RAND_EN (1ULL<<57)
427429
#define IBS_FETCH_VAL (1ULL<<49)
428430
#define IBS_FETCH_ENABLE (1ULL<<48)
@@ -439,6 +441,7 @@ struct pebs_xmm {
439441
#define IBS_OP_CNT_CTL (1ULL<<19)
440442
#define IBS_OP_VAL (1ULL<<18)
441443
#define IBS_OP_ENABLE (1ULL<<17)
444+
#define IBS_OP_L3MISSONLY (1ULL<<16)
442445
#define IBS_OP_MAX_CNT 0x0000FFFFULL
443446
#define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */
444447
#define IBS_OP_MAX_CNT_EXT_MASK (0x7FULL<<20) /* separate upper 7 bits */

0 commit comments

Comments
 (0)