PERF_EVSEL__CONFIG_TERM_PERCORE,
PERF_EVSEL__CONFIG_TERM_AUX_OUTPUT,
PERF_EVSEL__CONFIG_TERM_AUX_SAMPLE_SIZE,
+ PERF_EVSEL__CONFIG_TERM_CFG_CHG,
};
struct perf_evsel_config_term {
bool percore;
bool aux_output;
u32 aux_sample_size;
+ u64 cfg_chg;
} val;
bool weak;
};
break;
}
}
-#undef ADD_EVSEL_CONFIG
+ return 0;
+}
+
+/*
+ * Add PERF_EVSEL__CONFIG_TERM_CFG_CHG where cfg_chg will have a bit set for
+ * each bit of attr->config that the user has changed.
+ */
+static int get_config_chgs(struct perf_pmu *pmu, struct list_head *head_config,
+ struct list_head *head_terms)
+{
+ struct parse_events_term *term;
+ u64 bits = 0;
+ int type;
+
+ list_for_each_entry(term, head_config, list) {
+ switch (term->type_term) {
+ case PARSE_EVENTS__TERM_TYPE_USER:
+ type = perf_pmu__format_type(&pmu->format, term->config);
+ if (type != PERF_PMU_FORMAT_VALUE_CONFIG)
+ continue;
+ bits |= perf_pmu__format_bits(&pmu->format, term->config);
+ break;
+ case PARSE_EVENTS__TERM_TYPE_CONFIG:
+ bits = ~(u64)0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (bits)
+ ADD_CONFIG_TERM(CFG_CHG, cfg_chg, bits);
+
+#undef ADD_CONFIG_TERM
return 0;
}
if (get_config_terms(head_config, &config_terms))
return -ENOMEM;
+ /*
+ * When using default config, record which bits of attr->config were
+ * changed by the user.
+ */
+ if (pmu->default_config && get_config_chgs(pmu, head_config, &config_terms))
+ return -ENOMEM;
+
if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
struct perf_evsel_config_term *pos, *tmp;
return bits;
}
+int perf_pmu__format_type(struct list_head *formats, const char *name)
+{
+ struct perf_pmu_format *format = pmu_find_format(formats, name);
+
+ if (!format)
+ return -1;
+
+ return format->value;
+}
+
/*
* Sets value based on the format definition (format parameter)
* and unformated value (value parameter).
struct list_head *head_terms,
bool zero, struct parse_events_error *error);
__u64 perf_pmu__format_bits(struct list_head *formats, const char *name);
+int perf_pmu__format_type(struct list_head *formats, const char *name);
int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
struct perf_pmu_info *info);
struct list_head *perf_pmu__alias(struct perf_pmu *pmu,