Re: [PATCH v2] libtraceevent plugins: Parse sched_switch "prev_state" field for state info

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 8 Dec 2023 15:41:01 +0800
Ze Gao <zegao2021@xxxxxxxxx> wrote:

> > diff --git a/plugins/plugin_sched_switch.c b/plugins/plugin_sched_switch.c
> > index e0986ac9cc3d..bde68c4b602d 100644
> > --- a/plugins/plugin_sched_switch.c
> > +++ b/plugins/plugin_sched_switch.c
> > @@ -9,13 +9,136 @@
> >  #include "event-parse.h"
> >  #include "trace-seq.h"
> >
> > -static void write_state(struct trace_seq *s, int val)
> > +static const char *convert_sym(struct tep_print_flag_sym *sym)
> >  {
> > -       const char states[] = "SDTtXZPI";
> > +       static char save_states[33];
> > +
> > +       memset(save_states, 0, sizeof(save_states));
> > +
> > +       /* This is the flags for the prev_state_field, now make them into a string */
> > +       for (; sym; sym = sym->next) {
> > +               long bitmask = strtoul(sym->value, NULL, 0);
> > +               int i;
> > +
> > +               for (i = 0; !(bitmask & 1); i++)
> > +                       bitmask >>= 1;  
> 
> It's no big deal but I think glibc has a faster version of ffs here
> we can directly call that one instead.

I'm use to using ffs in the kernel, but I'm always weary of glibc. No real
reason, just a personal reaction. Anyway, this is far from a fast path if
it's only calculated when hitting a new prev_state field. Although this can
happen often with host/guest tracing.

I figured I'd optimize that in another patch.

> 
> > +               if (i > 32)
> > +                       continue; // warn?
> > +
> > +               save_states[i] = sym->str[0];
> > +       }
> > +
> > +       return save_states;
> > +}
> > +


> > +static void write_state(struct trace_seq *s, struct tep_format_field *field,
> > +                       struct tep_record *record)
> > +{
> > +       static struct tep_format_field *prev_state_field;
> > +       static const char *states;
> > +       unsigned long long val;
> >         int found = 0;
> > +       int len;
> >         int i;
> >
> > -       for (i = 0; i < (sizeof(states) - 1); i++) {
> > +       if (!field)
> > +               return;
> > +
> > +       if (!states || field != prev_state_field) {
> > +               states = get_states(field);
> > +               if (!states)
> > +                       states = "SDTtXZPI";
> > +               printf("states = '%s'\n", states);  
> 
> printf here introduces some noises when I use perf script to inspect
> the raw events,
> and it always shows this "out-of-nowhere" message in the first
> sched_switch record.
> Still, no big deal, and better without this one.

Bah, that was for debugging. I forgot to nuke it. That's what I get when I
work on user space tooling while compiling the kernel for updates I'm doing
there. :-p

> 
> > +               prev_state_field = field;
> > +       }
> > +
> > +       tep_read_number_field(field, record->data, &val);
> > +
> > +       len = strlen(states);
> > +       for (i = 0; i < len; i++) {
> >                 if (!(val & (1 << i)))
> >                         continue;  
> 
> I think here is another case to consider, the preemption state. it's
> exposed as well IIRC.
> and the kernel denotes this as "R+", maybe we can follow that
> convention by adding
> checks like:
> 
>         if (!found) {
>                 trace_seq_putc(s, 'R');
>                 if (val)
>                      trace_seq_putc(s,  ‘+’);
>         }
> 
> Just in case, if you were not intentional to make it as it is now.

Sounds good. I'd do that in a separate patch too.

> 
> > @@ -99,8 +222,8 @@ static int sched_switch_handler(struct trace_seq *s,
> >         if (tep_get_field_val(s, event, "prev_prio", record, &val, 1) == 0)
> >                 trace_seq_printf(s, "[%d] ", (int) val);
> >
> > -       if (tep_get_field_val(s,  event, "prev_state", record, &val, 1) == 0)
> > -               write_state(s, val);
> > +       field = tep_find_any_field(event, "prev_state");
> > +       write_state(s, field, record);
> >
> >         trace_seq_puts(s, " ==> ");
> >
> > --
> > 2.42.0
> >  
> 
> Overall, I did the tests on my settings, and the patch worked. It's much more
> robust in finding and validating TEP_PRINT_FLAG than the one I posted and
> This is the first time I know we are capable of doing analyses on multiple data
> records simultaneously. Learned a lot!
> 
> Last but the least,  I had trouble applying the diff to the branch libtraceevent
> initially but had to copy and paste on my own.  Just FYI. Still no big deal :)

I have three patches I have yet to push on top of this one. I'm way behind
in my user space work. As mentioned above, I tend to screw up when I try to
focus both on the kernel and user space libraries (unless I'm working on
both because they are related, but that's not currently the case).

Hopefully this will get done before the end of the year.

Thanks!

-- Steve





[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux