All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Kent Gibson <warthog618@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Jack Winch <sunt.un.morcov@gmail.com>,
	Helmut Grohne <helmut.grohne@intenta.de>,
	Ben Hutchings <ben.hutchings@essensium.com>,
	"open list:GPIO SUBSYSTEM" <linux-gpio@vger.kernel.org>
Subject: Re: [libgpiod v2][PATCH] line-config: rework the internal implementation
Date: Fri, 8 Oct 2021 21:15:22 +0200	[thread overview]
Message-ID: <CAMRc=MfJVAB4day4Qvq1VdMcoqH6pLr7=FFjri=6VotxqtZ3Bg@mail.gmail.com> (raw)
In-Reply-To: <20211005042022.GA109255@sol>

On Tue, Oct 5, 2021 at 6:20 AM Kent Gibson <warthog618@gmail.com> wrote:
>
> On Wed, Sep 22, 2021 at 10:11:00AM +0200, Bartosz Golaszewski wrote:
> > This reworks how the line config objects work internally. In order to reduce
> > the size of the gpiod_line_config objects, we switch from using a set number
> > of override config structures with each storing a list of line offsets to
> > storing a smaller override object for each of the maximum of 64 lines.
> > Additionally these internal config structures are now packed and only occupy
> > the minimum required amount of memory.
> >
> > The processing of these new overrides has become a bit more complicated but
> > should actually be more robust wrt corner cases.
> >
> > Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
>
> Given the level of rework the diff is harder work than looking at the
> resulting code, but it all looks good to me.
> A few minor comments scattered below.
>

[snip]

> >
> >  GPIOD_API struct gpiod_line_config *gpiod_line_config_new(void)
>
> You don't have any change to gpiod_line_config_free() here, but
> isn't free() guaranteed to be NULL aware, so you can drop the NULL
> check?
> If not, couldn't it be flipped to:
>
>         if (config)
>                 free(config);
>
> Similarly gpiod_line_config_new() could have
>
>         if (config)
>                 gpiod_line_config_reset(config);
>
> and that "if" could be dropped if gpiod_line_config_reset() were NULL
> aware.
>

No, you're right, as long as we don't dereference the pointer, we can
drop the check. Here and elsewhere.

> But the general policy is that gpiod functions are not NULL aware?
>

In general yes, but various free functions are NULL-aware.

[snip]

> >  static struct base_config *
> > -get_base_config_for_offset(struct gpiod_line_config *config,
> > -                        unsigned int offset)
> > +get_base_config_for_reading(struct gpiod_line_config *config,
> > +                        unsigned int offset, unsigned int flag)
> >  {
> > -     struct secondary_config *secondary;
> > -     unsigned int i, j;
> > -
> > -     /*
> > -      * We're looking backwards as the settings get overwritten if set
> > -      * multiple times.
> > -      */
> > -     for (i = config->num_secondary; i > 0; i--) {
> > -             secondary = &config->secondary[i - 1];
> > +     struct override_config *override;
> >
> > -             for (j = 0; j < secondary->num_offsets; j++) {
> > -                     if (secondary->offsets[j] == offset)
> > -                             return &secondary->config;
> > -             }
> > -     }
> > +     override = get_override_by_offset(config, offset);
> > +     if (!override || !(override->override_flags & flag))
> > +             return &config->defaults;
> >
> > -     return NULL;
> > +     return &override->base;
> >  }
> >
>
> Maybe flip the logic around to make it easier to read:
>
>         if (override && (override->override_flags & flag))
>                 return &override->base;
>
>     return &config->defaults;
>
> Similarly in gpiod_line_config_get_output_value().
>

Done.

> >  static void set_direction(struct base_config *config, int direction)
>
> In set_direction() you have a specific case (GPIOD_LINE_DIRECTION_AS_IS)
> that matches the default behaviour.  I generally drop that case and let
> the default handle it, but that is just personal preference.
>
> Similarly in other set_XXX switches.
>

My personal preference is to be explicit and include those default
cases even if only to tell my future self what's happening here.

> > @@ -209,7 +170,7 @@ static void set_direction(struct base_config *config, int direction)
> >  GPIOD_API void
> >  gpiod_line_config_set_direction(struct gpiod_line_config *config, int direction)
> >  {
> > -     set_direction(&config->primary, direction);
> > +     set_direction(&config->defaults, direction);
> >  }
> >
> >  GPIOD_API void
> > @@ -224,13 +185,19 @@ gpiod_line_config_set_direction_subset(struct gpiod_line_config *config,
> >                                      int direction, unsigned int num_offsets,
> >                                      const unsigned int *offsets)
> >  {
> > -     struct secondary_config *secondary;
> > +     struct override_config *override;
> > +     unsigned int i, offset;
> >
> > -     secondary = get_secondary_config(config, num_offsets, offsets);
> > -     if (!secondary)
> > -             return;
> > +     for (i = 0; i < num_offsets; i++) {
> > +             offset = offsets[i];
> >
>
> Worth the effort given it is only used once?
>

Must have been a leftover, thanks.

[snip]

> >
> >  GPIOD_API void
> > @@ -464,20 +448,26 @@ gpiod_line_config_set_active_high_subset(struct gpiod_line_config *config,
> >                                        unsigned int num_offsets,
> >                                        const unsigned int *offsets)
> >  {
> > -     struct secondary_config *secondary;
> > +     struct override_config *override;
> > +     unsigned int i, offset;
> >
> > -     secondary = get_secondary_config(config, num_offsets, offsets);
> > -     if (!secondary)
> > -             return;
> > +     for (i = 0; i < num_offsets; i++) {
> > +             offset = offsets[i];
> > +
> > +             override = get_override_config_for_writing(config, offset);
> > +             if (!override)
> > +                     return;
> >
> > -     secondary->config.active_low = false;
> > +             override->base.active_low = false;
> > +             override->override_flags |= OVERRIDE_FLAG_ACTIVE_LOW;
> > +     }
> >  }
> >
>
> gpiod_line_config_set_active_low_subset() and
> gpiod_line_config_set_active_high_subset() could call a common helper
> that accepts the active_low as a parameter?
>

Makes sense.

[snip]

> > +
> > +static bool override_config_debounce_period_is_equal(struct override_config *a,
> > +                                                  struct override_config *b)
> > +{
> > +     if (base_debounce_period_is_equal(&a->base, b) &&
> > +         ((a->override_flags & OVERRIDE_FLAG_DEBOUNCE_PERIOD) ==
> > +          (b->override_flags & OVERRIDE_FLAG_DEBOUNCE_PERIOD)))
> > +             return true;
> > +
> > +     return false;
> > +}
> > +
>
> To improve readability, flip the order here to test the flag equivalence
> first.
> Particularly wrt the "a" doesn't have debounce overridden case.
>

Done.

[snip]

>
> Don't see anything wrong here, but I'd like to see a bunch of tests to
> cover the corner cases you mentioned, as the bulk of the module complexity
> is here.
> Not that I expect that now.
>

Yes, definitely. Trying to get the gpio-sim module upstream for this
exact reason. Please take a look at this series if you can.

[snip]

>
> Overall it looks really good to me, so no problem with applying it,
> with or without my suggestions.

I've applied most of your suggestions and will squash this into the
big patch, thanks as usual!

Bart

      reply	other threads:[~2021-10-08 19:15 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-22  8:11 [libgpiod v2][PATCH] line-config: rework the internal implementation Bartosz Golaszewski
2021-10-05  4:20 ` Kent Gibson
2021-10-08 19:15   ` Bartosz Golaszewski [this message]

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='CAMRc=MfJVAB4day4Qvq1VdMcoqH6pLr7=FFjri=6VotxqtZ3Bg@mail.gmail.com' \
    --to=brgl@bgdev.pl \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=ben.hutchings@essensium.com \
    --cc=helmut.grohne@intenta.de \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=sunt.un.morcov@gmail.com \
    --cc=warthog618@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.