perf kwork: Overwrite original atom in the list when a new atom is pushed.
authorYang Jihong <yangjihong1@huawei.com>
Sat, 12 Aug 2023 08:49:06 +0000 (08:49 +0000)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 12 Sep 2023 20:31:59 +0000 (17:31 -0300)
work_push_atom() supports nesting. Currently, all supported kworks are not
nested. A `overwrite` parameter is added to overwrite the original atom in
the list.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Sandipan Das <sandipan.das@amd.com>
Link: https://lore.kernel.org/r/20230812084917.169338-6-yangjihong1@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-kwork.c

index 42ea59a957aed9dad6967fafc381f5c49e8a26df..f620911a26a24836d5eb0d80bec6f754908d9081 100644 (file)
@@ -392,9 +392,10 @@ static int work_push_atom(struct perf_kwork *kwork,
                          struct evsel *evsel,
                          struct perf_sample *sample,
                          struct machine *machine,
-                         struct kwork_work **ret_work)
+                         struct kwork_work **ret_work,
+                         bool overwrite)
 {
-       struct kwork_atom *atom, *dst_atom;
+       struct kwork_atom *atom, *dst_atom, *last_atom;
        struct kwork_work *work, key;
 
        BUG_ON(class->work_init == NULL);
@@ -427,6 +428,17 @@ static int work_push_atom(struct perf_kwork *kwork,
        if (ret_work != NULL)
                *ret_work = work;
 
+       if (overwrite) {
+               last_atom = list_last_entry_or_null(&work->atom_list[src_type],
+                                                   struct kwork_atom, list);
+               if (last_atom) {
+                       atom_del(last_atom);
+
+                       kwork->nr_skipped_events[src_type]++;
+                       kwork->nr_skipped_events[KWORK_TRACE_MAX]++;
+               }
+       }
+
        list_add_tail(&atom->list, &work->atom_list[src_type]);
 
        return 0;
@@ -502,7 +514,7 @@ static int report_entry_event(struct perf_kwork *kwork,
 {
        return work_push_atom(kwork, class, KWORK_TRACE_ENTRY,
                              KWORK_TRACE_MAX, evsel, sample,
-                             machine, NULL);
+                             machine, NULL, true);
 }
 
 static int report_exit_event(struct perf_kwork *kwork,
@@ -557,7 +569,7 @@ static int latency_raise_event(struct perf_kwork *kwork,
 {
        return work_push_atom(kwork, class, KWORK_TRACE_RAISE,
                              KWORK_TRACE_MAX, evsel, sample,
-                             machine, NULL);
+                             machine, NULL, true);
 }
 
 static int latency_entry_event(struct perf_kwork *kwork,
@@ -716,7 +728,7 @@ static int timehist_raise_event(struct perf_kwork *kwork,
 {
        return work_push_atom(kwork, class, KWORK_TRACE_RAISE,
                              KWORK_TRACE_MAX, evsel, sample,
-                             machine, NULL);
+                             machine, NULL, true);
 }
 
 static int timehist_entry_event(struct perf_kwork *kwork,
@@ -730,7 +742,7 @@ static int timehist_entry_event(struct perf_kwork *kwork,
 
        ret = work_push_atom(kwork, class, KWORK_TRACE_ENTRY,
                             KWORK_TRACE_RAISE, evsel, sample,
-                            machine, &work);
+                            machine, &work, true);
        if (ret)
                return ret;