xref: /linux/tools/perf/util/metricgroup.c (revision c717993dd76a1049093af5c262e751d901b8da10)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Copyright (c) 2017, Intel Corporation.
4   */
5  
6  /* Manage metrics and groups of metrics from JSON files */
7  
8  #include "metricgroup.h"
9  #include "debug.h"
10  #include "evlist.h"
11  #include "evsel.h"
12  #include "strbuf.h"
13  #include "pmu.h"
14  #include "pmu-hybrid.h"
15  #include "expr.h"
16  #include "rblist.h"
17  #include <string.h>
18  #include <errno.h>
19  #include "strlist.h"
20  #include <assert.h>
21  #include <linux/ctype.h>
22  #include <linux/list_sort.h>
23  #include <linux/string.h>
24  #include <linux/zalloc.h>
25  #include <subcmd/parse-options.h>
26  #include <api/fs/fs.h>
27  #include "util.h"
28  #include <asm/bug.h>
29  #include "cgroup.h"
30  
31  struct metric_event *metricgroup__lookup(struct rblist *metric_events,
32  					 struct evsel *evsel,
33  					 bool create)
34  {
35  	struct rb_node *nd;
36  	struct metric_event me = {
37  		.evsel = evsel
38  	};
39  
40  	if (!metric_events)
41  		return NULL;
42  
43  	nd = rblist__find(metric_events, &me);
44  	if (nd)
45  		return container_of(nd, struct metric_event, nd);
46  	if (create) {
47  		rblist__add_node(metric_events, &me);
48  		nd = rblist__find(metric_events, &me);
49  		if (nd)
50  			return container_of(nd, struct metric_event, nd);
51  	}
52  	return NULL;
53  }
54  
55  static int metric_event_cmp(struct rb_node *rb_node, const void *entry)
56  {
57  	struct metric_event *a = container_of(rb_node,
58  					      struct metric_event,
59  					      nd);
60  	const struct metric_event *b = entry;
61  
62  	if (a->evsel == b->evsel)
63  		return 0;
64  	if ((char *)a->evsel < (char *)b->evsel)
65  		return -1;
66  	return +1;
67  }
68  
69  static struct rb_node *metric_event_new(struct rblist *rblist __maybe_unused,
70  					const void *entry)
71  {
72  	struct metric_event *me = malloc(sizeof(struct metric_event));
73  
74  	if (!me)
75  		return NULL;
76  	memcpy(me, entry, sizeof(struct metric_event));
77  	me->evsel = ((struct metric_event *)entry)->evsel;
78  	INIT_LIST_HEAD(&me->head);
79  	return &me->nd;
80  }
81  
82  static void metric_event_delete(struct rblist *rblist __maybe_unused,
83  				struct rb_node *rb_node)
84  {
85  	struct metric_event *me = container_of(rb_node, struct metric_event, nd);
86  	struct metric_expr *expr, *tmp;
87  
88  	list_for_each_entry_safe(expr, tmp, &me->head, nd) {
89  		free((char *)expr->metric_name);
90  		free(expr->metric_refs);
91  		free(expr->metric_events);
92  		free(expr);
93  	}
94  
95  	free(me);
96  }
97  
98  static void metricgroup__rblist_init(struct rblist *metric_events)
99  {
100  	rblist__init(metric_events);
101  	metric_events->node_cmp = metric_event_cmp;
102  	metric_events->node_new = metric_event_new;
103  	metric_events->node_delete = metric_event_delete;
104  }
105  
106  void metricgroup__rblist_exit(struct rblist *metric_events)
107  {
108  	rblist__exit(metric_events);
109  }
110  
111  /*
112   * A node in the list of referenced metrics. metric_expr
113   * is held as a convenience to avoid a search through the
114   * metric list.
115   */
116  struct metric_ref_node {
117  	const char *metric_name;
118  	const char *metric_expr;
119  	struct list_head list;
120  };
121  
122  /**
123   * The metric under construction. The data held here will be placed in a
124   * metric_expr.
125   */
126  struct metric {
127  	struct list_head nd;
128  	/**
129  	 * The expression parse context importantly holding the IDs contained
130  	 * within the expression.
131  	 */
132  	struct expr_parse_ctx *pctx;
133  	/** The name of the metric such as "IPC". */
134  	const char *metric_name;
135  	/** Modifier on the metric such as "u" or NULL for none. */
136  	const char *modifier;
137  	/** The expression to parse, for example, "instructions/cycles". */
138  	const char *metric_expr;
139  	/**
140  	 * The "ScaleUnit" that scales and adds a unit to the metric during
141  	 * output.
142  	 */
143  	const char *metric_unit;
144  	/** Optional null terminated array of referenced metrics. */
145  	struct metric_ref *metric_refs;
146  	/**
147  	 * Is there a constraint on the group of events? In which case the
148  	 * events won't be grouped.
149  	 */
150  	bool has_constraint;
151  	/**
152  	 * Parsed events for the metric. Optional as events may be taken from a
153  	 * different metric whose group contains all the IDs necessary for this
154  	 * one.
155  	 */
156  	struct evlist *evlist;
157  };
158  
159  static void metricgroup___watchdog_constraint_hint(const char *name, bool foot)
160  {
161  	static bool violate_nmi_constraint;
162  
163  	if (!foot) {
164  		pr_warning("Splitting metric group %s into standalone metrics.\n", name);
165  		violate_nmi_constraint = true;
166  		return;
167  	}
168  
169  	if (!violate_nmi_constraint)
170  		return;
171  
172  	pr_warning("Try disabling the NMI watchdog to comply NO_NMI_WATCHDOG metric constraint:\n"
173  		   "    echo 0 > /proc/sys/kernel/nmi_watchdog\n"
174  		   "    perf stat ...\n"
175  		   "    echo 1 > /proc/sys/kernel/nmi_watchdog\n");
176  }
177  
178  static bool metricgroup__has_constraint(const struct pmu_event *pe)
179  {
180  	if (!pe->metric_constraint)
181  		return false;
182  
183  	if (!strcmp(pe->metric_constraint, "NO_NMI_WATCHDOG") &&
184  	    sysctl__nmi_watchdog_enabled()) {
185  		metricgroup___watchdog_constraint_hint(pe->metric_name, false);
186  		return true;
187  	}
188  
189  	return false;
190  }
191  
192  static struct metric *metric__new(const struct pmu_event *pe,
193  				  const char *modifier,
194  				  bool metric_no_group,
195  				  int runtime)
196  {
197  	struct metric *m;
198  
199  	m = zalloc(sizeof(*m));
200  	if (!m)
201  		return NULL;
202  
203  	m->pctx = expr__ctx_new();
204  	if (!m->pctx) {
205  		free(m);
206  		return NULL;
207  	}
208  
209  	m->metric_name = pe->metric_name;
210  	m->modifier = modifier ? strdup(modifier) : NULL;
211  	if (modifier && !m->modifier) {
212  		expr__ctx_free(m->pctx);
213  		free(m);
214  		return NULL;
215  	}
216  	m->metric_expr = pe->metric_expr;
217  	m->metric_unit = pe->unit;
218  	m->pctx->runtime = runtime;
219  	m->has_constraint = metric_no_group || metricgroup__has_constraint(pe);
220  	m->metric_refs = NULL;
221  	m->evlist = NULL;
222  
223  	return m;
224  }
225  
226  static void metric__free(struct metric *m)
227  {
228  	free(m->metric_refs);
229  	expr__ctx_free(m->pctx);
230  	free((char *)m->modifier);
231  	evlist__delete(m->evlist);
232  	free(m);
233  }
234  
235  static bool contains_metric_id(struct evsel **metric_events, int num_events,
236  			       const char *metric_id)
237  {
238  	int i;
239  
240  	for (i = 0; i < num_events; i++) {
241  		if (!strcmp(evsel__metric_id(metric_events[i]), metric_id))
242  			return true;
243  	}
244  	return false;
245  }
246  
247  /**
248   * setup_metric_events - Find a group of events in metric_evlist that correspond
249   *                       to the IDs from a parsed metric expression.
250   * @ids: the metric IDs to match.
251   * @metric_evlist: the list of perf events.
252   * @out_metric_events: holds the created metric events array.
253   */
254  static int setup_metric_events(struct hashmap *ids,
255  			       struct evlist *metric_evlist,
256  			       struct evsel ***out_metric_events)
257  {
258  	struct evsel **metric_events;
259  	const char *metric_id;
260  	struct evsel *ev;
261  	size_t ids_size, matched_events, i;
262  
263  	*out_metric_events = NULL;
264  	ids_size = hashmap__size(ids);
265  
266  	metric_events = calloc(sizeof(void *), ids_size + 1);
267  	if (!metric_events)
268  		return -ENOMEM;
269  
270  	matched_events = 0;
271  	evlist__for_each_entry(metric_evlist, ev) {
272  		struct expr_id_data *val_ptr;
273  
274  		/*
275  		 * Check for duplicate events with the same name. For
276  		 * example, uncore_imc/cas_count_read/ will turn into 6
277  		 * events per socket on skylakex. Only the first such
278  		 * event is placed in metric_events.
279  		 */
280  		metric_id = evsel__metric_id(ev);
281  		if (contains_metric_id(metric_events, matched_events, metric_id))
282  			continue;
283  		/*
284  		 * Does this event belong to the parse context? For
285  		 * combined or shared groups, this metric may not care
286  		 * about this event.
287  		 */
288  		if (hashmap__find(ids, metric_id, (void **)&val_ptr)) {
289  			metric_events[matched_events++] = ev;
290  
291  			if (matched_events >= ids_size)
292  				break;
293  		}
294  	}
295  	if (matched_events < ids_size) {
296  		free(metric_events);
297  		return -EINVAL;
298  	}
299  	for (i = 0; i < ids_size; i++) {
300  		ev = metric_events[i];
301  		ev->collect_stat = true;
302  
303  		/*
304  		 * The metric leader points to the identically named
305  		 * event in metric_events.
306  		 */
307  		ev->metric_leader = ev;
308  		/*
309  		 * Mark two events with identical names in the same
310  		 * group (or globally) as being in use as uncore events
311  		 * may be duplicated for each pmu. Set the metric leader
312  		 * of such events to be the event that appears in
313  		 * metric_events.
314  		 */
315  		metric_id = evsel__metric_id(ev);
316  		evlist__for_each_entry_continue(metric_evlist, ev) {
317  			if (!strcmp(evsel__metric_id(ev), metric_id))
318  				ev->metric_leader = metric_events[i];
319  		}
320  	}
321  	*out_metric_events = metric_events;
322  	return 0;
323  }
324  
325  static bool match_metric(const char *n, const char *list)
326  {
327  	int len;
328  	char *m;
329  
330  	if (!list)
331  		return false;
332  	if (!strcmp(list, "all"))
333  		return true;
334  	if (!n)
335  		return !strcasecmp(list, "No_group");
336  	len = strlen(list);
337  	m = strcasestr(n, list);
338  	if (!m)
339  		return false;
340  	if ((m == n || m[-1] == ';' || m[-1] == ' ') &&
341  	    (m[len] == 0 || m[len] == ';'))
342  		return true;
343  	return false;
344  }
345  
346  static bool match_pe_metric(const struct pmu_event *pe, const char *metric)
347  {
348  	return match_metric(pe->metric_group, metric) ||
349  	       match_metric(pe->metric_name, metric);
350  }
351  
352  struct mep {
353  	struct rb_node nd;
354  	const char *name;
355  	struct strlist *metrics;
356  };
357  
358  static int mep_cmp(struct rb_node *rb_node, const void *entry)
359  {
360  	struct mep *a = container_of(rb_node, struct mep, nd);
361  	struct mep *b = (struct mep *)entry;
362  
363  	return strcmp(a->name, b->name);
364  }
365  
366  static struct rb_node *mep_new(struct rblist *rl __maybe_unused,
367  					const void *entry)
368  {
369  	struct mep *me = malloc(sizeof(struct mep));
370  
371  	if (!me)
372  		return NULL;
373  	memcpy(me, entry, sizeof(struct mep));
374  	me->name = strdup(me->name);
375  	if (!me->name)
376  		goto out_me;
377  	me->metrics = strlist__new(NULL, NULL);
378  	if (!me->metrics)
379  		goto out_name;
380  	return &me->nd;
381  out_name:
382  	zfree(&me->name);
383  out_me:
384  	free(me);
385  	return NULL;
386  }
387  
388  static struct mep *mep_lookup(struct rblist *groups, const char *name)
389  {
390  	struct rb_node *nd;
391  	struct mep me = {
392  		.name = name
393  	};
394  	nd = rblist__find(groups, &me);
395  	if (nd)
396  		return container_of(nd, struct mep, nd);
397  	rblist__add_node(groups, &me);
398  	nd = rblist__find(groups, &me);
399  	if (nd)
400  		return container_of(nd, struct mep, nd);
401  	return NULL;
402  }
403  
404  static void mep_delete(struct rblist *rl __maybe_unused,
405  		       struct rb_node *nd)
406  {
407  	struct mep *me = container_of(nd, struct mep, nd);
408  
409  	strlist__delete(me->metrics);
410  	zfree(&me->name);
411  	free(me);
412  }
413  
414  static void metricgroup__print_strlist(struct strlist *metrics, bool raw)
415  {
416  	struct str_node *sn;
417  	int n = 0;
418  
419  	strlist__for_each_entry (sn, metrics) {
420  		if (raw)
421  			printf("%s%s", n > 0 ? " " : "", sn->s);
422  		else
423  			printf("  %s\n", sn->s);
424  		n++;
425  	}
426  	if (raw)
427  		putchar('\n');
428  }
429  
430  static int metricgroup__print_pmu_event(const struct pmu_event *pe,
431  					bool metricgroups, char *filter,
432  					bool raw, bool details,
433  					struct rblist *groups,
434  					struct strlist *metriclist)
435  {
436  	const char *g;
437  	char *omg, *mg;
438  
439  	g = pe->metric_group;
440  	if (!g && pe->metric_name) {
441  		if (pe->name)
442  			return 0;
443  		g = "No_group";
444  	}
445  
446  	if (!g)
447  		return 0;
448  
449  	mg = strdup(g);
450  
451  	if (!mg)
452  		return -ENOMEM;
453  	omg = mg;
454  	while ((g = strsep(&mg, ";")) != NULL) {
455  		struct mep *me;
456  		char *s;
457  
458  		g = skip_spaces(g);
459  		if (*g == 0)
460  			g = "No_group";
461  		if (filter && !strstr(g, filter))
462  			continue;
463  		if (raw)
464  			s = (char *)pe->metric_name;
465  		else {
466  			if (asprintf(&s, "%s\n%*s%s]",
467  				     pe->metric_name, 8, "[", pe->desc) < 0)
468  				return -1;
469  			if (details) {
470  				if (asprintf(&s, "%s\n%*s%s]",
471  					     s, 8, "[", pe->metric_expr) < 0)
472  					return -1;
473  			}
474  		}
475  
476  		if (!s)
477  			continue;
478  
479  		if (!metricgroups) {
480  			strlist__add(metriclist, s);
481  		} else {
482  			me = mep_lookup(groups, g);
483  			if (!me)
484  				continue;
485  			strlist__add(me->metrics, s);
486  		}
487  
488  		if (!raw)
489  			free(s);
490  	}
491  	free(omg);
492  
493  	return 0;
494  }
495  
496  struct metricgroup_print_sys_idata {
497  	struct strlist *metriclist;
498  	char *filter;
499  	struct rblist *groups;
500  	bool metricgroups;
501  	bool raw;
502  	bool details;
503  };
504  
505  typedef int (*metricgroup_sys_event_iter_fn)(const struct pmu_event *pe, void *);
506  
507  struct metricgroup_iter_data {
508  	metricgroup_sys_event_iter_fn fn;
509  	void *data;
510  };
511  
512  static int metricgroup__sys_event_iter(const struct pmu_event *pe, void *data)
513  {
514  	struct metricgroup_iter_data *d = data;
515  	struct perf_pmu *pmu = NULL;
516  
517  	if (!pe->metric_expr || !pe->compat)
518  		return 0;
519  
520  	while ((pmu = perf_pmu__scan(pmu))) {
521  
522  		if (!pmu->id || strcmp(pmu->id, pe->compat))
523  			continue;
524  
525  		return d->fn(pe, d->data);
526  	}
527  
528  	return 0;
529  }
530  
531  static int metricgroup__print_sys_event_iter(const struct pmu_event *pe, void *data)
532  {
533  	struct metricgroup_print_sys_idata *d = data;
534  
535  	return metricgroup__print_pmu_event(pe, d->metricgroups, d->filter, d->raw,
536  				     d->details, d->groups, d->metriclist);
537  }
538  
539  void metricgroup__print(bool metrics, bool metricgroups, char *filter,
540  			bool raw, bool details, const char *pmu_name)
541  {
542  	const struct pmu_events_map *map = pmu_events_map__find();
543  	const struct pmu_event *pe;
544  	int i;
545  	struct rblist groups;
546  	struct rb_node *node, *next;
547  	struct strlist *metriclist = NULL;
548  
549  	if (!metricgroups) {
550  		metriclist = strlist__new(NULL, NULL);
551  		if (!metriclist)
552  			return;
553  	}
554  
555  	rblist__init(&groups);
556  	groups.node_new = mep_new;
557  	groups.node_cmp = mep_cmp;
558  	groups.node_delete = mep_delete;
559  	for (i = 0; map; i++) {
560  		pe = &map->table[i];
561  
562  		if (!pe->name && !pe->metric_group && !pe->metric_name)
563  			break;
564  		if (!pe->metric_expr)
565  			continue;
566  		if (pmu_name && perf_pmu__is_hybrid(pe->pmu) &&
567  		    strcmp(pmu_name, pe->pmu)) {
568  			continue;
569  		}
570  		if (metricgroup__print_pmu_event(pe, metricgroups, filter,
571  						 raw, details, &groups,
572  						 metriclist) < 0)
573  			return;
574  	}
575  
576  	{
577  		struct metricgroup_iter_data data = {
578  			.fn = metricgroup__print_sys_event_iter,
579  			.data = (void *) &(struct metricgroup_print_sys_idata){
580  				.metriclist = metriclist,
581  				.metricgroups = metricgroups,
582  				.filter = filter,
583  				.raw = raw,
584  				.details = details,
585  				.groups = &groups,
586  			},
587  		};
588  
589  		pmu_for_each_sys_event(metricgroup__sys_event_iter, &data);
590  	}
591  
592  	if (!filter || !rblist__empty(&groups)) {
593  		if (metricgroups && !raw)
594  			printf("\nMetric Groups:\n\n");
595  		else if (metrics && !raw)
596  			printf("\nMetrics:\n\n");
597  	}
598  
599  	for (node = rb_first_cached(&groups.entries); node; node = next) {
600  		struct mep *me = container_of(node, struct mep, nd);
601  
602  		if (metricgroups)
603  			printf("%s%s%s", me->name, metrics && !raw ? ":" : "", raw ? " " : "\n");
604  		if (metrics)
605  			metricgroup__print_strlist(me->metrics, raw);
606  		next = rb_next(node);
607  		rblist__remove_node(&groups, node);
608  	}
609  	if (!metricgroups)
610  		metricgroup__print_strlist(metriclist, raw);
611  	strlist__delete(metriclist);
612  }
613  
614  static const char *code_characters = ",-=@";
615  
616  static int encode_metric_id(struct strbuf *sb, const char *x)
617  {
618  	char *c;
619  	int ret = 0;
620  
621  	for (; *x; x++) {
622  		c = strchr(code_characters, *x);
623  		if (c) {
624  			ret = strbuf_addch(sb, '!');
625  			if (ret)
626  				break;
627  
628  			ret = strbuf_addch(sb, '0' + (c - code_characters));
629  			if (ret)
630  				break;
631  		} else {
632  			ret = strbuf_addch(sb, *x);
633  			if (ret)
634  				break;
635  		}
636  	}
637  	return ret;
638  }
639  
640  static int decode_metric_id(struct strbuf *sb, const char *x)
641  {
642  	const char *orig = x;
643  	size_t i;
644  	char c;
645  	int ret;
646  
647  	for (; *x; x++) {
648  		c = *x;
649  		if (*x == '!') {
650  			x++;
651  			i = *x - '0';
652  			if (i > strlen(code_characters)) {
653  				pr_err("Bad metric-id encoding in: '%s'", orig);
654  				return -1;
655  			}
656  			c = code_characters[i];
657  		}
658  		ret = strbuf_addch(sb, c);
659  		if (ret)
660  			return ret;
661  	}
662  	return 0;
663  }
664  
665  static int decode_all_metric_ids(struct evlist *perf_evlist, const char *modifier)
666  {
667  	struct evsel *ev;
668  	struct strbuf sb = STRBUF_INIT;
669  	char *cur;
670  	int ret = 0;
671  
672  	evlist__for_each_entry(perf_evlist, ev) {
673  		if (!ev->metric_id)
674  			continue;
675  
676  		ret = strbuf_setlen(&sb, 0);
677  		if (ret)
678  			break;
679  
680  		ret = decode_metric_id(&sb, ev->metric_id);
681  		if (ret)
682  			break;
683  
684  		free((char *)ev->metric_id);
685  		ev->metric_id = strdup(sb.buf);
686  		if (!ev->metric_id) {
687  			ret = -ENOMEM;
688  			break;
689  		}
690  		/*
691  		 * If the name is just the parsed event, use the metric-id to
692  		 * give a more friendly display version.
693  		 */
694  		if (strstr(ev->name, "metric-id=")) {
695  			bool has_slash = false;
696  
697  			free(ev->name);
698  			for (cur = strchr(sb.buf, '@') ; cur; cur = strchr(++cur, '@')) {
699  				*cur = '/';
700  				has_slash = true;
701  			}
702  
703  			if (modifier) {
704  				if (!has_slash && !strchr(sb.buf, ':')) {
705  					ret = strbuf_addch(&sb, ':');
706  					if (ret)
707  						break;
708  				}
709  				ret = strbuf_addstr(&sb, modifier);
710  				if (ret)
711  					break;
712  			}
713  			ev->name = strdup(sb.buf);
714  			if (!ev->name) {
715  				ret = -ENOMEM;
716  				break;
717  			}
718  		}
719  	}
720  	strbuf_release(&sb);
721  	return ret;
722  }
723  
724  static int metricgroup__build_event_string(struct strbuf *events,
725  					   const struct expr_parse_ctx *ctx,
726  					   const char *modifier,
727  					   bool has_constraint)
728  {
729  	struct hashmap_entry *cur;
730  	size_t bkt;
731  	bool no_group = true, has_duration = false;
732  	int ret = 0;
733  
734  #define RETURN_IF_NON_ZERO(x) do { if (x) return x; } while (0)
735  
736  	hashmap__for_each_entry(ctx->ids, cur, bkt) {
737  		const char *sep, *rsep, *id = cur->key;
738  
739  		pr_debug("found event %s\n", id);
740  		/*
741  		 * Duration time maps to a software event and can make
742  		 * groups not count. Always use it outside a
743  		 * group.
744  		 */
745  		if (!strcmp(id, "duration_time")) {
746  			has_duration = true;
747  			continue;
748  		}
749  		/* Separate events with commas and open the group if necessary. */
750  		if (no_group) {
751  			if (!has_constraint) {
752  				ret = strbuf_addch(events, '{');
753  				RETURN_IF_NON_ZERO(ret);
754  			}
755  
756  			no_group = false;
757  		} else {
758  			ret = strbuf_addch(events, ',');
759  			RETURN_IF_NON_ZERO(ret);
760  		}
761  		/*
762  		 * Encode the ID as an event string. Add a qualifier for
763  		 * metric_id that is the original name except with characters
764  		 * that parse-events can't parse replaced. For example,
765  		 * 'msr@tsc@' gets added as msr/tsc,metric-id=msr!3tsc!3/
766  		 */
767  		sep = strchr(id, '@');
768  		if (sep != NULL) {
769  			ret = strbuf_add(events, id, sep - id);
770  			RETURN_IF_NON_ZERO(ret);
771  			ret = strbuf_addch(events, '/');
772  			RETURN_IF_NON_ZERO(ret);
773  			rsep = strrchr(sep, '@');
774  			ret = strbuf_add(events, sep + 1, rsep - sep - 1);
775  			RETURN_IF_NON_ZERO(ret);
776  			ret = strbuf_addstr(events, ",metric-id=");
777  			RETURN_IF_NON_ZERO(ret);
778  			sep = rsep;
779  		} else {
780  			sep = strchr(id, ':');
781  			if (sep != NULL) {
782  				ret = strbuf_add(events, id, sep - id);
783  				RETURN_IF_NON_ZERO(ret);
784  			} else {
785  				ret = strbuf_addstr(events, id);
786  				RETURN_IF_NON_ZERO(ret);
787  			}
788  			ret = strbuf_addstr(events, "/metric-id=");
789  			RETURN_IF_NON_ZERO(ret);
790  		}
791  		ret = encode_metric_id(events, id);
792  		RETURN_IF_NON_ZERO(ret);
793  		ret = strbuf_addstr(events, "/");
794  		RETURN_IF_NON_ZERO(ret);
795  
796  		if (sep != NULL) {
797  			ret = strbuf_addstr(events, sep + 1);
798  			RETURN_IF_NON_ZERO(ret);
799  		}
800  		if (modifier) {
801  			ret = strbuf_addstr(events, modifier);
802  			RETURN_IF_NON_ZERO(ret);
803  		}
804  	}
805  	if (has_duration) {
806  		if (no_group) {
807  			/* Strange case of a metric of just duration_time. */
808  			ret = strbuf_addf(events, "duration_time");
809  		} else if (!has_constraint)
810  			ret = strbuf_addf(events, "}:W,duration_time");
811  		else
812  			ret = strbuf_addf(events, ",duration_time");
813  	} else if (!no_group && !has_constraint)
814  		ret = strbuf_addf(events, "}:W");
815  
816  	return ret;
817  #undef RETURN_IF_NON_ZERO
818  }
819  
820  int __weak arch_get_runtimeparam(const struct pmu_event *pe __maybe_unused)
821  {
822  	return 1;
823  }
824  
825  /*
826   * A singly linked list on the stack of the names of metrics being
827   * processed. Used to identify recursion.
828   */
829  struct visited_metric {
830  	const char *name;
831  	const struct visited_metric *parent;
832  };
833  
834  struct metricgroup_add_iter_data {
835  	struct list_head *metric_list;
836  	const char *metric_name;
837  	const char *modifier;
838  	int *ret;
839  	bool *has_match;
840  	bool metric_no_group;
841  	struct metric *root_metric;
842  	const struct visited_metric *visited;
843  	const struct pmu_events_map *map;
844  };
845  
846  static int add_metric(struct list_head *metric_list,
847  		      const struct pmu_event *pe,
848  		      const char *modifier,
849  		      bool metric_no_group,
850  		      struct metric *root_metric,
851  		      const struct visited_metric *visited,
852  		      const struct pmu_events_map *map);
853  
854  /**
855   * resolve_metric - Locate metrics within the root metric and recursively add
856   *                    references to them.
857   * @metric_list: The list the metric is added to.
858   * @modifier: if non-null event modifiers like "u".
859   * @metric_no_group: Should events written to events be grouped "{}" or
860   *                   global. Grouping is the default but due to multiplexing the
861   *                   user may override.
862   * @root_metric: Metrics may reference other metrics to form a tree. In this
863   *               case the root_metric holds all the IDs and a list of referenced
864   *               metrics. When adding a root this argument is NULL.
865   * @visited: A singly linked list of metric names being added that is used to
866   *           detect recursion.
867   * @map: The map that is searched for metrics, most commonly the table for the
868   *       architecture perf is running upon.
869   */
870  static int resolve_metric(struct list_head *metric_list,
871  			  const char *modifier,
872  			  bool metric_no_group,
873  			  struct metric *root_metric,
874  			  const struct visited_metric *visited,
875  			  const struct pmu_events_map *map)
876  {
877  	struct hashmap_entry *cur;
878  	size_t bkt;
879  	struct to_resolve {
880  		/* The metric to resolve. */
881  		const struct pmu_event *pe;
882  		/*
883  		 * The key in the IDs map, this may differ from in case,
884  		 * etc. from pe->metric_name.
885  		 */
886  		const char *key;
887  	} *pending = NULL;
888  	int i, ret = 0, pending_cnt = 0;
889  
890  	/*
891  	 * Iterate all the parsed IDs and if there's a matching metric and it to
892  	 * the pending array.
893  	 */
894  	hashmap__for_each_entry(root_metric->pctx->ids, cur, bkt) {
895  		const struct pmu_event *pe;
896  
897  		pe = metricgroup__find_metric(cur->key, map);
898  		if (pe) {
899  			pending = realloc(pending,
900  					(pending_cnt + 1) * sizeof(struct to_resolve));
901  			if (!pending)
902  				return -ENOMEM;
903  
904  			pending[pending_cnt].pe = pe;
905  			pending[pending_cnt].key = cur->key;
906  			pending_cnt++;
907  		}
908  	}
909  
910  	/* Remove the metric IDs from the context. */
911  	for (i = 0; i < pending_cnt; i++)
912  		expr__del_id(root_metric->pctx, pending[i].key);
913  
914  	/*
915  	 * Recursively add all the metrics, IDs are added to the root metric's
916  	 * context.
917  	 */
918  	for (i = 0; i < pending_cnt; i++) {
919  		ret = add_metric(metric_list, pending[i].pe, modifier, metric_no_group,
920  				root_metric, visited, map);
921  		if (ret)
922  			break;
923  	}
924  
925  	free(pending);
926  	return ret;
927  }
928  
929  /**
930   * __add_metric - Add a metric to metric_list.
931   * @metric_list: The list the metric is added to.
932   * @pe: The pmu_event containing the metric to be added.
933   * @modifier: if non-null event modifiers like "u".
934   * @metric_no_group: Should events written to events be grouped "{}" or
935   *                   global. Grouping is the default but due to multiplexing the
936   *                   user may override.
937   * @runtime: A special argument for the parser only known at runtime.
938   * @root_metric: Metrics may reference other metrics to form a tree. In this
939   *               case the root_metric holds all the IDs and a list of referenced
940   *               metrics. When adding a root this argument is NULL.
941   * @visited: A singly linked list of metric names being added that is used to
942   *           detect recursion.
943   * @map: The map that is searched for metrics, most commonly the table for the
944   *       architecture perf is running upon.
945   */
946  static int __add_metric(struct list_head *metric_list,
947  			const struct pmu_event *pe,
948  			const char *modifier,
949  			bool metric_no_group,
950  			int runtime,
951  			struct metric *root_metric,
952  			const struct visited_metric *visited,
953  			const struct pmu_events_map *map)
954  {
955  	const struct visited_metric *vm;
956  	int ret;
957  	bool is_root = !root_metric;
958  	struct visited_metric visited_node = {
959  		.name = pe->metric_name,
960  		.parent = visited,
961  	};
962  
963  	for (vm = visited; vm; vm = vm->parent) {
964  		if (!strcmp(pe->metric_name, vm->name)) {
965  			pr_err("failed: recursion detected for %s\n", pe->metric_name);
966  			return -1;
967  		}
968  	}
969  
970  	if (is_root) {
971  		/*
972  		 * This metric is the root of a tree and may reference other
973  		 * metrics that are added recursively.
974  		 */
975  		root_metric = metric__new(pe, modifier, metric_no_group, runtime);
976  		if (!root_metric)
977  			return -ENOMEM;
978  
979  	} else {
980  		int cnt = 0;
981  
982  		/*
983  		 * This metric was referenced in a metric higher in the
984  		 * tree. Check if the same metric is already resolved in the
985  		 * metric_refs list.
986  		 */
987  		if (root_metric->metric_refs) {
988  			for (; root_metric->metric_refs[cnt].metric_name; cnt++) {
989  				if (!strcmp(pe->metric_name,
990  					    root_metric->metric_refs[cnt].metric_name))
991  					return 0;
992  			}
993  		}
994  
995  		/* Create reference. Need space for the entry and the terminator. */
996  		root_metric->metric_refs = realloc(root_metric->metric_refs,
997  						(cnt + 2) * sizeof(struct metric_ref));
998  		if (!root_metric->metric_refs)
999  			return -ENOMEM;
1000  
1001  		/*
1002  		 * Intentionally passing just const char pointers,
1003  		 * from 'pe' object, so they never go away. We don't
1004  		 * need to change them, so there's no need to create
1005  		 * our own copy.
1006  		 */
1007  		root_metric->metric_refs[cnt].metric_name = pe->metric_name;
1008  		root_metric->metric_refs[cnt].metric_expr = pe->metric_expr;
1009  
1010  		/* Null terminate array. */
1011  		root_metric->metric_refs[cnt+1].metric_name = NULL;
1012  		root_metric->metric_refs[cnt+1].metric_expr = NULL;
1013  	}
1014  
1015  	/*
1016  	 * For both the parent and referenced metrics, we parse
1017  	 * all the metric's IDs and add it to the root context.
1018  	 */
1019  	if (expr__find_ids(pe->metric_expr, NULL, root_metric->pctx) < 0) {
1020  		/* Broken metric. */
1021  		ret = -EINVAL;
1022  	} else {
1023  		/* Resolve referenced metrics. */
1024  		ret = resolve_metric(metric_list, modifier, metric_no_group, root_metric,
1025  				     &visited_node, map);
1026  	}
1027  
1028  	if (ret) {
1029  		if (is_root)
1030  			metric__free(root_metric);
1031  
1032  	} else if (is_root)
1033  		list_add(&root_metric->nd, metric_list);
1034  
1035  	return ret;
1036  }
1037  
1038  #define map_for_each_event(__pe, __idx, __map)					\
1039  	if (__map)								\
1040  		for (__idx = 0, __pe = &__map->table[__idx];			\
1041  		     __pe->name || __pe->metric_group || __pe->metric_name;	\
1042  		     __pe = &__map->table[++__idx])
1043  
1044  #define map_for_each_metric(__pe, __idx, __map, __metric)		\
1045  	map_for_each_event(__pe, __idx, __map)				\
1046  		if (__pe->metric_expr &&				\
1047  		    (match_metric(__pe->metric_group, __metric) ||	\
1048  		     match_metric(__pe->metric_name, __metric)))
1049  
1050  const struct pmu_event *metricgroup__find_metric(const char *metric,
1051  						 const struct pmu_events_map *map)
1052  {
1053  	const struct pmu_event *pe;
1054  	int i;
1055  
1056  	map_for_each_event(pe, i, map) {
1057  		if (match_metric(pe->metric_name, metric))
1058  			return pe;
1059  	}
1060  
1061  	return NULL;
1062  }
1063  
1064  static int add_metric(struct list_head *metric_list,
1065  		      const struct pmu_event *pe,
1066  		      const char *modifier,
1067  		      bool metric_no_group,
1068  		      struct metric *root_metric,
1069  		      const struct visited_metric *visited,
1070  		      const struct pmu_events_map *map)
1071  {
1072  	int ret = 0;
1073  
1074  	pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name);
1075  
1076  	if (!strstr(pe->metric_expr, "?")) {
1077  		ret = __add_metric(metric_list, pe, modifier, metric_no_group, 0,
1078  				   root_metric, visited, map);
1079  	} else {
1080  		int j, count;
1081  
1082  		count = arch_get_runtimeparam(pe);
1083  
1084  		/* This loop is added to create multiple
1085  		 * events depend on count value and add
1086  		 * those events to metric_list.
1087  		 */
1088  
1089  		for (j = 0; j < count && !ret; j++)
1090  			ret = __add_metric(metric_list, pe, modifier, metric_no_group, j,
1091  					root_metric, visited, map);
1092  	}
1093  
1094  	return ret;
1095  }
1096  
1097  static int metricgroup__add_metric_sys_event_iter(const struct pmu_event *pe,
1098  						  void *data)
1099  {
1100  	struct metricgroup_add_iter_data *d = data;
1101  	int ret;
1102  
1103  	if (!match_pe_metric(pe, d->metric_name))
1104  		return 0;
1105  
1106  	ret = add_metric(d->metric_list, pe, d->modifier, d->metric_no_group,
1107  			 d->root_metric, d->visited, d->map);
1108  	if (ret)
1109  		goto out;
1110  
1111  	*(d->has_match) = true;
1112  
1113  out:
1114  	*(d->ret) = ret;
1115  	return ret;
1116  }
1117  
1118  /**
1119   * metric_list_cmp - list_sort comparator that sorts metrics with more events to
1120   *                   the front. duration_time is excluded from the count.
1121   */
1122  static int metric_list_cmp(void *priv __maybe_unused, const struct list_head *l,
1123  			   const struct list_head *r)
1124  {
1125  	const struct metric *left = container_of(l, struct metric, nd);
1126  	const struct metric *right = container_of(r, struct metric, nd);
1127  	struct expr_id_data *data;
1128  	int left_count, right_count;
1129  
1130  	left_count = hashmap__size(left->pctx->ids);
1131  	if (!expr__get_id(left->pctx, "duration_time", &data))
1132  		left_count--;
1133  
1134  	right_count = hashmap__size(right->pctx->ids);
1135  	if (!expr__get_id(right->pctx, "duration_time", &data))
1136  		right_count--;
1137  
1138  	return right_count - left_count;
1139  }
1140  
1141  /**
1142   * metricgroup__add_metric - Find and add a metric, or a metric group.
1143   * @metric_name: The name of the metric or metric group. For example, "IPC"
1144   *               could be the name of a metric and "TopDownL1" the name of a
1145   *               metric group.
1146   * @modifier: if non-null event modifiers like "u".
1147   * @metric_no_group: Should events written to events be grouped "{}" or
1148   *                   global. Grouping is the default but due to multiplexing the
1149   *                   user may override.
1150   * @metric_list: The list that the metric or metric group are added to.
1151   * @map: The map that is searched for metrics, most commonly the table for the
1152   *       architecture perf is running upon.
1153   */
1154  static int metricgroup__add_metric(const char *metric_name, const char *modifier,
1155  				   bool metric_no_group,
1156  				   struct list_head *metric_list,
1157  				   const struct pmu_events_map *map)
1158  {
1159  	const struct pmu_event *pe;
1160  	LIST_HEAD(list);
1161  	int i, ret;
1162  	bool has_match = false;
1163  
1164  	/*
1165  	 * Iterate over all metrics seeing if metric matches either the name or
1166  	 * group. When it does add the metric to the list.
1167  	 */
1168  	map_for_each_metric(pe, i, map, metric_name) {
1169  		has_match = true;
1170  		ret = add_metric(&list, pe, modifier, metric_no_group,
1171  				 /*root_metric=*/NULL,
1172  				 /*visited_metrics=*/NULL, map);
1173  		if (ret)
1174  			goto out;
1175  	}
1176  
1177  	{
1178  		struct metricgroup_iter_data data = {
1179  			.fn = metricgroup__add_metric_sys_event_iter,
1180  			.data = (void *) &(struct metricgroup_add_iter_data) {
1181  				.metric_list = &list,
1182  				.metric_name = metric_name,
1183  				.modifier = modifier,
1184  				.metric_no_group = metric_no_group,
1185  				.has_match = &has_match,
1186  				.ret = &ret,
1187  				.map = map,
1188  			},
1189  		};
1190  
1191  		pmu_for_each_sys_event(metricgroup__sys_event_iter, &data);
1192  	}
1193  	/* End of pmu events. */
1194  	if (!has_match)
1195  		ret = -EINVAL;
1196  
1197  out:
1198  	/*
1199  	 * add to metric_list so that they can be released
1200  	 * even if it's failed
1201  	 */
1202  	list_splice(&list, metric_list);
1203  	return ret;
1204  }
1205  
1206  /**
1207   * metricgroup__add_metric_list - Find and add metrics, or metric groups,
1208   *                                specified in a list.
1209   * @list: the list of metrics or metric groups. For example, "IPC,CPI,TopDownL1"
1210   *        would match the IPC and CPI metrics, and TopDownL1 would match all
1211   *        the metrics in the TopDownL1 group.
1212   * @metric_no_group: Should events written to events be grouped "{}" or
1213   *                   global. Grouping is the default but due to multiplexing the
1214   *                   user may override.
1215   * @metric_list: The list that metrics are added to.
1216   * @map: The map that is searched for metrics, most commonly the table for the
1217   *       architecture perf is running upon.
1218   */
1219  static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
1220  					struct list_head *metric_list,
1221  					const struct pmu_events_map *map)
1222  {
1223  	char *list_itr, *list_copy, *metric_name, *modifier;
1224  	int ret, count = 0;
1225  
1226  	list_copy = strdup(list);
1227  	if (!list_copy)
1228  		return -ENOMEM;
1229  	list_itr = list_copy;
1230  
1231  	while ((metric_name = strsep(&list_itr, ",")) != NULL) {
1232  		modifier = strchr(metric_name, ':');
1233  		if (modifier)
1234  			*modifier++ = '\0';
1235  
1236  		ret = metricgroup__add_metric(metric_name, modifier,
1237  					      metric_no_group, metric_list,
1238  					      map);
1239  		if (ret == -EINVAL)
1240  			pr_err("Cannot find metric or group `%s'\n", metric_name);
1241  
1242  		if (ret)
1243  			break;
1244  
1245  		count++;
1246  	}
1247  	free(list_copy);
1248  
1249  	if (!ret) {
1250  		/*
1251  		 * Warn about nmi_watchdog if any parsed metrics had the
1252  		 * NO_NMI_WATCHDOG constraint.
1253  		 */
1254  		metricgroup___watchdog_constraint_hint(NULL, true);
1255  		/* No metrics. */
1256  		if (count == 0)
1257  			return -EINVAL;
1258  	}
1259  	return ret;
1260  }
1261  
1262  static void metricgroup__free_metrics(struct list_head *metric_list)
1263  {
1264  	struct metric *m, *tmp;
1265  
1266  	list_for_each_entry_safe (m, tmp, metric_list, nd) {
1267  		list_del_init(&m->nd);
1268  		metric__free(m);
1269  	}
1270  }
1271  
1272  /**
1273   * build_combined_expr_ctx - Make an expr_parse_ctx with all has_constraint
1274   *                           metric IDs, as the IDs are held in a set,
1275   *                           duplicates will be removed.
1276   * @metric_list: List to take metrics from.
1277   * @combined: Out argument for result.
1278   */
1279  static int build_combined_expr_ctx(const struct list_head *metric_list,
1280  				   struct expr_parse_ctx **combined)
1281  {
1282  	struct hashmap_entry *cur;
1283  	size_t bkt;
1284  	struct metric *m;
1285  	char *dup;
1286  	int ret;
1287  
1288  	*combined = expr__ctx_new();
1289  	if (!*combined)
1290  		return -ENOMEM;
1291  
1292  	list_for_each_entry(m, metric_list, nd) {
1293  		if (m->has_constraint && !m->modifier) {
1294  			hashmap__for_each_entry(m->pctx->ids, cur, bkt) {
1295  				dup = strdup(cur->key);
1296  				if (!dup) {
1297  					ret = -ENOMEM;
1298  					goto err_out;
1299  				}
1300  				ret = expr__add_id(*combined, dup);
1301  				if (ret)
1302  					goto err_out;
1303  			}
1304  		}
1305  	}
1306  	return 0;
1307  err_out:
1308  	expr__ctx_free(*combined);
1309  	*combined = NULL;
1310  	return ret;
1311  }
1312  
1313  /**
1314   * parse_ids - Build the event string for the ids and parse them creating an
1315   *             evlist. The encoded metric_ids are decoded.
1316   * @metric_no_merge: is metric sharing explicitly disabled.
1317   * @fake_pmu: used when testing metrics not supported by the current CPU.
1318   * @ids: the event identifiers parsed from a metric.
1319   * @modifier: any modifiers added to the events.
1320   * @has_constraint: false if events should be placed in a weak group.
1321   * @out_evlist: the created list of events.
1322   */
1323  static int parse_ids(bool metric_no_merge, struct perf_pmu *fake_pmu,
1324  		     struct expr_parse_ctx *ids, const char *modifier,
1325  		     bool has_constraint, struct evlist **out_evlist)
1326  {
1327  	struct parse_events_error parse_error;
1328  	struct evlist *parsed_evlist;
1329  	struct strbuf events = STRBUF_INIT;
1330  	int ret;
1331  
1332  	*out_evlist = NULL;
1333  	if (!metric_no_merge || hashmap__size(ids->ids) == 0) {
1334  		char *tmp;
1335  		/*
1336  		 * We may fail to share events between metrics because
1337  		 * duration_time isn't present in one metric. For example, a
1338  		 * ratio of cache misses doesn't need duration_time but the same
1339  		 * events may be used for a misses per second. Events without
1340  		 * sharing implies multiplexing, that is best avoided, so place
1341  		 * duration_time in every group.
1342  		 *
1343  		 * Also, there may be no ids/events in the expression parsing
1344  		 * context because of constant evaluation, e.g.:
1345  		 *    event1 if #smt_on else 0
1346  		 * Add a duration_time event to avoid a parse error on an empty
1347  		 * string.
1348  		 */
1349  		tmp = strdup("duration_time");
1350  		if (!tmp)
1351  			return -ENOMEM;
1352  
1353  		ids__insert(ids->ids, tmp);
1354  	}
1355  	ret = metricgroup__build_event_string(&events, ids, modifier,
1356  					      has_constraint);
1357  	if (ret)
1358  		return ret;
1359  
1360  	parsed_evlist = evlist__new();
1361  	if (!parsed_evlist) {
1362  		ret = -ENOMEM;
1363  		goto err_out;
1364  	}
1365  	pr_debug("Parsing metric events '%s'\n", events.buf);
1366  	parse_events_error__init(&parse_error);
1367  	ret = __parse_events(parsed_evlist, events.buf, &parse_error, fake_pmu);
1368  	if (ret) {
1369  		parse_events_error__print(&parse_error, events.buf);
1370  		goto err_out;
1371  	}
1372  	ret = decode_all_metric_ids(parsed_evlist, modifier);
1373  	if (ret)
1374  		goto err_out;
1375  
1376  	*out_evlist = parsed_evlist;
1377  	parsed_evlist = NULL;
1378  err_out:
1379  	parse_events_error__exit(&parse_error);
1380  	evlist__delete(parsed_evlist);
1381  	strbuf_release(&events);
1382  	return ret;
1383  }
1384  
1385  static int parse_groups(struct evlist *perf_evlist, const char *str,
1386  			bool metric_no_group,
1387  			bool metric_no_merge,
1388  			struct perf_pmu *fake_pmu,
1389  			struct rblist *metric_events_list,
1390  			const struct pmu_events_map *map)
1391  {
1392  	struct evlist *combined_evlist = NULL;
1393  	LIST_HEAD(metric_list);
1394  	struct metric *m;
1395  	int ret;
1396  
1397  	if (metric_events_list->nr_entries == 0)
1398  		metricgroup__rblist_init(metric_events_list);
1399  	ret = metricgroup__add_metric_list(str, metric_no_group,
1400  					   &metric_list, map);
1401  	if (ret)
1402  		goto out;
1403  
1404  	/* Sort metrics from largest to smallest. */
1405  	list_sort(NULL, &metric_list, metric_list_cmp);
1406  
1407  	if (!metric_no_merge) {
1408  		struct expr_parse_ctx *combined = NULL;
1409  
1410  		ret = build_combined_expr_ctx(&metric_list, &combined);
1411  
1412  		if (!ret && combined && hashmap__size(combined->ids)) {
1413  			ret = parse_ids(metric_no_merge, fake_pmu, combined,
1414  					/*modifier=*/NULL,
1415  					/*has_constraint=*/true,
1416  					&combined_evlist);
1417  		}
1418  		if (combined)
1419  			expr__ctx_free(combined);
1420  
1421  		if (ret)
1422  			goto out;
1423  	}
1424  
1425  	list_for_each_entry(m, &metric_list, nd) {
1426  		struct metric_event *me;
1427  		struct evsel **metric_events;
1428  		struct evlist *metric_evlist = NULL;
1429  		struct metric *n;
1430  		struct metric_expr *expr;
1431  
1432  		if (combined_evlist && m->has_constraint) {
1433  			metric_evlist = combined_evlist;
1434  		} else if (!metric_no_merge) {
1435  			/*
1436  			 * See if the IDs for this metric are a subset of an
1437  			 * earlier metric.
1438  			 */
1439  			list_for_each_entry(n, &metric_list, nd) {
1440  				if (m == n)
1441  					break;
1442  
1443  				if (n->evlist == NULL)
1444  					continue;
1445  
1446  				if ((!m->modifier && n->modifier) ||
1447  				    (m->modifier && !n->modifier) ||
1448  				    (m->modifier && n->modifier &&
1449  					    strcmp(m->modifier, n->modifier)))
1450  					continue;
1451  
1452  				if (expr__subset_of_ids(n->pctx, m->pctx)) {
1453  					pr_debug("Events in '%s' fully contained within '%s'\n",
1454  						 m->metric_name, n->metric_name);
1455  					metric_evlist = n->evlist;
1456  					break;
1457  				}
1458  
1459  			}
1460  		}
1461  		if (!metric_evlist) {
1462  			ret = parse_ids(metric_no_merge, fake_pmu, m->pctx, m->modifier,
1463  					m->has_constraint, &m->evlist);
1464  			if (ret)
1465  				goto out;
1466  
1467  			metric_evlist = m->evlist;
1468  		}
1469  		ret = setup_metric_events(m->pctx->ids, metric_evlist, &metric_events);
1470  		if (ret) {
1471  			pr_debug("Cannot resolve IDs for %s: %s\n",
1472  				m->metric_name, m->metric_expr);
1473  			goto out;
1474  		}
1475  
1476  		me = metricgroup__lookup(metric_events_list, metric_events[0], true);
1477  
1478  		expr = malloc(sizeof(struct metric_expr));
1479  		if (!expr) {
1480  			ret = -ENOMEM;
1481  			free(metric_events);
1482  			goto out;
1483  		}
1484  
1485  		expr->metric_refs = m->metric_refs;
1486  		m->metric_refs = NULL;
1487  		expr->metric_expr = m->metric_expr;
1488  		if (m->modifier) {
1489  			char *tmp;
1490  
1491  			if (asprintf(&tmp, "%s:%s", m->metric_name, m->modifier) < 0)
1492  				expr->metric_name = NULL;
1493  			else
1494  				expr->metric_name = tmp;
1495  		} else
1496  			expr->metric_name = strdup(m->metric_name);
1497  
1498  		if (!expr->metric_name) {
1499  			ret = -ENOMEM;
1500  			free(metric_events);
1501  			goto out;
1502  		}
1503  		expr->metric_unit = m->metric_unit;
1504  		expr->metric_events = metric_events;
1505  		expr->runtime = m->pctx->runtime;
1506  		list_add(&expr->nd, &me->head);
1507  	}
1508  
1509  
1510  	if (combined_evlist) {
1511  		evlist__splice_list_tail(perf_evlist, &combined_evlist->core.entries);
1512  		evlist__delete(combined_evlist);
1513  	}
1514  
1515  	list_for_each_entry(m, &metric_list, nd) {
1516  		if (m->evlist)
1517  			evlist__splice_list_tail(perf_evlist, &m->evlist->core.entries);
1518  	}
1519  
1520  out:
1521  	metricgroup__free_metrics(&metric_list);
1522  	return ret;
1523  }
1524  
1525  int metricgroup__parse_groups(const struct option *opt,
1526  			      const char *str,
1527  			      bool metric_no_group,
1528  			      bool metric_no_merge,
1529  			      struct rblist *metric_events)
1530  {
1531  	struct evlist *perf_evlist = *(struct evlist **)opt->value;
1532  	const struct pmu_events_map *map = pmu_events_map__find();
1533  
1534  	return parse_groups(perf_evlist, str, metric_no_group,
1535  			    metric_no_merge, NULL, metric_events, map);
1536  }
1537  
1538  int metricgroup__parse_groups_test(struct evlist *evlist,
1539  				   const struct pmu_events_map *map,
1540  				   const char *str,
1541  				   bool metric_no_group,
1542  				   bool metric_no_merge,
1543  				   struct rblist *metric_events)
1544  {
1545  	return parse_groups(evlist, str, metric_no_group,
1546  			    metric_no_merge, &perf_pmu__fake, metric_events, map);
1547  }
1548  
1549  bool metricgroup__has_metric(const char *metric)
1550  {
1551  	const struct pmu_events_map *map = pmu_events_map__find();
1552  	const struct pmu_event *pe;
1553  	int i;
1554  
1555  	if (!map)
1556  		return false;
1557  
1558  	for (i = 0; ; i++) {
1559  		pe = &map->table[i];
1560  
1561  		if (!pe->name && !pe->metric_group && !pe->metric_name)
1562  			break;
1563  		if (!pe->metric_expr)
1564  			continue;
1565  		if (match_metric(pe->metric_name, metric))
1566  			return true;
1567  	}
1568  	return false;
1569  }
1570  
1571  int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp,
1572  				    struct rblist *new_metric_events,
1573  				    struct rblist *old_metric_events)
1574  {
1575  	unsigned i;
1576  
1577  	for (i = 0; i < rblist__nr_entries(old_metric_events); i++) {
1578  		struct rb_node *nd;
1579  		struct metric_event *old_me, *new_me;
1580  		struct metric_expr *old_expr, *new_expr;
1581  		struct evsel *evsel;
1582  		size_t alloc_size;
1583  		int idx, nr;
1584  
1585  		nd = rblist__entry(old_metric_events, i);
1586  		old_me = container_of(nd, struct metric_event, nd);
1587  
1588  		evsel = evlist__find_evsel(evlist, old_me->evsel->core.idx);
1589  		if (!evsel)
1590  			return -EINVAL;
1591  		new_me = metricgroup__lookup(new_metric_events, evsel, true);
1592  		if (!new_me)
1593  			return -ENOMEM;
1594  
1595  		pr_debug("copying metric event for cgroup '%s': %s (idx=%d)\n",
1596  			 cgrp ? cgrp->name : "root", evsel->name, evsel->core.idx);
1597  
1598  		list_for_each_entry(old_expr, &old_me->head, nd) {
1599  			new_expr = malloc(sizeof(*new_expr));
1600  			if (!new_expr)
1601  				return -ENOMEM;
1602  
1603  			new_expr->metric_expr = old_expr->metric_expr;
1604  			new_expr->metric_name = strdup(old_expr->metric_name);
1605  			if (!new_expr->metric_name)
1606  				return -ENOMEM;
1607  
1608  			new_expr->metric_unit = old_expr->metric_unit;
1609  			new_expr->runtime = old_expr->runtime;
1610  
1611  			if (old_expr->metric_refs) {
1612  				/* calculate number of metric_events */
1613  				for (nr = 0; old_expr->metric_refs[nr].metric_name; nr++)
1614  					continue;
1615  				alloc_size = sizeof(*new_expr->metric_refs);
1616  				new_expr->metric_refs = calloc(nr + 1, alloc_size);
1617  				if (!new_expr->metric_refs) {
1618  					free(new_expr);
1619  					return -ENOMEM;
1620  				}
1621  
1622  				memcpy(new_expr->metric_refs, old_expr->metric_refs,
1623  				       nr * alloc_size);
1624  			} else {
1625  				new_expr->metric_refs = NULL;
1626  			}
1627  
1628  			/* calculate number of metric_events */
1629  			for (nr = 0; old_expr->metric_events[nr]; nr++)
1630  				continue;
1631  			alloc_size = sizeof(*new_expr->metric_events);
1632  			new_expr->metric_events = calloc(nr + 1, alloc_size);
1633  			if (!new_expr->metric_events) {
1634  				free(new_expr->metric_refs);
1635  				free(new_expr);
1636  				return -ENOMEM;
1637  			}
1638  
1639  			/* copy evsel in the same position */
1640  			for (idx = 0; idx < nr; idx++) {
1641  				evsel = old_expr->metric_events[idx];
1642  				evsel = evlist__find_evsel(evlist, evsel->core.idx);
1643  				if (evsel == NULL) {
1644  					free(new_expr->metric_events);
1645  					free(new_expr->metric_refs);
1646  					free(new_expr);
1647  					return -EINVAL;
1648  				}
1649  				new_expr->metric_events[idx] = evsel;
1650  			}
1651  
1652  			list_add(&new_expr->nd, &new_me->head);
1653  		}
1654  	}
1655  	return 0;
1656  }
1657