Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf pmu: Avoid passing format list to perf_pmu__config_terms()

Abstract the format list better, hiding it in the PMU, by changing
perf_pmu__config_terms() the PMU rather than the format list in the PMU.

Change the PMU test to pass a dummy PMU for this purpose. Changing the
test allows perf_pmu__del_formats() to become static.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Gaosheng Cui <cuigaosheng1@huawei.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20230823080828.1460376-6-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
804fee5d 6f2f6eaf

+58 -64
+10 -20
tools/perf/arch/x86/util/intel-pt.c
··· 60 60 size_t priv_size; 61 61 }; 62 62 63 - static int intel_pt_parse_terms_with_default(const char *pmu_name, 64 - struct list_head *formats, 63 + static int intel_pt_parse_terms_with_default(struct perf_pmu *pmu, 65 64 const char *str, 66 65 u64 *config) 67 66 { ··· 79 80 goto out_free; 80 81 81 82 attr.config = *config; 82 - err = perf_pmu__config_terms(pmu_name, formats, &attr, terms, true, 83 - NULL); 83 + err = perf_pmu__config_terms(pmu, &attr, terms, /*zero=*/true, /*err=*/NULL); 84 84 if (err) 85 85 goto out_free; 86 86 ··· 89 91 return err; 90 92 } 91 93 92 - static int intel_pt_parse_terms(const char *pmu_name, struct list_head *formats, 93 - const char *str, u64 *config) 94 + static int intel_pt_parse_terms(struct perf_pmu *pmu, const char *str, u64 *config) 94 95 { 95 96 *config = 0; 96 - return intel_pt_parse_terms_with_default(pmu_name, formats, str, 97 - config); 97 + return intel_pt_parse_terms_with_default(pmu, str, config); 98 98 } 99 99 100 100 static u64 intel_pt_masked_bits(u64 mask, u64 bits) ··· 232 236 233 237 pr_debug2("%s default config: %s\n", intel_pt_pmu->name, buf); 234 238 235 - intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, buf, 236 - &config); 239 + intel_pt_parse_terms(intel_pt_pmu, buf, &config); 237 240 238 241 close(dirfd); 239 242 return config; ··· 343 348 if (priv_size != ptr->priv_size) 344 349 return -EINVAL; 345 350 346 - intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, 347 - "tsc", &tsc_bit); 348 - intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, 349 - "noretcomp", &noretcomp_bit); 350 - intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, 351 - "mtc", &mtc_bit); 351 + intel_pt_parse_terms(intel_pt_pmu, "tsc", &tsc_bit); 352 + intel_pt_parse_terms(intel_pt_pmu, "noretcomp", &noretcomp_bit); 353 + intel_pt_parse_terms(intel_pt_pmu, "mtc", &mtc_bit); 352 354 mtc_freq_bits = perf_pmu__format_bits(&intel_pt_pmu->format, 353 355 "mtc_period"); 354 - intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, 355 - "cyc", &cyc_bit); 356 + intel_pt_parse_terms(intel_pt_pmu, "cyc", &cyc_bit); 356 357 357 358 intel_pt_tsc_ctc_ratio(&tsc_ctc_ratio_n, &tsc_ctc_ratio_d); 358 359 ··· 772 781 intel_pt_evsel->core.attr.aux_watermark = aux_watermark; 773 782 } 774 783 775 - intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, 776 - "tsc", &tsc_bit); 784 + intel_pt_parse_terms(intel_pt_pmu, "tsc", &tsc_bit); 777 785 778 786 if (opts->full_auxtrace && (intel_pt_evsel->core.attr.config & tsc_bit)) 779 787 have_timing_info = true;
+39 -31
tools/perf/tests/pmu.c
··· 7 7 #include <stdio.h> 8 8 #include <linux/kernel.h> 9 9 #include <linux/limits.h> 10 + #include <linux/zalloc.h> 10 11 11 12 /* Simulated format definitions. */ 12 13 static struct test_format { ··· 142 141 static int test__pmu(struct test_suite *test __maybe_unused, int subtest __maybe_unused) 143 142 { 144 143 char dir[PATH_MAX]; 145 - char *format = test_format_dir_get(dir, sizeof(dir)); 146 - LIST_HEAD(formats); 144 + char *format; 147 145 struct list_head *terms = test_terms_list(); 146 + struct perf_event_attr attr; 147 + struct perf_pmu *pmu; 148 + int fd; 148 149 int ret; 149 150 150 - if (!format) 151 + pmu = zalloc(sizeof(*pmu)); 152 + if (!pmu) 153 + return -ENOMEM; 154 + 155 + INIT_LIST_HEAD(&pmu->format); 156 + INIT_LIST_HEAD(&pmu->aliases); 157 + INIT_LIST_HEAD(&pmu->caps); 158 + format = test_format_dir_get(dir, sizeof(dir)); 159 + if (!format) { 160 + free(pmu); 151 161 return -EINVAL; 162 + } 152 163 153 - do { 154 - struct perf_event_attr attr; 155 - int fd; 164 + memset(&attr, 0, sizeof(attr)); 156 165 157 - memset(&attr, 0, sizeof(attr)); 166 + fd = open(format, O_DIRECTORY); 167 + if (fd < 0) { 168 + ret = fd; 169 + goto out; 170 + } 158 171 159 - fd = open(format, O_DIRECTORY); 160 - if (fd < 0) { 161 - ret = fd; 162 - break; 163 - } 164 - ret = perf_pmu__format_parse(fd, &formats); 165 - if (ret) 166 - break; 172 + pmu->name = strdup("perf-pmu-test"); 173 + ret = perf_pmu__format_parse(fd, &pmu->format); 174 + if (ret) 175 + goto out; 167 176 168 - ret = perf_pmu__config_terms("perf-pmu-test", &formats, &attr, 169 - terms, false, NULL); 170 - if (ret) 171 - break; 177 + ret = perf_pmu__config_terms(pmu, &attr, terms, /*zero=*/false, /*err=*/NULL); 178 + if (ret) 179 + goto out; 172 180 173 - ret = -EINVAL; 181 + ret = -EINVAL; 182 + if (attr.config != 0xc00000000002a823) 183 + goto out; 184 + if (attr.config1 != 0x8000400000000145) 185 + goto out; 186 + if (attr.config2 != 0x0400000020041d07) 187 + goto out; 174 188 175 - if (attr.config != 0xc00000000002a823) 176 - break; 177 - if (attr.config1 != 0x8000400000000145) 178 - break; 179 - if (attr.config2 != 0x0400000020041d07) 180 - break; 181 - 182 - ret = 0; 183 - } while (0); 184 - 185 - perf_pmu__del_formats(&formats); 189 + ret = 0; 190 + out: 186 191 test_format_dir_put(format); 192 + perf_pmu__delete(pmu); 187 193 return ret; 188 194 } 189 195
+8 -11
tools/perf/util/pmu.c
··· 1135 1135 * Setup one of config[12] attr members based on the 1136 1136 * user input data - term parameter. 1137 1137 */ 1138 - static int pmu_config_term(const char *pmu_name, 1139 - struct list_head *formats, 1138 + static int pmu_config_term(struct perf_pmu *pmu, 1140 1139 struct perf_event_attr *attr, 1141 1140 struct parse_events_term *term, 1142 1141 struct list_head *head_terms, ··· 1159 1160 if (parse_events__is_hardcoded_term(term)) 1160 1161 return 0; 1161 1162 1162 - format = pmu_find_format(formats, term->config); 1163 + format = pmu_find_format(&pmu->format, term->config); 1163 1164 if (!format) { 1164 - char *pmu_term = pmu_formats_string(formats); 1165 + char *pmu_term = pmu_formats_string(&pmu->format); 1165 1166 char *unknown_term; 1166 1167 char *help_msg; 1167 1168 1168 1169 if (asprintf(&unknown_term, 1169 1170 "unknown term '%s' for pmu '%s'", 1170 - term->config, pmu_name) < 0) 1171 + term->config, pmu->name) < 0) 1171 1172 unknown_term = NULL; 1172 1173 help_msg = parse_events_formats_error_string(pmu_term); 1173 1174 if (err) { ··· 1258 1259 return 0; 1259 1260 } 1260 1261 1261 - int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats, 1262 + int perf_pmu__config_terms(struct perf_pmu *pmu, 1262 1263 struct perf_event_attr *attr, 1263 1264 struct list_head *head_terms, 1264 1265 bool zero, struct parse_events_error *err) ··· 1266 1267 struct parse_events_term *term; 1267 1268 1268 1269 list_for_each_entry(term, head_terms, list) { 1269 - if (pmu_config_term(pmu_name, formats, attr, term, head_terms, 1270 - zero, err)) 1270 + if (pmu_config_term(pmu, attr, term, head_terms, zero, err)) 1271 1271 return -EINVAL; 1272 1272 } 1273 1273 ··· 1284 1286 { 1285 1287 bool zero = !!pmu->default_config; 1286 1288 1287 - return perf_pmu__config_terms(pmu->name, &pmu->format, attr, 1288 - head_terms, zero, err); 1289 + return perf_pmu__config_terms(pmu, attr, head_terms, zero, err); 1289 1290 } 1290 1291 1291 1292 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, ··· 1414 1417 return 0; 1415 1418 } 1416 1419 1417 - void perf_pmu__del_formats(struct list_head *formats) 1420 + static void perf_pmu__del_formats(struct list_head *formats) 1418 1421 { 1419 1422 struct perf_pmu_format *fmt, *tmp; 1420 1423
+1 -2
tools/perf/util/pmu.h
··· 217 217 int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 218 218 struct list_head *head_terms, 219 219 struct parse_events_error *error); 220 - int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats, 220 + int perf_pmu__config_terms(struct perf_pmu *pmu, 221 221 struct perf_event_attr *attr, 222 222 struct list_head *head_terms, 223 223 bool zero, struct parse_events_error *error); ··· 231 231 int perf_pmu__new_format(struct list_head *list, char *name, 232 232 int config, unsigned long *bits); 233 233 int perf_pmu__format_parse(int dirfd, struct list_head *head); 234 - void perf_pmu__del_formats(struct list_head *formats); 235 234 bool perf_pmu__has_format(const struct perf_pmu *pmu, const char *name); 236 235 237 236 bool is_pmu_core(const char *name);