mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 16:12:59 +02:00
perf/amd/ibs: Enable streaming store filter
IBS OP on future hardware supports recording samples only for instructions that does streaming store. Like the existing IBS filters, samples pointing to instruction which does not cause streaming store are discarded and IBS restarts internally. Example: $ perf record -e ibs_op/strmst=1/ -- <workload> Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://patch.msgid.link/20260216042530.1546-7-ravi.bangoria@amd.com
This commit is contained in:
parent
8c63c4af92
commit
8ae68bfec9
|
|
@ -34,6 +34,8 @@ static u32 ibs_caps;
|
|||
|
||||
/* attr.config1 */
|
||||
#define IBS_OP_CONFIG1_LDLAT_MASK (0xFFFULL << 0)
|
||||
#define IBS_OP_CONFIG1_STRMST_MASK (1ULL << 12)
|
||||
#define IBS_OP_CONFIG1_STRMST_SHIFT (12)
|
||||
|
||||
#define IBS_FETCH_CONFIG1_FETCHLAT_MASK (0x7FFULL << 0)
|
||||
|
||||
|
|
@ -292,6 +294,14 @@ static bool perf_ibs_fetch_lat_event(struct perf_ibs *perf_ibs,
|
|||
(event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK);
|
||||
}
|
||||
|
||||
static bool perf_ibs_strmst_event(struct perf_ibs *perf_ibs,
|
||||
struct perf_event *event)
|
||||
{
|
||||
return perf_ibs == &perf_ibs_op &&
|
||||
(ibs_caps & IBS_CAPS_STRMST_RMTSOCKET) &&
|
||||
(event->attr.config1 & IBS_OP_CONFIG1_STRMST_MASK);
|
||||
}
|
||||
|
||||
static int perf_ibs_init(struct perf_event *event)
|
||||
{
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
|
|
@ -419,6 +429,15 @@ static int perf_ibs_init(struct perf_event *event)
|
|||
hwc->extra_reg.config |= fetchlat << IBS_FETCH_2_FETCHLAT_FILTER_SHIFT;
|
||||
}
|
||||
|
||||
if (perf_ibs_strmst_event(perf_ibs, event)) {
|
||||
u64 strmst = event->attr.config1 & IBS_OP_CONFIG1_STRMST_MASK;
|
||||
|
||||
strmst >>= IBS_OP_CONFIG1_STRMST_SHIFT;
|
||||
|
||||
hwc->extra_reg.reg = perf_ibs->msr2;
|
||||
hwc->extra_reg.config |= strmst << IBS_OP_2_STRM_ST_FILTER_SHIFT;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we modify hwc->sample_period, we also need to update
|
||||
* hwc->last_period and hwc->period_left.
|
||||
|
|
@ -709,6 +728,8 @@ PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_cap, "1");
|
|||
PMU_EVENT_ATTR_STRING(dtlb_pgsize, ibs_op_dtlb_pgsize_cap, "1");
|
||||
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
|
||||
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
|
||||
PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_format, "config1:12");
|
||||
PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_cap, "1");
|
||||
|
||||
static umode_t
|
||||
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
|
||||
|
|
@ -722,6 +743,12 @@ ibs_fetch_lat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
|
|||
return ibs_caps & IBS_CAPS_FETCHLAT ? attr->mode : 0;
|
||||
}
|
||||
|
||||
static umode_t
|
||||
ibs_op_strmst_is_visible(struct kobject *kobj, struct attribute *attr, int i)
|
||||
{
|
||||
return ibs_caps & IBS_CAPS_STRMST_RMTSOCKET ? attr->mode : 0;
|
||||
}
|
||||
|
||||
static umode_t
|
||||
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
|
||||
{
|
||||
|
|
@ -770,6 +797,11 @@ static struct attribute *ibs_op_dtlb_pgsize_cap_attrs[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *ibs_op_strmst_cap_attrs[] = {
|
||||
&ibs_op_strmst_cap.attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group group_fetch_formats = {
|
||||
.name = "format",
|
||||
.attrs = fetch_attrs,
|
||||
|
|
@ -811,6 +843,12 @@ static struct attribute_group group_ibs_op_dtlb_pgsize_cap = {
|
|||
.is_visible = ibs_op_dtlb_pgsize_is_visible,
|
||||
};
|
||||
|
||||
static struct attribute_group group_ibs_op_strmst_cap = {
|
||||
.name = "caps",
|
||||
.attrs = ibs_op_strmst_cap_attrs,
|
||||
.is_visible = ibs_op_strmst_is_visible,
|
||||
};
|
||||
|
||||
static const struct attribute_group *fetch_attr_groups[] = {
|
||||
&group_fetch_formats,
|
||||
&empty_caps_group,
|
||||
|
|
@ -856,6 +894,11 @@ static struct attribute *ibs_op_ldlat_format_attrs[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *ibs_op_strmst_format_attrs[] = {
|
||||
&ibs_op_strmst_format.attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group group_cnt_ctl = {
|
||||
.name = "format",
|
||||
.attrs = cnt_ctl_attrs,
|
||||
|
|
@ -880,6 +923,12 @@ static struct attribute_group group_ibs_op_ldlat_format = {
|
|||
.is_visible = ibs_op_ldlat_is_visible,
|
||||
};
|
||||
|
||||
static struct attribute_group group_ibs_op_strmst_format = {
|
||||
.name = "format",
|
||||
.attrs = ibs_op_strmst_format_attrs,
|
||||
.is_visible = ibs_op_strmst_is_visible,
|
||||
};
|
||||
|
||||
static const struct attribute_group *op_attr_update[] = {
|
||||
&group_cnt_ctl,
|
||||
&group_op_l3missonly,
|
||||
|
|
@ -887,6 +936,8 @@ static const struct attribute_group *op_attr_update[] = {
|
|||
&group_ibs_op_ldlat_cap,
|
||||
&group_ibs_op_ldlat_format,
|
||||
&group_ibs_op_dtlb_pgsize_cap,
|
||||
&group_ibs_op_strmst_cap,
|
||||
&group_ibs_op_strmst_format,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,8 @@ union ibs_op_data2 {
|
|||
rmt_node:1, /* 4: destination node */
|
||||
cache_hit_st:1, /* 5: cache hit state */
|
||||
data_src_hi:2, /* 6-7: data source high */
|
||||
reserved1:56; /* 8-63: reserved */
|
||||
strm_st:1, /* 8: streaming store */
|
||||
reserved1:55; /* 9-63: reserved */
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user