perf tools: Use list_del_init() more thorougly
authorArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 4 Jul 2019 15:13:46 +0000 (12:13 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 9 Jul 2019 13:13:27 +0000 (10:13 -0300)
To allow for destructors to check if they're operating on a object still
in a list, and to avoid going from use after free list entries into
still valid, or even also other already removed from list entries.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lkml.kernel.org/n/tip-deh17ub44atyox3j90e6rksu@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
22 files changed:
tools/perf/builtin-ftrace.c
tools/perf/builtin-lock.c
tools/perf/pmu-events/jevents.c
tools/perf/tests/switch-tracking.c
tools/perf/ui/gtk/annotate.c
tools/perf/util/annotate.c
tools/perf/util/auxtrace.c
tools/perf/util/bpf-loader.c
tools/perf/util/call-path.c
tools/perf/util/callchain.c
tools/perf/util/db-export.c
tools/perf/util/dso.c
tools/perf/util/evsel.c
tools/perf/util/hist.c
tools/perf/util/ordered-events.c
tools/perf/util/parse-events.c
tools/perf/util/pmu.c
tools/perf/util/probe-event.c
tools/perf/util/s390-cpumsf.c
tools/perf/util/srccode.c
tools/perf/util/symbol-elf.c
tools/perf/util/thread.c

index 9c228c55e1fb782f5f95a04760b7a41f36235a9e..66d5a6658daf542489d5eed878b9ed0e1035498a 100644 (file)
@@ -431,7 +431,7 @@ static void delete_filter_func(struct list_head *head)
        struct filter_entry *pos, *tmp;
 
        list_for_each_entry_safe(pos, tmp, head, list) {
-               list_del(&pos->list);
+               list_del_init(&pos->list);
                free(pos);
        }
 }
index c0be44e65e9d33b2c4703c336fcb9db233fc7ca9..574e30ec6d7c76913b806cfe831a3ffaba1f77ec 100644 (file)
@@ -454,7 +454,7 @@ broken:
                /* broken lock sequence, discard it */
                ls->discard = 1;
                bad_hist[BROKEN_ACQUIRE]++;
-               list_del(&seq->list);
+               list_del_init(&seq->list);
                free(seq);
                goto end;
        default:
@@ -515,7 +515,7 @@ static int report_lock_acquired_event(struct perf_evsel *evsel,
                /* broken lock sequence, discard it */
                ls->discard = 1;
                bad_hist[BROKEN_ACQUIRED]++;
-               list_del(&seq->list);
+               list_del_init(&seq->list);
                free(seq);
                goto end;
        default:
@@ -570,7 +570,7 @@ static int report_lock_contended_event(struct perf_evsel *evsel,
                /* broken lock sequence, discard it */
                ls->discard = 1;
                bad_hist[BROKEN_CONTENDED]++;
-               list_del(&seq->list);
+               list_del_init(&seq->list);
                free(seq);
                goto end;
        default:
@@ -639,7 +639,7 @@ static int report_lock_release_event(struct perf_evsel *evsel,
 
        ls->nr_release++;
 free_seq:
-       list_del(&seq->list);
+       list_del_init(&seq->list);
        free(seq);
 end:
        return 0;
index 287a6f10ca487d7991ea3c807a8a2f27dc8bbadb..1a91a197cafb02124b9ca20cda355b7195c51fcd 100644 (file)
@@ -407,7 +407,7 @@ static void free_arch_std_events(void)
 
        list_for_each_entry_safe(es, next, &arch_std_events, list) {
                FOR_ALL_EVENT_STRUCT_FIELDS(FREE_EVENT_FIELD);
-               list_del(&es->list);
+               list_del_init(&es->list);
                free(es);
        }
 }
index 744409dce65f92435054c31ffdaddf6a2bd5eb5d..6cdab5f4812addff90263e25db1f39b7c055f786 100644 (file)
@@ -238,7 +238,7 @@ static void free_event_nodes(struct list_head *events)
 
        while (!list_empty(events)) {
                node = list_entry(events->next, struct event_node, list);
-               list_del(&node->list);
+               list_del_init(&node->list);
                free(node);
        }
 }
index df49c9ba178571acd4960efbbfe8800ebe8ef47f..3af87c18a914f738259d8474fb0105a956224d7d 100644 (file)
@@ -152,7 +152,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
        gtk_container_add(GTK_CONTAINER(window), view);
 
        list_for_each_entry_safe(pos, n, &notes->src->source, al.node) {
-               list_del(&pos->al.node);
+               list_del_init(&pos->al.node);
                disasm_line__free(pos);
        }
 
index ef0e6028684c3fc48a4895f58f58001e71491409..ac9ad2330f930d78fe499d38bdc80937d71bdd3c 100644 (file)
@@ -1586,7 +1586,7 @@ static void delete_last_nop(struct symbol *sym)
                                return;
                }
 
-               list_del(&dl->al.node);
+               list_del_init(&dl->al.node);
                disasm_line__free(dl);
        }
 }
@@ -2463,7 +2463,7 @@ void annotated_source__purge(struct annotated_source *as)
        struct annotation_line *al, *n;
 
        list_for_each_entry_safe(al, n, &as->source, node) {
-               list_del(&al->node);
+               list_del_init(&al->node);
                disasm_line__free(disasm_line(al));
        }
 }
index b033a43dfe3b4b93e7a2fa96bb17cfd70c7f00c2..ec0af36697c496e07c5158318b2da49f13587fcb 100644 (file)
@@ -408,7 +408,7 @@ void auxtrace_queues__free(struct auxtrace_queues *queues)
 
                        buffer = list_entry(queues->queue_array[i].head.next,
                                            struct auxtrace_buffer, list);
-                       list_del(&buffer->list);
+                       list_del_init(&buffer->list);
                        auxtrace_buffer__free(buffer);
                }
        }
@@ -612,7 +612,7 @@ void auxtrace_index__free(struct list_head *head)
        struct auxtrace_index *auxtrace_index, *n;
 
        list_for_each_entry_safe(auxtrace_index, n, head, list) {
-               list_del(&auxtrace_index->list);
+               list_del_init(&auxtrace_index->list);
                free(auxtrace_index);
        }
 }
index 93d0f239ad4f17523fc862fa3014c069f90c9df3..c61974a50aa59266aea6a4760fddc4cb038eb64f 100644 (file)
@@ -829,7 +829,7 @@ static void
 bpf_map_op__delete(struct bpf_map_op *op)
 {
        if (!list_empty(&op->list))
-               list_del(&op->list);
+               list_del_init(&op->list);
        if (op->key_type == BPF_MAP_KEY_RANGES)
                parse_events__clear_array(&op->k.array);
        free(op);
index e8a80c41cba32dd1c891337cfc73ec8d2b83e1ba..5c60b8be1cf6e4bb0fb9ab8750d604e3b836ee33 100644 (file)
@@ -40,7 +40,7 @@ void call_path_root__free(struct call_path_root *cpr)
        struct call_path_block *pos, *n;
 
        list_for_each_entry_safe(pos, n, &cpr->blocks, node) {
-               list_del(&pos->node);
+               list_del_init(&pos->node);
                free(pos);
        }
        free(cpr);
index b4af25dca5ebeabf3501fd07a1f664bfa11f2f1a..8d7d8f62fcca389dc7a0d2a6a886dd59d5f24c23 100644 (file)
@@ -636,7 +636,7 @@ add_child(struct callchain_node *parent,
                struct callchain_list *call, *tmp;
 
                list_for_each_entry_safe(call, tmp, &new->val, list) {
-                       list_del(&call->list);
+                       list_del_init(&call->list);
                        map__zput(call->ms.map);
                        free(call);
                }
@@ -1002,7 +1002,7 @@ merge_chain_branch(struct callchain_cursor *cursor,
                callchain_cursor_append(cursor, list->ip,
                                        list->ms.map, list->ms.sym,
                                        false, NULL, 0, 0, 0, list->srcline);
-               list_del(&list->list);
+               list_del_init(&list->list);
                map__zput(list->ms.map);
                free(list);
        }
@@ -1453,13 +1453,13 @@ static void free_callchain_node(struct callchain_node *node)
        struct rb_node *n;
 
        list_for_each_entry_safe(list, tmp, &node->parent_val, list) {
-               list_del(&list->list);
+               list_del_init(&list->list);
                map__zput(list->ms.map);
                free(list);
        }
 
        list_for_each_entry_safe(list, tmp, &node->val, list) {
-               list_del(&list->list);
+               list_del_init(&list->list);
                map__zput(list->ms.map);
                free(list);
        }
@@ -1544,7 +1544,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
 
 out:
        list_for_each_entry_safe(chain, new, &head, list) {
-               list_del(&chain->list);
+               list_del_init(&chain->list);
                map__zput(chain->ms.map);
                free(chain);
        }
index 3f2694ccfac749c5bd38daf8c21646876aaa8ff2..2394c7506abe111ec21bbdea52d946c5a4866b99 100644 (file)
@@ -34,7 +34,7 @@ static int db_export__deferred(struct db_export *dbe)
                de = list_entry(dbe->deferred.next, struct deferred_export,
                                node);
                err = dbe->export_comm(dbe, de->comm);
-               list_del(&de->node);
+               list_del_init(&de->node);
                free(de);
                if (err)
                        return err;
@@ -50,7 +50,7 @@ static void db_export__free_deferred(struct db_export *dbe)
        while (!list_empty(&dbe->deferred)) {
                de = list_entry(dbe->deferred.next, struct deferred_export,
                                node);
-               list_del(&de->node);
+               list_del_init(&de->node);
                free(de);
        }
 }
index ebacf07fc9ee9461bf4f76db0b5a71cdbca8aee5..ebc9d46c15a7ecee48db2ebc2762c77ea650e453 100644 (file)
@@ -434,7 +434,7 @@ static void dso__list_add(struct dso *dso)
 
 static void dso__list_del(struct dso *dso)
 {
-       list_del(&dso->data.open_entry);
+       list_del_init(&dso->data.open_entry);
        WARN_ONCE(dso__data_open_cnt <= 0,
                  "DSO data fd counter out of bounds.");
        dso__data_open_cnt--;
index 7ede674edf07426d1a49d88c5272026ba1ce9dac..ebb46da4dfe5abc6056f9054db2bbeba63cf1c6a 100644 (file)
@@ -1298,7 +1298,7 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel)
        struct perf_evsel_config_term *term, *h;
 
        list_for_each_entry_safe(term, h, &evsel->config_terms, list) {
-               list_del(&term->list);
+               list_del_init(&term->list);
                free(term);
        }
 }
index 9b0ee0ef0f447320b599ce39fd4b4caa51e47ec9..f24fd1954f6c9c3287fd312dd286252a905f0138 100644 (file)
@@ -2741,10 +2741,10 @@ static void hists_evsel__exit(struct perf_evsel *evsel)
 
        list_for_each_entry_safe(node, tmp, &hists->hpp_formats, list) {
                perf_hpp_list__for_each_format_safe(&node->hpp, fmt, pos) {
-                       list_del(&fmt->list);
+                       list_del_init(&fmt->list);
                        free(fmt);
                }
-               list_del(&node->list);
+               list_del_init(&node->list);
                free(node);
        }
 }
index 989fed6f43b5a5f34d485c39b7b8fa30790e6a2d..bb5f34b7ab446dad4b668c43621ee1c1cc547ec5 100644 (file)
@@ -138,7 +138,7 @@ static struct ordered_event *alloc_event(struct ordered_events *oe,
 
        if (!list_empty(cache)) {
                new = list_entry(cache->next, struct ordered_event, list);
-               list_del(&new->list);
+               list_del_init(&new->list);
        } else if (oe->buffer) {
                new = &oe->buffer->event[oe->buffer_idx];
                if (++oe->buffer_idx == MAX_SAMPLE_BUFFER)
@@ -394,13 +394,13 @@ void ordered_events__free(struct ordered_events *oe)
         * yet, we need to free only allocated ones ...
         */
        if (oe->buffer) {
-               list_del(&oe->buffer->list);
+               list_del_init(&oe->buffer->list);
                ordered_events_buffer__free(oe->buffer, oe->buffer_idx, oe);
        }
 
        /* ... and continue with the rest */
        list_for_each_entry_safe(buffer, tmp, &oe->to_free, list) {
-               list_del(&buffer->list);
+               list_del_init(&buffer->list);
                ordered_events_buffer__free(buffer, MAX_SAMPLE_BUFFER, oe);
        }
 }
index aa439853f20aaeb5bcd8deb2c6bcd579eb06aa8c..371ff3aee769af09e342d052b26fb95bcebb938a 100644 (file)
@@ -652,7 +652,7 @@ static int add_bpf_event(const char *group, const char *event, int fd,
                pr_debug("Failed to add BPF event %s:%s\n",
                         group, event);
                list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
-                       list_del(&evsel->node);
+                       list_del_init(&evsel->node);
                        perf_evsel__delete(evsel);
                }
                return err;
index 12b677902fbc3efab2408d13d50cf95645650ea2..f32b710347dbd5c6ca87b9a7aaf8be7fe3e0a155 100644 (file)
@@ -1245,7 +1245,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
                info->metric_expr = alias->metric_expr;
                info->metric_name = alias->metric_name;
 
-               list_del(&term->list);
+               list_del_init(&term->list);
                free(term);
        }
 
index 0a57b316c4dda835712f0f8774ddb4a522d2536b..0c3b55d0617dc32c03229af3d1ada79307c64e8c 100644 (file)
@@ -2333,7 +2333,7 @@ static void kprobe_blacklist__delete(struct list_head *blacklist)
        while (!list_empty(blacklist)) {
                node = list_first_entry(blacklist,
                                        struct kprobe_blacklist_node, list);
-               list_del(&node->list);
+               list_del_init(&node->list);
                zfree(&node->symbol);
                free(node);
        }
index cca9cb851d028808b4a5011346da9d33d8279aeb..83d2e149ef19180e9ad610d7e7851b744698d2c3 100644 (file)
@@ -756,7 +756,7 @@ static int s390_cpumsf_run_decoder(struct s390_cpumsf_queue *sfq,
         */
        if (err) {
                sfq->buffer = NULL;
-               list_del(&buffer->list);
+               list_del_init(&buffer->list);
                auxtrace_buffer__free(buffer);
                if (err > 0)            /* Buffer done, no error */
                        err = 0;
index 688a85a3d454640b9ec6a5dbaa0588fd58cbc1c7..adfcf1ff464c6277f25c113d0e733702bdd9afc2 100644 (file)
@@ -83,7 +83,7 @@ static void fill_lines(char **lines, int maxline, char *map, int maplen)
 
 static void free_srcfile(struct srcfile *sf)
 {
-       list_del(&sf->nd);
+       list_del_init(&sf->nd);
        hlist_del(&sf->hash_nd);
        map_total_sz -= sf->maplen;
        munmap(sf->map, sf->maplen);
index 1d5447594f5df1317a3ae080377e6d6848610b7f..7d504dc221084f54bd924a6556a256342ce752cc 100644 (file)
@@ -1478,7 +1478,7 @@ static void kcore_copy__free_phdrs(struct kcore_copy_info *kci)
        struct phdr_data *p, *tmp;
 
        list_for_each_entry_safe(p, tmp, &kci->phdrs, node) {
-               list_del(&p->node);
+               list_del_init(&p->node);
                free(p);
        }
 }
@@ -1501,7 +1501,7 @@ static void kcore_copy__free_syms(struct kcore_copy_info *kci)
        struct sym_data *s, *tmp;
 
        list_for_each_entry_safe(s, tmp, &kci->syms, node) {
-               list_del(&s->node);
+               list_del_init(&s->node);
                free(s);
        }
 }
@@ -2252,7 +2252,7 @@ int cleanup_sdt_note_list(struct list_head *sdt_notes)
        int nr_free = 0;
 
        list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) {
-               list_del(&pos->note_list);
+               list_del_init(&pos->note_list);
                zfree(&pos->name);
                zfree(&pos->provider);
                free(pos);
index bbfb9c767f5fffcce0ce216dd5dc0a048c6f1850..873ab505ca8071fdf38e2eb8b091e19553f165fc 100644 (file)
@@ -93,14 +93,14 @@ void thread__delete(struct thread *thread)
        down_write(&thread->namespaces_lock);
        list_for_each_entry_safe(namespaces, tmp_namespaces,
                                 &thread->namespaces_list, list) {
-               list_del(&namespaces->list);
+               list_del_init(&namespaces->list);
                namespaces__free(namespaces);
        }
        up_write(&thread->namespaces_lock);
 
        down_write(&thread->comm_lock);
        list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) {
-               list_del(&comm->list);
+               list_del_init(&comm->list);
                comm__free(comm);
        }
        up_write(&thread->comm_lock);