perf tools: Fix hybrid config terms list corruption
[linux-2.6-microblaze.git] / tools / perf / util / parse-events.c
index 84108c1..51a2219 100644 (file)
@@ -387,7 +387,7 @@ __add_event(struct list_head *list, int *idx,
                evsel->name = strdup(name);
 
        if (config_terms)
-               list_splice(config_terms, &evsel->config_terms);
+               list_splice_init(config_terms, &evsel->config_terms);
 
        if (list)
                list_add_tail(&evsel->core.node, list);
@@ -535,9 +535,12 @@ int parse_events_add_cache(struct list_head *list, int *idx,
                                             config_name ? : name, &config_terms,
                                             &hybrid, parse_state);
        if (hybrid)
-               return ret;
+               goto out_free_terms;
 
-       return add_event(list, idx, &attr, config_name ? : name, &config_terms);
+       ret = add_event(list, idx, &attr, config_name ? : name, &config_terms);
+out_free_terms:
+       free_config_terms(&config_terms);
+       return ret;
 }
 
 static void tracepoint_error(struct parse_events_error *e, int err,
@@ -1457,10 +1460,13 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
                                               get_config_name(head_config),
                                               &config_terms, &hybrid);
        if (hybrid)
-               return ret;
+               goto out_free_terms;
 
-       return add_event(list, &parse_state->idx, &attr,
-                        get_config_name(head_config), &config_terms);
+       ret = add_event(list, &parse_state->idx, &attr,
+                       get_config_name(head_config), &config_terms);
+out_free_terms:
+       free_config_terms(&config_terms);
+       return ret;
 }
 
 int parse_events_add_tool(struct parse_events_state *parse_state,
@@ -1608,14 +1614,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
        }
 
        if (!parse_state->fake_pmu && perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
-               struct evsel_config_term *pos, *tmp;
-
-               list_for_each_entry_safe(pos, tmp, &config_terms, list) {
-                       list_del_init(&pos->list);
-                       if (pos->free_str)
-                               zfree(&pos->val.str);
-                       free(pos);
-               }
+               free_config_terms(&config_terms);
                return -EINVAL;
        }
 
@@ -1740,7 +1739,7 @@ parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list,
 
        leader = list_first_entry(list, struct evsel, core.node);
        evsel = list_last_entry(list, struct evsel, core.node);
-       total_members = evsel->idx - leader->idx + 1;
+       total_members = evsel->core.idx - leader->core.idx + 1;
 
        leaders = calloc(total_members, sizeof(uintptr_t));
        if (WARN_ON(!leaders))
@@ -1800,7 +1799,7 @@ parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list,
        __evlist__for_each_entry(list, evsel) {
                if (i >= nr_pmu)
                        i = 0;
-               evsel->leader = (struct evsel *) leaders[i++];
+               evsel__set_leader(evsel, (struct evsel *) leaders[i++]);
        }
 
        /* The number of members and group name are same for each group */
@@ -1833,7 +1832,7 @@ void parse_events__set_leader(char *name, struct list_head *list,
        if (parse_events__set_leader_for_uncore_aliase(name, list, parse_state))
                return;
 
-       __evlist__set_leader(list);
+       __perf_evlist__set_leader(list);
        leader = list_entry(list->next, struct evsel, core.node);
        leader->group_name = name ? strdup(name) : NULL;
 }
@@ -2285,7 +2284,7 @@ int __parse_events(struct evlist *evlist, const char *str,
        if (!ret) {
                struct evsel *last;
 
-               evlist->nr_groups += parse_state.nr_groups;
+               evlist->core.nr_groups += parse_state.nr_groups;
                last = evlist__last(evlist);
                last->cmdline_group_boundary = true;