linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Łukasz Bartosik" <lb@semihalf.com>
To: jim.cromie@gmail.com
Cc: Jason Baron <jbaron@akamai.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	 Kees Cook <keescook@chromium.org>,
	Douglas Anderson <dianders@chromium.org>,
	 Guenter Roeck <groeck@google.com>,
	Yaniv Tzoreff <yanivt@google.com>,
	Benson Leung <bleung@google.com>,
	 Steven Rostedt <rostedt@goodmis.org>,
	Vincent Whitchurch <vincent.whitchurch@axis.com>,
	 Pekka Paalanen <ppaalanen@gmail.com>,
	Sean Paul <seanpaul@chromium.org>,
	 Daniel Vetter <daniel@ffwll.ch>,
	linux-kernel@vger.kernel.org, upstream@semihalf.com
Subject: Re: [PATCH v2 10/15] dyndbg: add open and close commands for trace
Date: Mon, 18 Dec 2023 02:07:17 +0100	[thread overview]
Message-ID: <CAK8ByeLwbYZW6zLnjy4UZsjvoDNkiudAgiNxRCbOPg8DLKGe0Q@mail.gmail.com> (raw)
In-Reply-To: <CAJfuBxwYhidyr0Fmjbf8Sp1H0-f8yWx4eazE301HtkzrboThqA@mail.gmail.com>

sob., 16 gru 2023 o 07:17 <jim.cromie@gmail.com> napisał(a):
>
> ** entering the bikeshed **
>
> On Thu, Nov 30, 2023 at 4:41 PM Łukasz Bartosik <lb@semihalf.com> wrote:
> >
> > Add open and close commands for opening and closing trace instances.
> > The open command has to be mandatory followed by a trace instance name.
> > If a trace instance already exists in <debugfs>/tracing/instances
> > directory then the open command will reuse it otherwise a new trace
> > instance with a name provided to the open will be created. Close
> > command closes previously opened trace instance. The close will
> > fail if a user tries to close non-existent trace instances or an
> > instance which was not previously opened.
> >
> > For example the following command will open (create or reuse existing)
> > trace instance located in <debugfs>/tracing/instances/usbcore:
> >
> >     echo "open usbcore" > <debugfs>/dynamic_debug/control
> >
> > Signed-off-by: Łukasz Bartosik <lb@semihalf.com>
> > ---
> >  lib/Kconfig.debug   |   1 +
> >  lib/dynamic_debug.c | 193 ++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 194 insertions(+)
> >
> > diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> > index 5bc56c7247a2..f184c3c91ba3 100644
> > --- a/lib/Kconfig.debug
> > +++ b/lib/Kconfig.debug
> > @@ -181,6 +181,7 @@ config DYNAMIC_DEBUG_CORE
> >         bool "Enable core function of dynamic debug support"
> >         depends on PRINTK
> >         depends on (DEBUG_FS || PROC_FS)
> > +       depends on TRACING
> >         help
> >           Enable core functional support of dynamic debug. It is useful
> >           when you want to tie dynamic debug to your kernel modules with
> > diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> > index 0dc9ec76b867..43e94023a4eb 100644
> > --- a/lib/dynamic_debug.c
> > +++ b/lib/dynamic_debug.c
> > @@ -36,6 +36,7 @@
> >  #include <linux/sched.h>
> >  #include <linux/device.h>
> >  #include <linux/netdevice.h>
> > +#include <linux/trace.h>
> >
> >  #define CREATE_TRACE_POINTS
> >  #include <trace/events/dyndbg.h>
> > @@ -73,6 +74,25 @@ struct flag_settings {
> >         unsigned int mask;
> >  };
> >
> > +#define DD_OPEN_CMD    "open"
> > +#define DD_CLOSE_CMD   "close"
> > +#define DD_TR_EVENT    "0"
> > +
> > +struct ddebug_trace_inst {
> > +       const char *name;
> > +       struct trace_array *arr;
> > +};
>
> can we bikeshed the struct name here ?
> inst is not a great abbreviation, its hard to say,
> and tends to look like a spelling error.
>
>  _tr_ appearing later on in function names isnt great either.
>

Would like me to replace all _tr_ with _trace_ ? Or do you other
suggestion to names ?

> dd_private_tracebuf ??
>

I will change the name

> I could get used to EVENT for the global tracebuf,
> but I dont find it entirely natural.
> Is it a convention in any way ?
>
> FWIW, I chose "class" as synonymous with (modelled after)
> drm's category, but spelled different (and shorter)
>
>
>
> > +
> > +/*
> > + * TRACE_DST_MAX value is reserved for writing
> > + * debug logs to trace events (prdbg, devdbg)
> > + */
> > +struct ddebug_trace {
> > +       struct ddebug_trace_inst inst[TRACE_DST_MAX-1];
> > +       DECLARE_BITMAP(bmap, TRACE_DST_MAX-1);
> > +       int bmap_size;
> > +};
>
> some kind of tbl in the name ?
> struct _ddebug_info contains descriptors and classes,
> struct dd_tracebuf_tbl_info ??

Ack

> (maybe not, but hopefully it prompts better)
>
> Also, since it touches on the 0 as EVENTS global trace-buf,
> does it simplify if we just waste index 0 in the inst[] array,
> and change MAX to LAST ?
> Or is it too much magic in 0 this way ?
>

Wasting index 0 might work. I will verify if there are no major
obstacles and will change if nothing pops up.

> > +
> >  static DEFINE_MUTEX(ddebug_lock);
> >  static LIST_HEAD(ddebug_tables);
> >  static int verbose;
> > @@ -80,6 +100,8 @@ module_param(verbose, int, 0644);
> >  MODULE_PARM_DESC(verbose, " dynamic_debug/control processing "
> >                  "( 0 = off (default), 1 = module add/rm, 2 = >control summary, 3 = parsing, 4 = per-site changes)");
> >
> > +static struct ddebug_trace tr = { .bmap_size = TRACE_DST_MAX-1 };
>
> cryptic name.
> it does appear ~20x in kernel/trace/trace_events.c
> usually as trace_array_put(tr)
>
>    trc_tbl ?
>

Ack

> and where is the map itself established ?
>

DECLARE_BITMAP(bmap, TRACE_DST_MAX-1); in struct ddebug_trace

> > +
> >  static inline struct dd_ctrl *get_ctrl(struct _ddebug *desc)
> >  {
> >         return &desc->ctrl;
> > @@ -171,6 +193,148 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
> >                   query->first_lineno, query->last_lineno, query->class_string);
> >  }
> >
> > +static bool is_ddebug_cmd(const char *str)
>
> is_dd_trace_cmd()
>

Ack

> > +{
> > +       if (!strcmp(str, DD_OPEN_CMD) ||
> > +           !strcmp(str, DD_CLOSE_CMD))
>
> single line < 80 chr ?
>

Ack

> > +               return true;
> > +
> > +       return false;
> > +}
> > +
> > +static bool validate_tr_name(const char *str)
>
> something less procedural sounding, and more is-ok?
> dd_good_trace_name ?
>

Ack

> > +{
> > +       /* "0" is reserved for writing debug logs to trace events (prdbg, devdbg) */
> > +       if (!strcmp(str, DD_TR_EVENT))
> > +               return false;
> > +
> > +       /* we allow trace instance names to include ^\w+ and underscore */
> > +       while (*str != '\0') {
> > +               if (!isalnum(*str) && *str != '_')
> > +                       return false;
> > +               str++;
> > +       }
> > +
> > +       return true;
> > +}
> > +
> > +static int find_tr_instance(const char *name)
>
> is this finding a slot ?

This function finds index of trace instance which was previously
"opened" (with open command)

> not that slot is meaningful, but instance is at risk of overuse.
>

What is your suggestion for a function name ?

> > +{
> > +       int idx;
> > +
> > +       for_each_set_bit(idx, tr.bmap, tr.bmap_size)
> > +               if (!strcmp(tr.inst[idx].name, name))
> > +                       return idx;
> > +
> > +       return -ENOENT;
> > +}
> > +
> > +static int handle_tr_opend_cmd(const char *arg)
>
> handle_open_?trace_cmd or  handle_trace_?open_cmd ?
>

I will change to handle_trace_open_cmd

> > +{
> > +       struct ddebug_trace_inst *inst;
> > +       int idx, ret = 0;
> > +
> > +       mutex_lock(&ddebug_lock);
> > +
> > +       idx = find_first_zero_bit(tr.bmap, tr.bmap_size);
> > +       if (idx == tr.bmap_size) {
> > +               ret = -ENOSPC;
> > +               goto end;
> > +       }
> > +
> > +       if (!validate_tr_name(arg)) {
> > +               pr_err("invalid instance name:%s\n", arg);
> > +               ret = -EINVAL;
> > +               goto end;
> > +       }
> > +
> > +       if (find_tr_instance(arg) >= 0) {
> > +               pr_err("instance is already opened name:%s\n ", arg);
> > +               ret = -EEXIST;
> > +               goto end;
> > +       }
> > +
> > +       inst = &tr.inst[idx];
> > +       inst->name = kstrdup(arg, GFP_KERNEL);
> > +       if (!inst->name) {
> > +               ret = -ENOMEM;
> > +               goto end;
> > +       }
> > +
> > +       inst->arr = trace_array_get_by_name(inst->name);
> > +       if (!inst->arr) {
>
> any advice (pr_notice) worth giving if this happens ?

I will add

> conversely, does this get need a corresponding put ?
> yes - I see it in the close-cmd-handler
> if so, can we check the inst->arr before (re-)calling get-by-name ?
>

The open/close commands make sure that we won't call trace_array_get_by_name
on the same trace instance again before it is closed. The open command
will fail if it is called again for already opened instance.
The open command increases reference count of the instance and close
command decrements it.
Checking inst->arr without holding its reference would be risky.

> Or does doing this tie up the instance,
> blocking the user from deleting it ?
>

Function trace_array_get_by_name also increases reference count of a
given trace instance
which prohibits a user from deleting it.

> > +               ret = -EINVAL;
> > +               goto end;trace_array_get_by_name
> > +       }
> > +
> > +       ret = trace_array_init_printk(inst->arr);
> > +       if (ret) {
> > +               trace_array_put(inst->arr);
> > +               trace_array_destroy(inst->arr);
> > +               goto end;
> > +       }
> > +
> > +       set_bit(idx, tr.bmap);
> > +       v3pr_info("opened trace instance idx=%d, name=%s\n", idx, arg);
> > +end:
> > +       mutex_unlock(&ddebug_lock);
> > +       return ret;
> > +}
> > +
> > +static int handle_tr_close_cmd(const char *arg)
> > +{
> > +       struct ddebug_trace_inst *inst;
> > +       int idx, ret = 0;
> > +
> > +       mutex_lock(&ddebug_lock);
> > +
> > +       idx = find_tr_instance(arg);
> > +       if (idx < 0) {
> > +               ret = idx;
> > +               goto end;
> > +       }
> > +
> > +       inst = &tr.inst[idx];
> > +
> > +       trace_array_put(inst->arr);
> > +       /*
> > +        * don't destroy trace instance but let user do it manually
> > +        * with rmdir command at a convenient time later, if it is
> > +        * destroyed here all debug logs will be lost
> > +        *
>
> aha.  thx for this comment. it clarifies something I asked somewhere
>

;)

> > +        * trace_array_destroy(inst->arr);
> > +        */
> > +       inst->arr = NULL;
> > +
> > +       kfree(inst->name);
> > +       inst->name = NULL;
> > +
> > +       clear_bit(idx, tr.bmap);
> > +       v3pr_info("closed trace instance idx=%d, name=%s\n", idx, arg);
> > +end:
> > +       mutex_unlock(&ddebug_lock);
> > +       return ret;
> > +}
> > +
> > +static int ddebug_parse_cmd(char *words[], int nwords)
> > +{
> > +       int ret;
> > +
> > +       if (nwords != 1)
> > +               return -EINVAL;
> > +
> > +       if (!strcmp(words[0], DD_OPEN_CMD))
> > +               ret = handle_tr_opend_cmd(words[1]);
>
>   just return handle_() ?
>   and drop following else
>

Ack

> > +       else if (!strcmp(words[0], DD_CLOSE_CMD))
> > +               ret = handle_tr_close_cmd(words[1]);
> > +       else {
> > +               pr_err("invalid command %s\n", words[0]);
> > +               ret = -EINVAL;
>
> just return here.
>

Ack

Thanks,
Lukasz


> > +}
> > +
> >  static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table const *dt,
> >                                                           const char *class_string, int *class_id)
> >  {
> > @@ -567,6 +731,11 @@ static int ddebug_exec_query(char *query_string, const char *modname)
> >                 pr_err("tokenize failed\n");
> >                 return -EINVAL;
> >         }
> > +
> > +       /* check for open, close commands */
> > +       if (is_ddebug_cmd(words[0]))
> > +               return ddebug_parse_cmd(words, nwords-1);
> > +
> >         /* check flags 1st (last arg) so query is pairs of spec,val */
> >         if (ddebug_parse_flags(words[nwords-1], &modifiers)) {
> >                 pr_err("flags parse failed\n");
> > @@ -1191,6 +1360,20 @@ static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
> >         return &iter->table->ddebugs[iter->idx];
> >  }
> >
> > +/*
> > + * Check if the iterator points to the last _ddebug object
> > + * to traverse.
> > + */
> > +static bool ddebug_iter_is_last(struct ddebug_iter *iter)
> > +{
> > +       if (iter->table == NULL)
> > +               return false;
> > +       if (iter->idx-1 < 0 &&
> > +           list_is_last(&iter->table->link, &ddebug_tables))
> > +               return true;
> > +       return false;
> > +}
> > +
> >  /*
> >   * Seq_ops start method.  Called at the start of every
> >   * read() call from userspace.  Takes the ddebug_lock and
> > @@ -1281,6 +1464,16 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
> >         }
> >         seq_puts(m, "\n");
> >
> > +       if (ddebug_iter_is_last(iter) &&
> > +           !bitmap_empty(tr.bmap, tr.bmap_size)) {
> > +               int idx;
> > +
> > +               seq_puts(m, "\n");
> > +               seq_puts(m, "Opened trace instances:\n");
> > +               for_each_set_bit(idx, tr.bmap, tr.bmap_size)
> > +                       seq_printf(m, "%s\n", tr.inst[idx].name);
> > +       }
> > +
> >         return 0;
> >  }
> >
> > --
> > 2.43.0.rc2.451.g8631bc7472-goog
> >

  reply	other threads:[~2023-12-18  1:07 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-30 23:40 [PATCH v2 00/15] dyndbg: add support for writing debug logs to trace Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 01/15] dyndbg: add _DPRINTK_FLAGS_ENABLED Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 02/15] dyndbg: add _DPRINTK_FLAGS_TRACE Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 03/15] dyndbg: add write events to tracefs code Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 04/15] dyndbg: add 2 trace-events: prdbg, devdbg Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 05/15] tracefs: add __get_str_strip_nl - RFC Łukasz Bartosik
2023-12-01  0:25   ` Steven Rostedt
2023-12-01  9:00     ` Łukasz Bartosik
2023-12-08  0:15       ` [re: PATCH v2 00/15 - 00/11] dyndbg: add support for writing debug logs to trace Jim Cromie
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 01/11] dyndbg: export _print_hex_dump Jim Cromie
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 02/11] dyndbg: tweak pr_info format s/trace dest/trace_dest/ Jim Cromie
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 03/11] dyndbg: disambiguate quoting in a debug msg Jim Cromie
2023-12-18 16:34           ` Petr Mladek
2023-12-19 23:38             ` jim.cromie
2024-01-04  7:54               ` Petr Mladek
2024-01-05  0:06                 ` jim.cromie
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 04/11] dyndbg: fix old BUG_ON in >control parser Jim Cromie
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 05/11] dyndbg: change +T:name_terminator to dot Jim Cromie
2023-12-18 17:29           ` Petr Mladek
2023-12-21 15:21             ` Łukasz Bartosik
2024-01-04  7:54               ` Petr Mladek
2024-01-08 12:21                 ` Łukasz Bartosik
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 06/11] dyndbg: treat comma as a token separator Jim Cromie
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 07/11] dyndbg: __skip_spaces Jim Cromie
2023-12-18 17:17           ` Petr Mladek
2023-12-21 15:25             ` Łukasz Bartosik
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 08/11] dyndbg: split multi-query strings with % Jim Cromie
2023-12-09  0:32           ` Łukasz Bartosik
2023-12-11  1:07             ` jim.cromie
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 09/11] dyndbg: reduce verbose/debug clutter Jim Cromie
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 10/11] dyndbg: move lock,unlock into ddebug_change, drop goto Jim Cromie
2023-12-09  0:32           ` Łukasz Bartosik
2023-12-08  0:15         ` [re: PATCH v2 00/15 - 11/11] dyndbg: id the bad word in parse-flags err msg Jim Cromie
2023-12-09  0:31         ` [re: PATCH v2 00/15 - 00/11] dyndbg: add support for writing debug logs to trace Łukasz Bartosik
2023-12-14 15:20           ` Łukasz Bartosik
2023-12-16  3:09             ` jim.cromie
2023-12-18  1:01               ` Łukasz Bartosik
2023-12-18 14:12                 ` Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 06/15] dyndbg: use __get_str_strip_nl in prdbg and devdbg Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 07/15] dyndbg: repack _ddebug structure Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 08/15] dyndbg: move flags field to a new structure Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 09/15] dyndbg: add trace destination field to _ddebug Łukasz Bartosik
2023-12-14  7:09   ` jim.cromie
2023-12-14 15:46     ` Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 10/15] dyndbg: add open and close commands for trace Łukasz Bartosik
2023-12-16  6:17   ` jim.cromie
2023-12-18  1:07     ` Łukasz Bartosik [this message]
2024-01-05 22:46   ` Jason Baron
2024-01-09 15:19     ` jim.cromie
2024-01-10 12:40       ` Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 11/15] dyndbg: don't close trace instance when in use Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 12/15] dyndbg: add processing of T(race) flag argument Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 13/15] dyndbg: add support for default trace destination Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 14/15] dyndbg: write debug logs to trace instance Łukasz Bartosik
2023-11-30 23:40 ` [PATCH v2 15/15] dyndbg: add support for hex_dump output to trace Łukasz Bartosik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAK8ByeLwbYZW6zLnjy4UZsjvoDNkiudAgiNxRCbOPg8DLKGe0Q@mail.gmail.com \
    --to=lb@semihalf.com \
    --cc=akpm@linux-foundation.org \
    --cc=bleung@google.com \
    --cc=daniel@ffwll.ch \
    --cc=dianders@chromium.org \
    --cc=groeck@google.com \
    --cc=jbaron@akamai.com \
    --cc=jim.cromie@gmail.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ppaalanen@gmail.com \
    --cc=rostedt@goodmis.org \
    --cc=seanpaul@chromium.org \
    --cc=upstream@semihalf.com \
    --cc=vincent.whitchurch@axis.com \
    --cc=yanivt@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).