From: Linu Cherian <linuc.decode@gmail.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: paulmck@linux.vnet.ibm.com, rkrcmar@redhat.com,
kvm@vger.kernel.org, linu.cherian@cavium.com,
sunil.goutham@cavium.com, Geethasowjanya.Akula@cavium.com
Subject: Re: Possible race condition during lock_count increment in srcu_read_lock
Date: Wed, 31 May 2017 18:33:30 +0530 [thread overview]
Message-ID: <20170531130330.GA15887@virtx40> (raw)
In-Reply-To: <a0ad9967-95c8-b596-5ca6-a63f45bf0ad9@redhat.com>
On Tue May 30, 2017 at 03:49:31PM +0200, Paolo Bonzini wrote:
>
>
> On 29/05/2017 22:14, Paul E. McKenney wrote:
> > On Mon, May 29, 2017 at 06:38:19PM +0200, Paolo Bonzini wrote:
> >> On 29/05/2017 17:50, Paul E. McKenney wrote:
> >>> You actually are not supposed to call __srcu_read_lock() and
> >>> __srcu_read_unlock() from irq context. (Unless you know that you
> >>> interrupted some context that is guaranteed never to use the srcu_struct
> >>> in question or some such.)
>
> I was going to improve the SRCU doc comments, and then started digging
> into srcu.c history to find out why srcu_read_unlock uses this_cpu_inc.
>
> It turns out that back in 2012 __srcu_read_lock did two accesses to
> percpu variables, while __srcu_read_unlock did one (a decrement). Then,
> commit 5a41344a3d83 ("srcu: Simplify __srcu_read_unlock() via
> this_cpu_dec()", 2012-11-29) changed __srcu_read_unlock to use
> this_cpu_dec and remove the preempt_disable/preempt_enable pair.
>
> Nowadays, __srcu_read_lock only does one access to percpu variables so
> we could do the same as commit 5a41344a3d83 did:
>
> diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> index 167ad8831aaf..4c1d5f7e62c4 100644
> --- a/include/linux/srcu.h
> +++ b/include/linux/srcu.h
> @@ -172,9 +172,7 @@ static inline int srcu_read_lock(struct srcu_struct *sp) __acquires(sp)
> {
> int retval;
>
> - preempt_disable();
> retval = __srcu_read_lock(sp);
> - preempt_enable();
> rcu_lock_acquire(&(sp)->dep_map);
> return retval;
> }
> diff --git a/kernel/rcu/srcu.c b/kernel/rcu/srcu.c
> index 584d8a983883..dea03614263f 100644
> --- a/kernel/rcu/srcu.c
> +++ b/kernel/rcu/srcu.c
> @@ -263,7 +263,7 @@ void cleanup_srcu_struct(struct srcu_struct *sp)
>
> /*
> * Counts the new reader in the appropriate per-CPU element of the
> - * srcu_struct. Must be called from process context.
> + * srcu_struct.
> * Returns an index that must be passed to the matching srcu_read_unlock().
> */
> int __srcu_read_lock(struct srcu_struct *sp)
> @@ -271,7 +271,7 @@ int __srcu_read_lock(struct srcu_struct *sp)
> int idx;
>
> idx = READ_ONCE(sp->completed) & 0x1;
> - __this_cpu_inc(sp->per_cpu_ref->lock_count[idx]);
> + this_cpu_inc(sp->per_cpu_ref->lock_count[idx]);
> smp_mb(); /* B */ /* Avoid leaking the critical section. */
> return idx;
> }
> @@ -281,7 +281,6 @@ int __srcu_read_lock(struct srcu_struct *sp)
> * Removes the count for the old reader from the appropriate per-CPU
> * element of the srcu_struct. Note that this may well be a different
> * CPU than that which was incremented by the corresponding srcu_read_lock().
> - * Must be called from process context.
> */
> void __srcu_read_unlock(struct srcu_struct *sp, int idx)
> {
>
>
> As said earlier, this would slow down SRCU on machines where neither fast
> this_cpu_inc nor atomic_inc_relaxed are available, and local_irq_save/restore
> is slower than disabling preemption. The main one is s390, which however is
> already paying the price in __srcu_read_unlock.
>
> Any objections to the above for 4.12, with commit message explaining both the
> history of __srcu_read_unlock and what this fixes in KVM?
>
> Thanks,
>
> Paolo
>
This works for me atleast on 4.11.2 kernel on Cavium arm64 platform.
Thanks.
--
Linu cherian
prev parent reply other threads:[~2017-05-31 13:03 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-29 14:30 Possible race condition during lock_count increment in srcu_read_lock Linu Cherian
2017-05-29 15:05 ` Paolo Bonzini
2017-05-29 15:50 ` Paul E. McKenney
2017-05-29 16:38 ` Paolo Bonzini
2017-05-29 20:14 ` Paul E. McKenney
2017-05-30 13:49 ` Paolo Bonzini
2017-05-30 16:19 ` Paul E. McKenney
2017-05-31 13:03 ` Linu Cherian [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=20170531130330.GA15887@virtx40 \
--to=linuc.decode@gmail.com \
--cc=Geethasowjanya.Akula@cavium.com \
--cc=kvm@vger.kernel.org \
--cc=linu.cherian@cavium.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=pbonzini@redhat.com \
--cc=rkrcmar@redhat.com \
--cc=sunil.goutham@cavium.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.