Re: [PATCH v3 06/10] iio: adc: ad_sigma_delta: Fix a race condition

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

 



On Fri, Nov 22, 2024 at 1:34 PM Uwe Kleine-König
<u.kleine-koenig@xxxxxxxxxxxx> wrote:
>
> The ad_sigma_delta driver helper uses irq_disable_nosync(). With that
> one it is possible that the irq handler still runs after the
> irq_disable_nosync() function call returns. Also to properly synchronize
> irq disabling in the different threads proper locking is needed and
> because it's unclear if the irq handler's irq_disable_nosync() call
> comes first or the one in the enabler's error path, all code locations
> that disable the irq must check for .irq_dis first to ensure there is
> exactly one disable per enable.

"...exactly one disable call per one enable call."

> So add a spinlock to the struct ad_sigma_delta and use it to synchronize
> irq enabling and disabling. Also only act in the irq handler if the irq
> is still enabled.

...

> +static bool ad_sd_disable_irq(struct ad_sigma_delta *sigma_delta)
> +{
> +       guard(spinlock_irqsave)(&sigma_delta->irq_lock);
> +
> +       if (!sigma_delta->irq_dis) {

Why not positive conditional?

  if (->irq_dis)
    return false;
  ...
  return true;

> +               sigma_delta->irq_dis = true;
> +               disable_irq_nosync(sigma_delta->irq_line);
> +               return true;
> +       } else {
> +               return false;
> +       }
> +}

...

>  /* private: */

Consider at some point marking the below members with __private.

>         struct completion       completion;
> +       spinlock_t              irq_lock; /* protects .irq_dis and irq en/disable state */
>         bool                    irq_dis;

-- 
With Best Regards,
Andy Shevchenko





[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux