[RFC v1 05/16] perf kwork: Overwrite original atom in the list when a new atom is pushed.

Yang Jihong posted 16 patches 2 years, 4 months ago
[RFC v1 05/16] perf kwork: Overwrite original atom in the list when a new atom is pushed.
Posted by Yang Jihong 2 years, 4 months ago
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.

Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
---
 tools/perf/builtin-kwork.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c
index 42ea59a957ae..f620911a26a2 100644
--- a/tools/perf/builtin-kwork.c
+++ b/tools/perf/builtin-kwork.c
@@ -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;
 
-- 
2.30.GIT
Re: [RFC v1 05/16] perf kwork: Overwrite original atom in the list when a new atom is pushed.
Posted by Ian Rogers 2 years, 3 months ago
On Sat, Aug 12, 2023 at 1:52 AM Yang Jihong <yangjihong1@huawei.com> wrote:
>
> 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.
>
> Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
> ---
>  tools/perf/builtin-kwork.c | 24 ++++++++++++++++++------
>  1 file changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c
> index 42ea59a957ae..f620911a26a2 100644
> --- a/tools/perf/builtin-kwork.c
> +++ b/tools/perf/builtin-kwork.c
> @@ -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)

kerneldoc would be useful. Pushing something seems self-evident but
what does overwrite mean without reading the code?

>  {
> -       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);

nit: for constant arguments it can be useful to add parameter names
which can enable checks like clang-tidy's bugprone argument:
https://clang.llvm.org/extra/clang-tidy/checks/bugprone/argument-comment.html
This would make this:
        return work_push_atom(kwork, class, KWORK_TRACE_ENTRY,
                              KWORK_TRACE_MAX, evsel, sample,
                              machine, /*ret_work=*/NULL, /*overwite=*/true);

Thanks,
Ian

>  }
>
>  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;
>
> --
> 2.30.GIT
>
Re: [RFC v1 05/16] perf kwork: Overwrite original atom in the list when a new atom is pushed.
Posted by Yang Jihong 2 years, 3 months ago
Hello,

On 2023/9/4 12:13, Ian Rogers wrote:
> On Sat, Aug 12, 2023 at 1:52 AM Yang Jihong <yangjihong1@huawei.com> wrote:
>>
>> 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.
>>
>> Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
>> ---
>>   tools/perf/builtin-kwork.c | 24 ++++++++++++++++++------
>>   1 file changed, 18 insertions(+), 6 deletions(-)
>>
>> diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c
>> index 42ea59a957ae..f620911a26a2 100644
>> --- a/tools/perf/builtin-kwork.c
>> +++ b/tools/perf/builtin-kwork.c
>> @@ -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)
> 
> kerneldoc would be useful. Pushing something seems self-evident but
> what does overwrite mean without reading the code?

Okay, I'll add comments.

> 
>>   {
>> -       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);
> 
> nit: for constant arguments it can be useful to add parameter names
> which can enable checks like clang-tidy's bugprone argument:
> https://clang.llvm.org/extra/clang-tidy/checks/bugprone/argument-comment.html
> This would make this:
>          return work_push_atom(kwork, class, KWORK_TRACE_ENTRY,
>                                KWORK_TRACE_MAX, evsel, sample,
>                                machine, /*ret_work=*/NULL, /*overwite=*/true);
> 
Thanks for your advice, will add parameter names later.

Thanks,
Yang