All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Vyukov <dvyukov@google.com>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org,
	Andrey Konovalov <andreyknvl@gmail.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Steven Rostedt <rostedt@goodmis.org>,
	Marco Elver <elver@google.com>,
	Clark Williams <williams@redhat.com>
Subject: Re: [PATCH 5/5] kcov: Replace local_irq_save() with a local_lock_t.
Date: Fri, 17 Sep 2021 16:58:21 +0200	[thread overview]
Message-ID: <CACT4Y+axiW+rAs+8a8E9WRx+rpv67ciKcZT_qEqZ_Hyt-7hLVQ@mail.gmail.com> (raw)
In-Reply-To: <20210830172627.267989-6-bigeasy@linutronix.de>

/On Mon, 30 Aug 2021 at 19:26, Sebastian Andrzej Siewior
<bigeasy@linutronix.de> wrote:
>
> The kcov code mixes local_irq_save() and spin_lock() in
> kcov_remote_{start|end}(). This creates a warning on PREEMPT_RT because
> local_irq_save() disables interrupts and spin_lock_t is turned into a
> sleeping lock which can not be acquired in a section with disabled
> interrupts.
>
> The kcov_remote_lock is used to synchronize the access to the hash-list
> kcov_remote_map. The local_irq_save() block protects access to the
> per-CPU data kcov_percpu_data.
>
> There no compelling reason to change the lock type to raw_spin_lock_t to
> make it work with local_irq_save(). Changing it would require to move
> memory allocation (in kcov_remote_add()) and deallocation outside of the
> locked section.
> Adding an unlimited amount of entries to the hashlist will increase the
> IRQ-off time during lookup. It could be argued that this is debug code
> and the latency does not matter. There is however no need to do so and
> it would allow to use this facility in an RT enabled build.
>
> Using a local_lock_t instead of local_irq_save() has the befit of adding
> a protection scope within the source which makes it obvious what is
> protected. On a !PREEMPT_RT && !LOCKDEP build the local_lock_irqsave()
> maps directly to local_irq_save() so there is overhead at runtime.

s/befit/benefit/
s/overhead/no overhead/

but otherwise

Acked-by: Dmitry Vyukov <dvyukov@google.com>

> Replace the local_irq_save() section with a local_lock_t.
>
> Reported-by: Clark Williams <williams@redhat.com>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>  kernel/kcov.c | 30 +++++++++++++++++-------------
>  1 file changed, 17 insertions(+), 13 deletions(-)
>
> diff --git a/kernel/kcov.c b/kernel/kcov.c
> index 620dc4ffeb685..36ca640c4f8e7 100644
> --- a/kernel/kcov.c
> +++ b/kernel/kcov.c
> @@ -88,6 +88,7 @@ static struct list_head kcov_remote_areas = LIST_HEAD_INIT(kcov_remote_areas);
>
>  struct kcov_percpu_data {
>         void                    *irq_area;
> +       local_lock_t            lock;
>
>         unsigned int            saved_mode;
>         unsigned int            saved_size;
> @@ -96,7 +97,9 @@ struct kcov_percpu_data {
>         int                     saved_sequence;
>  };
>
> -static DEFINE_PER_CPU(struct kcov_percpu_data, kcov_percpu_data);
> +static DEFINE_PER_CPU(struct kcov_percpu_data, kcov_percpu_data) = {
> +       .lock = INIT_LOCAL_LOCK(lock),
> +};
>
>  /* Must be called with kcov_remote_lock locked. */
>  static struct kcov_remote *kcov_remote_find(u64 handle)
> @@ -824,7 +827,7 @@ void kcov_remote_start(u64 handle)
>         if (!in_task() && !in_serving_softirq())
>                 return;
>
> -       local_irq_save(flags);
> +       local_lock_irqsave(&kcov_percpu_data.lock, flags);
>
>         /*
>          * Check that kcov_remote_start() is not called twice in background
> @@ -832,7 +835,7 @@ void kcov_remote_start(u64 handle)
>          */
>         mode = READ_ONCE(t->kcov_mode);
>         if (WARN_ON(in_task() && kcov_mode_enabled(mode))) {
> -               local_irq_restore(flags);
> +               local_unlock_irqrestore(&kcov_percpu_data.lock, flags);
>                 return;
>         }
>         /*
> @@ -841,14 +844,15 @@ void kcov_remote_start(u64 handle)
>          * happened while collecting coverage from a background thread.
>          */
>         if (WARN_ON(in_serving_softirq() && t->kcov_softirq)) {
> -               local_irq_restore(flags);
> +               local_unlock_irqrestore(&kcov_percpu_data.lock, flags);
>                 return;
>         }
>
>         spin_lock(&kcov_remote_lock);
>         remote = kcov_remote_find(handle);
>         if (!remote) {
> -               spin_unlock_irqrestore(&kcov_remote_lock, flags);
> +               spin_unlock(&kcov_remote_lock);
> +               local_unlock_irqrestore(&kcov_percpu_data.lock, flags);
>                 return;
>         }
>         kcov_debug("handle = %llx, context: %s\n", handle,
> @@ -873,13 +877,13 @@ void kcov_remote_start(u64 handle)
>
>         /* Can only happen when in_task(). */
>         if (!area) {
> -               local_irqrestore(flags);
> +               local_unlock_irqrestore(&kcov_percpu_data.lock, flags);
>                 area = vmalloc(size * sizeof(unsigned long));
>                 if (!area) {
>                         kcov_put(kcov);
>                         return;
>                 }
> -               local_irq_save(flags);
> +               local_lock_irqsave(&kcov_percpu_data.lock, flags);
>         }
>
>         /* Reset coverage size. */
> @@ -891,7 +895,7 @@ void kcov_remote_start(u64 handle)
>         }
>         kcov_start(t, kcov, size, area, mode, sequence);
>
> -       local_irq_restore(flags);
> +       local_unlock_irqrestore(&kcov_percpu_data.lock, flags);
>
>  }
>  EXPORT_SYMBOL(kcov_remote_start);
> @@ -965,12 +969,12 @@ void kcov_remote_stop(void)
>         if (!in_task() && !in_serving_softirq())
>                 return;
>
> -       local_irq_save(flags);
> +       local_lock_irqsave(&kcov_percpu_data.lock, flags);
>
>         mode = READ_ONCE(t->kcov_mode);
>         barrier();
>         if (!kcov_mode_enabled(mode)) {
> -               local_irq_restore(flags);
> +               local_unlock_irqrestore(&kcov_percpu_data.lock, flags);
>                 return;
>         }
>         /*
> @@ -978,12 +982,12 @@ void kcov_remote_stop(void)
>          * actually found the remote handle and started collecting coverage.
>          */
>         if (in_serving_softirq() && !t->kcov_softirq) {
> -               local_irq_restore(flags);
> +               local_unlock_irqrestore(&kcov_percpu_data.lock, flags);
>                 return;
>         }
>         /* Make sure that kcov_softirq is only set when in softirq. */
>         if (WARN_ON(!in_serving_softirq() && t->kcov_softirq)) {
> -               local_irq_restore(flags);
> +               local_unlock_irqrestore(&kcov_percpu_data.lock, flags);
>                 return;
>         }
>
> @@ -1013,7 +1017,7 @@ void kcov_remote_stop(void)
>                 spin_unlock(&kcov_remote_lock);
>         }
>
> -       local_irq_restore(flags);
> +       local_unlock_irqrestore(&kcov_percpu_data.lock, flags);
>
>         /* Get in kcov_remote_start(). */
>         kcov_put(kcov);
> --
> 2.33.0
>

  reply	other threads:[~2021-09-17 14:58 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-30 17:26 [PATCH 0/5] kcov: PREEMPT_RT fixup + misc Sebastian Andrzej Siewior
2021-08-30 17:26 ` [PATCH 1/5] Documentation/kcov: Include types.h in the example Sebastian Andrzej Siewior
2021-09-17 14:34   ` Dmitry Vyukov
2021-08-30 17:26 ` [PATCH 2/5] Documentation/kcov: Define `ip' " Sebastian Andrzej Siewior
2021-09-17 14:37   ` Dmitry Vyukov
2021-08-30 17:26 ` [PATCH 3/5] kcov: Allocate per-CPU memory on the relevant node Sebastian Andrzej Siewior
2021-09-17 14:38   ` Dmitry Vyukov
2021-08-30 17:26 ` [PATCH 4/5] kcov: Avoid enable+disable interrupts if !in_task() Sebastian Andrzej Siewior
2021-09-17 14:50   ` Dmitry Vyukov
2021-08-30 17:26 ` [PATCH 5/5] kcov: Replace local_irq_save() with a local_lock_t Sebastian Andrzej Siewior
2021-09-17 14:58   ` Dmitry Vyukov [this message]
2021-09-06 16:13 ` [PATCH 0/5] kcov: PREEMPT_RT fixup + misc Marco Elver
2021-09-06 16:28   ` Sebastian Andrzej Siewior
2021-09-20  9:26     ` Marco Elver
2021-09-20  9:50       ` Sebastian Andrzej Siewior

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=CACT4Y+axiW+rAs+8a8E9WRx+rpv67ciKcZT_qEqZ_Hyt-7hLVQ@mail.gmail.com \
    --to=dvyukov@google.com \
    --cc=andreyknvl@gmail.com \
    --cc=bigeasy@linutronix.de \
    --cc=elver@google.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=williams@redhat.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.