Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <perf/cpumap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <perf/evlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include "metricgroup.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include "tests.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "pmu-events/pmu-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "rblist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "expr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "stat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) static struct pmu_event pme_test[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	.metric_expr	= "inst_retired.any / cpu_clk_unhalted.thread",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	.metric_name	= "IPC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	.metric_group	= "group1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	.metric_expr	= "idq_uops_not_delivered.core / (4 * (( ( cpu_clk_unhalted.thread / 2 ) * "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 			  "( 1 + cpu_clk_unhalted.one_thread_active / cpu_clk_unhalted.ref_xclk ) )))",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	.metric_name	= "Frontend_Bound_SMT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	.metric_expr	= "l1d\\-loads\\-misses / inst_retired.any",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	.metric_name	= "dcache_miss_cpi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	.metric_expr	= "l1i\\-loads\\-misses / inst_retired.any",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	.metric_name	= "icache_miss_cycles",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	.metric_expr	= "(dcache_miss_cpi + icache_miss_cycles)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	.metric_name	= "cache_miss_cycles",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	.metric_group	= "group1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	.metric_expr	= "l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	.metric_name	= "DCache_L2_All_Hits",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	.metric_expr	= "max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) + "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 			  "l2_rqsts.pf_miss + l2_rqsts.rfo_miss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	.metric_name	= "DCache_L2_All_Miss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	.metric_expr	= "dcache_l2_all_hits + dcache_l2_all_miss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	.metric_name	= "DCache_L2_All",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	.metric_expr	= "d_ratio(dcache_l2_all_hits, dcache_l2_all)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	.metric_name	= "DCache_L2_Hits",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	.metric_expr	= "d_ratio(dcache_l2_all_miss, dcache_l2_all)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	.metric_name	= "DCache_L2_Misses",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	.metric_expr	= "ipc + m2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	.metric_name	= "M1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	.metric_expr	= "ipc + m1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	.metric_name	= "M2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	.metric_expr	= "1/m3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	.metric_name	= "M3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	.name	= NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static struct pmu_events_map map = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	.cpuid		= "test",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	.version	= "1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	.type		= "core",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	.table		= pme_test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) struct value {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	const char	*event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	u64		 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static u64 find_value(const char *name, struct value *values)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	struct value *v = values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	while (v->event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		if (!strcmp(name, v->event))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			return v->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		v++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void load_runtime_stat(struct runtime_stat *st, struct evlist *evlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			      struct value *vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	u64 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		count = find_value(evsel->name, vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		perf_stat__update_shadow_stats(evsel, count, 0, st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static double compute_single(struct rblist *metric_events, struct evlist *evlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			     struct runtime_stat *st, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	struct metric_expr *mexp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct metric_event *me;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		me = metricgroup__lookup(metric_events, evsel, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		if (me != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			list_for_each_entry (mexp, &me->head, nd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				if (strcmp(mexp->metric_name, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 				return test_generic_metric(mexp, 0, st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	return 0.;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int __compute_metric(const char *name, struct value *vals,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			    const char *name1, double *ratio1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			    const char *name2, double *ratio2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	struct rblist metric_events = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		.nr_entries = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	struct perf_cpu_map *cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	struct runtime_stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct evlist *evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	 * We need to prepare evlist for stat mode running on CPU 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	 * because that's where all the stats are going to be created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	evlist = evlist__new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	if (!evlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	cpus = perf_cpu_map__new("0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	if (!cpus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		evlist__delete(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	perf_evlist__set_maps(&evlist->core, cpus, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	runtime_stat__init(&st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	/* Parse the metric into metric_events list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	err = metricgroup__parse_groups_test(evlist, &map, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 					     false, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 					     &metric_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	err = perf_evlist__alloc_stats(evlist, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	/* Load the runtime stats with given numbers for events. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	load_runtime_stat(&st, evlist, vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	/* And execute the metric */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (name1 && ratio1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		*ratio1 = compute_single(&metric_events, evlist, &st, name1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (name2 && ratio2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		*ratio2 = compute_single(&metric_events, evlist, &st, name2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	/* ... clenup. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	metricgroup__rblist_exit(&metric_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	runtime_stat__exit(&st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	perf_evlist__free_stats(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	perf_cpu_map__put(cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	evlist__delete(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int compute_metric(const char *name, struct value *vals, double *ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	return __compute_metric(name, vals, name, ratio, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int compute_metric_group(const char *name, struct value *vals,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				const char *name1, double *ratio1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				const char *name2, double *ratio2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return __compute_metric(name, vals, name1, ratio1, name2, ratio2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int test_ipc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	double ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	struct value vals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		{ .event = "inst_retired.any",        .val = 300 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		{ .event = "cpu_clk_unhalted.thread", .val = 200 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		{ .event = NULL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	TEST_ASSERT_VAL("failed to compute metric",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			compute_metric("IPC", vals, &ratio) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	TEST_ASSERT_VAL("IPC failed, wrong ratio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			ratio == 1.5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int test_frontend(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	double ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	struct value vals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		{ .event = "idq_uops_not_delivered.core",        .val = 300 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		{ .event = "cpu_clk_unhalted.thread",            .val = 200 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		{ .event = "cpu_clk_unhalted.one_thread_active", .val = 400 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		{ .event = "cpu_clk_unhalted.ref_xclk",          .val = 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		{ .event = NULL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	TEST_ASSERT_VAL("failed to compute metric",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			compute_metric("Frontend_Bound_SMT", vals, &ratio) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	TEST_ASSERT_VAL("Frontend_Bound_SMT failed, wrong ratio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			ratio == 0.45);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int test_cache_miss_cycles(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	double ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	struct value vals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		{ .event = "l1d-loads-misses",  .val = 300 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		{ .event = "l1i-loads-misses",  .val = 200 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		{ .event = "inst_retired.any",  .val = 400 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		{ .event = NULL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	TEST_ASSERT_VAL("failed to compute metric",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			compute_metric("cache_miss_cycles", vals, &ratio) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	TEST_ASSERT_VAL("cache_miss_cycles failed, wrong ratio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			ratio == 1.25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  * DCache_L2_All_Hits = l2_rqsts.demand_data_rd_hit + l2_rqsts.pf_hit + l2_rqsts.rfo_hi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  * DCache_L2_All_Miss = max(l2_rqsts.all_demand_data_rd - l2_rqsts.demand_data_rd_hit, 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  *                      l2_rqsts.pf_miss + l2_rqsts.rfo_miss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  * DCache_L2_All      = dcache_l2_all_hits + dcache_l2_all_miss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  * DCache_L2_Hits     = d_ratio(dcache_l2_all_hits, dcache_l2_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  * DCache_L2_Misses   = d_ratio(dcache_l2_all_miss, dcache_l2_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  * l2_rqsts.demand_data_rd_hit = 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  * l2_rqsts.pf_hit             = 200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  * l2_rqsts.rfo_hi             = 300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  * l2_rqsts.all_demand_data_rd = 400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  * l2_rqsts.pf_miss            = 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  * l2_rqsts.rfo_miss           = 600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  * DCache_L2_All_Hits = 600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  * DCache_L2_All_Miss = MAX(400 - 100, 0) + 500 + 600 = 1400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  * DCache_L2_All      = 600 + 1400  = 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * DCache_L2_Hits     = 600 / 2000  = 0.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  * DCache_L2_Misses   = 1400 / 2000 = 0.7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static int test_dcache_l2(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	double ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	struct value vals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		{ .event = "l2_rqsts.demand_data_rd_hit", .val = 100 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		{ .event = "l2_rqsts.pf_hit",             .val = 200 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		{ .event = "l2_rqsts.rfo_hit",            .val = 300 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		{ .event = "l2_rqsts.all_demand_data_rd", .val = 400 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		{ .event = "l2_rqsts.pf_miss",            .val = 500 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		{ .event = "l2_rqsts.rfo_miss",           .val = 600 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		{ .event = NULL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	TEST_ASSERT_VAL("failed to compute metric",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			compute_metric("DCache_L2_Hits", vals, &ratio) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	TEST_ASSERT_VAL("DCache_L2_Hits failed, wrong ratio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 			ratio == 0.3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	TEST_ASSERT_VAL("failed to compute metric",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			compute_metric("DCache_L2_Misses", vals, &ratio) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	TEST_ASSERT_VAL("DCache_L2_Misses failed, wrong ratio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			ratio == 0.7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int test_recursion_fail(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	double ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	struct value vals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		{ .event = "inst_retired.any",        .val = 300 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		{ .event = "cpu_clk_unhalted.thread", .val = 200 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		{ .event = NULL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	TEST_ASSERT_VAL("failed to find recursion",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			compute_metric("M1", vals, &ratio) == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	TEST_ASSERT_VAL("failed to find recursion",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			compute_metric("M3", vals, &ratio) == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int test_metric_group(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	double ratio1, ratio2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	struct value vals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		{ .event = "cpu_clk_unhalted.thread", .val = 200 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		{ .event = "l1d-loads-misses",        .val = 300 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		{ .event = "l1i-loads-misses",        .val = 200 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		{ .event = "inst_retired.any",        .val = 400 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		{ .event = NULL, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	TEST_ASSERT_VAL("failed to find recursion",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			compute_metric_group("group1", vals,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 					     "IPC", &ratio1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 					     "cache_miss_cycles", &ratio2) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	TEST_ASSERT_VAL("group IPC failed, wrong ratio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			ratio1 == 2.0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	TEST_ASSERT_VAL("group cache_miss_cycles failed, wrong ratio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			ratio2 == 1.25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int test__parse_metric(struct test *test __maybe_unused, int subtest __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	TEST_ASSERT_VAL("IPC failed", test_ipc() == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	TEST_ASSERT_VAL("frontend failed", test_frontend() == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	TEST_ASSERT_VAL("cache_miss_cycles failed", test_cache_miss_cycles() == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	TEST_ASSERT_VAL("DCache_L2 failed", test_dcache_l2() == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	TEST_ASSERT_VAL("recursion fail failed", test_recursion_fail() == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	TEST_ASSERT_VAL("test metric group", test_metric_group() == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }