Re: [PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-16 Thread Stephen Rothwell
Hi all,

On Wed, 16 Sep 2020 15:02:33 +0200 pet...@infradead.org wrote:
>
> On Wed, Sep 16, 2020 at 09:00:59AM -0400, Qian Cai wrote:
> > 
> > 
> > - Original Message -  
> > > On Wed, Sep 16, 2020 at 08:52:07AM -0400, Qian Cai wrote:  
> > > > On Tue, 2020-09-15 at 16:30 +0200, pet...@infradead.org wrote:  
> > > > > On Tue, Sep 15, 2020 at 08:48:17PM +0800, Boqun Feng wrote:  
> > > > > > I think this happened because seqcount_##lockname##_init() is 
> > > > > > defined
> > > > > > at
> > > > > > function rather than macro, so when the seqcount_init() gets expand 
> > > > > > in  
> > > > > 
> > > > > Bah! I hate all this :/
> > > > > 
> > > > > I suspect the below, while more verbose than I'd like is the best
> > > > > option.  
> > > > 
> > > > Stephen, can you add this patch for now until Peter beats you to it?  
> > > 
> > > Did you verify it works? I only wrote it..  
> > 
> > Yes, I did.  
> 
> Excellent, I'll stick a Tested-by from you on then.

I'll add this into the tip tree merge today (unless the tip tree is
updated in the mean time).

-- 
Cheers,
Stephen Rothwell


pgpl8Iukb0goQ.pgp
Description: OpenPGP digital signature


Re: [PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-16 Thread Qian Cai



- Original Message -
> On Wed, Sep 16, 2020 at 08:52:07AM -0400, Qian Cai wrote:
> > On Tue, 2020-09-15 at 16:30 +0200, pet...@infradead.org wrote:
> > > On Tue, Sep 15, 2020 at 08:48:17PM +0800, Boqun Feng wrote:
> > > > I think this happened because seqcount_##lockname##_init() is defined
> > > > at
> > > > function rather than macro, so when the seqcount_init() gets expand in
> > > 
> > > Bah! I hate all this :/
> > > 
> > > I suspect the below, while more verbose than I'd like is the best
> > > option.
> > 
> > Stephen, can you add this patch for now until Peter beats you to it?
> 
> Did you verify it works? I only wrote it..

Yes, I did.



Re: [PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-16 Thread Qian Cai
On Tue, 2020-09-15 at 16:30 +0200, pet...@infradead.org wrote:
> On Tue, Sep 15, 2020 at 08:48:17PM +0800, Boqun Feng wrote:
> > I think this happened because seqcount_##lockname##_init() is defined at
> > function rather than macro, so when the seqcount_init() gets expand in
> 
> Bah! I hate all this :/
> 
> I suspect the below, while more verbose than I'd like is the best
> option.

Stephen, can you add this patch for now until Peter beats you to it?

> 
> ---
>  include/linux/seqlock.h | 22 ++
>  1 file changed, 14 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
> index f73c7eb68f27..76e44e6c0100 100644
> --- a/include/linux/seqlock.h
> +++ b/include/linux/seqlock.h
> @@ -173,6 +173,19 @@ static inline void seqcount_lockdep_reader_access(const
> seqcount_t *s)
>   * @lock:Pointer to the associated lock
>   */
>  
> +#define seqcount_LOCKNAME_init(s, _lock, lockname)   \
> + do {\
> + seqcount_##lockname##_t *s = (s);   \
> + seqcount_init(&s->seqcount);\
> + __SEQ_LOCK(s->lock = (_lock));  \
> + } while (0)
> +
> +#define seqcount_raw_spinlock_init(s, lock)  seqcount_LOCKNAME_init(s, lock,
> raw_spinlock)
> +#define seqcount_spinlock_init(s, lock)  seqcount_LOCKNAME_init(s
> , lock, spinlock)
> +#define seqcount_rwlock_init(s, lock)seqcount_LOCKNAME_init(s
> , lock, rwlock);
> +#define seqcount_mutex_init(s, lock) seqcount_LOCKNAME_init(s, lock,
> mutex);
> +#define seqcount_ww_mutex_init(s, lock)  seqcount_LOCKNAME_init(s
> , lock, ww_mutex);
> +
>  /*
>   * SEQCOUNT_LOCKNAME()   - Instantiate seqcount_LOCKNAME_t and helpers
>   * seqprop_LOCKNAME_*()  - Property accessors for seqcount_LOCKNAME_t
> @@ -190,13 +203,6 @@ typedef struct seqcount_##lockname { 
> 
>   \
>   __SEQ_LOCK(locktype *lock); \
>  } seqcount_##lockname##_t;   \
>   \
> -static __always_inline void  \
> -seqcount_##lockname##_init(seqcount_##lockname##_t *s, locktype *lock)   
> \
> -{\
> - seqcount_init(>seqcount);\
> - __SEQ_LOCK(s->lock = lock); \
> -}\
> - \
>  static __always_inline seqcount_t *  \
>  __seqprop_##lockname##_ptr(seqcount_##lockname##_t *s)   
> \
>  {\
> @@ -284,8 +290,8 @@ SEQCOUNT_LOCKNAME(ww_mutex, struct ww_mutex,
> true, >lock->base, ww_mu
>   __SEQ_LOCK(.lock= (assoc_lock)) \
>  }
>  
> -#define SEQCNT_SPINLOCK_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name,
> lock)
>  #define SEQCNT_RAW_SPINLOCK_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name,
> lock)
> +#define SEQCNT_SPINLOCK_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name,
> lock)
>  #define SEQCNT_RWLOCK_ZERO(name, lock)   SEQCOUNT_LOCKNAME_ZERO(n
> ame, lock)
>  #define SEQCNT_MUTEX_ZERO(name, lock)SEQCOUNT_LOCKNAME_ZERO(n
> ame, lock)
>  #define SEQCNT_WW_MUTEX_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name,
> lock)
> 



Re: [PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-16 Thread peterz
On Wed, Sep 16, 2020 at 08:52:07AM -0400, Qian Cai wrote:
> On Tue, 2020-09-15 at 16:30 +0200, pet...@infradead.org wrote:
> > On Tue, Sep 15, 2020 at 08:48:17PM +0800, Boqun Feng wrote:
> > > I think this happened because seqcount_##lockname##_init() is defined at
> > > function rather than macro, so when the seqcount_init() gets expand in
> > 
> > Bah! I hate all this :/
> > 
> > I suspect the below, while more verbose than I'd like is the best
> > option.
> 
> Stephen, can you add this patch for now until Peter beats you to it?

Did you verify it works? I only wrote it..


Re: [PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-16 Thread peterz
On Wed, Sep 16, 2020 at 09:00:59AM -0400, Qian Cai wrote:
> 
> 
> - Original Message -
> > On Wed, Sep 16, 2020 at 08:52:07AM -0400, Qian Cai wrote:
> > > On Tue, 2020-09-15 at 16:30 +0200, pet...@infradead.org wrote:
> > > > On Tue, Sep 15, 2020 at 08:48:17PM +0800, Boqun Feng wrote:
> > > > > I think this happened because seqcount_##lockname##_init() is defined
> > > > > at
> > > > > function rather than macro, so when the seqcount_init() gets expand in
> > > > 
> > > > Bah! I hate all this :/
> > > > 
> > > > I suspect the below, while more verbose than I'd like is the best
> > > > option.
> > > 
> > > Stephen, can you add this patch for now until Peter beats you to it?
> > 
> > Did you verify it works? I only wrote it..
> 
> Yes, I did.

Excellent, I'll stick a Tested-by from you on then.


Re: [PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-15 Thread peterz
On Tue, Sep 15, 2020 at 08:48:17PM +0800, Boqun Feng wrote:
> I think this happened because seqcount_##lockname##_init() is defined at
> function rather than macro, so when the seqcount_init() gets expand in

Bah! I hate all this :/

I suspect the below, while more verbose than I'd like is the best
option.

---
 include/linux/seqlock.h | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index f73c7eb68f27..76e44e6c0100 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -173,6 +173,19 @@ static inline void seqcount_lockdep_reader_access(const 
seqcount_t *s)
  * @lock:  Pointer to the associated lock
  */
 
+#define seqcount_LOCKNAME_init(s, _lock, lockname) \
+   do {\
+   seqcount_##lockname##_t *s = (s);   \
+   seqcount_init(&s->seqcount);\
+   __SEQ_LOCK(s->lock = (_lock));  \
+   } while (0)
+
+#define seqcount_raw_spinlock_init(s, lock)seqcount_LOCKNAME_init(s, lock, 
raw_spinlock)
+#define seqcount_spinlock_init(s, lock)
seqcount_LOCKNAME_init(s, lock, spinlock)
+#define seqcount_rwlock_init(s, lock)  seqcount_LOCKNAME_init(s, lock, 
rwlock);
+#define seqcount_mutex_init(s, lock)   seqcount_LOCKNAME_init(s, lock, 
mutex);
+#define seqcount_ww_mutex_init(s, lock)
seqcount_LOCKNAME_init(s, lock, ww_mutex);
+
 /*
  * SEQCOUNT_LOCKNAME() - Instantiate seqcount_LOCKNAME_t and helpers
  * seqprop_LOCKNAME_*()- Property accessors for seqcount_LOCKNAME_t
@@ -190,13 +203,6 @@ typedef struct seqcount_##lockname {   
\
__SEQ_LOCK(locktype *lock); \
 } seqcount_##lockname##_t; \
\
-static __always_inline void\
-seqcount_##lockname##_init(seqcount_##lockname##_t *s, locktype *lock) \
-{  \
-   seqcount_init(>seqcount);\
-   __SEQ_LOCK(s->lock = lock); \
-}  \
-   \
 static __always_inline seqcount_t *\
 __seqprop_##lockname##_ptr(seqcount_##lockname##_t *s) \
 {  \
@@ -284,8 +290,8 @@ SEQCOUNT_LOCKNAME(ww_mutex, struct ww_mutex, true, 
>lock->base, ww_mu
__SEQ_LOCK(.lock= (assoc_lock)) \
 }
 
-#define SEQCNT_SPINLOCK_ZERO(name, lock)   SEQCOUNT_LOCKNAME_ZERO(name, 
lock)
 #define SEQCNT_RAW_SPINLOCK_ZERO(name, lock)   SEQCOUNT_LOCKNAME_ZERO(name, 
lock)
+#define SEQCNT_SPINLOCK_ZERO(name, lock)   SEQCOUNT_LOCKNAME_ZERO(name, 
lock)
 #define SEQCNT_RWLOCK_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name, 
lock)
 #define SEQCNT_MUTEX_ZERO(name, lock)  SEQCOUNT_LOCKNAME_ZERO(name, 
lock)
 #define SEQCNT_WW_MUTEX_ZERO(name, lock)   SEQCOUNT_LOCKNAME_ZERO(name, 
lock)


Re: [PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-15 Thread Boqun Feng
On Tue, Sep 15, 2020 at 08:48:17PM +0800, Boqun Feng wrote:
> On Mon, Sep 14, 2020 at 08:20:53PM -0400, Qian Cai wrote:
> > On Fri, 2020-09-04 at 17:32 +0200, Ahmed S. Darwish wrote:
> > > Hi,
> > > 
> > > Changelog-v2
> > > 
> > > 
> > >   - Standardize on seqcount_LOCKNAME_t as the canonical reference for
> > > sequence counters with associated locks, instead of v1
> > > seqcount_LOCKTYPE_t.
> > > 
> > >   - Use unique prefix "seqprop_*" for all seqcount_t/seqcount_LOCKNAME_t
> > > property accessors.
> > > 
> > >   - Touch-up the lock-unlock rationale for more clarity. Enforce writer
> > > non-preemitiblity using "__seq_enforce_writer_non_preemptibility()".
> > > 
> > > Cover letter (v1)
> > > =
> > > 
> > > https://lkml.kernel.org/r/20200828010710.5407-1-a.darw...@linutronix.de
> > > 
> > > Preemption must be disabled before entering a sequence counter write
> > > side critical section.  Otherwise the read side section can preempt the
> > > write side section and spin for the entire scheduler tick.  If that
> > > reader belongs to a real-time scheduling class, it can spin forever and
> > > the kernel will livelock.
> > > 
> > > Disabling preemption cannot be done for PREEMPT_RT though: it can lead
> > > to higher latencies, and the write side sections will not be able to
> > > acquire locks which become sleeping locks (e.g. spinlock_t).
> > > 
> > > To remain preemptible, while avoiding a possible livelock caused by the
> > > reader preempting the writer, use a different technique: let the reader
> > > detect if a seqcount_LOCKNAME_t writer is in progress. If that's the
> > > case, acquire then release the associated LOCKNAME writer serialization
> > > lock. This will allow any possibly-preempted writer to make progress
> > > until the end of its writer serialization lock critical section.
> > > 
> > > Implement this lock-unlock technique for all seqcount_LOCKNAME_t with
> > > an associated (PREEMPT_RT) sleeping lock, and for seqlock_t.
> > 
> > Reverting this patchset [1] from today's linux-next fixed a splat below. The
> > splat looks like a false positive anyway because the existing locking 
> > dependency
> > chains from the task #1 here:
> > 
> > >seqcount#2 ---> pidmap_lock
> > 
> > [  528.078061][ T7867] -> #1 (pidmap_lock){}-{2:2}:
> > [  528.078078][ T7867]lock_acquire+0x10c/0x560
> > [  528.078089][ T7867]_raw_spin_lock_irqsave+0x64/0xb0
> > [  528.078108][ T7867]free_pid+0x5c/0x160
> > free_pid at kernel/pid.c:131
> > [  528.078127][ T7867]release_task.part.40+0x59c/0x7f0
> > __unhash_process at kernel/exit.c:76
> > (inlined by) __exit_signal at kernel/exit.c:147
> > (inlined by) release_task at kernel/exit.c:198
> > [  528.078145][ T7867]do_exit+0x77c/0xda0
> > exit_notify at kernel/exit.c:679
> > (inlined by) do_exit at kernel/exit.c:826
> > [  528.078163][ T7867]kthread+0x148/0x1d0
> > [  528.078182][ T7867]ret_from_kernel_thread+0x5c/0x80
> > 
> > It is write_seqlock(>stats_lock) in __exit_signal(), but the 
> > >seqcount#2 
> > in read_mems_allowed_begin() is 
> > read_seqcount_begin(>mems_allowed_seq), 
> > so there should be no deadlock?
> > 
> 
> I think this happened because seqcount_##lockname##_init() is defined at
> function rather than macro, so when the seqcount_init() gets expand in
> that function, the lock_class_key of seqcount will be a static variable
> of seqcount_##lockname##_init() function, as a result, all
> seqcount_##lockname##_t in the same compile unit (in this case it's
> kernel/fork.c) share the same lock class key, and lockdep thought they
> are the same lock ;-)
> 

Don't know how to fix this properly, but below is an ugly attemption,
only build test, just food for thoughts.

Regards,
Boqun

--->8
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index f73c7eb68f27..938a5053def3 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -84,14 +84,18 @@ static inline void __seqcount_init(seqcount_t *s, const 
char *name,
 # define SEQCOUNT_DEP_MAP_INIT(lockname)   \
.dep_map = { .name = #lockname }
 
+# define MSIOCU 8 /* MAX SEQCOUNT IN ON COMPILE UNIT */
 /**
  * seqcount_init() - runtime initializer for seqcount_t
  * @s: Pointer to the seqcount_t instance
  */
 # define seqcount_init(s)  \
do {\
-   static struct lock_class_key __key; \
-   __seqcount_init((s), #s, &__key);   \
+   static struct lock_class_key __key[MSIOCU]; \
+   static int idx = 0; \
+   \
+   BUG_ON(idx >= MSIOCU);  \
+   

Re: [PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-15 Thread Boqun Feng
On Mon, Sep 14, 2020 at 08:20:53PM -0400, Qian Cai wrote:
> On Fri, 2020-09-04 at 17:32 +0200, Ahmed S. Darwish wrote:
> > Hi,
> > 
> > Changelog-v2
> > 
> > 
> >   - Standardize on seqcount_LOCKNAME_t as the canonical reference for
> > sequence counters with associated locks, instead of v1
> > seqcount_LOCKTYPE_t.
> > 
> >   - Use unique prefix "seqprop_*" for all seqcount_t/seqcount_LOCKNAME_t
> > property accessors.
> > 
> >   - Touch-up the lock-unlock rationale for more clarity. Enforce writer
> > non-preemitiblity using "__seq_enforce_writer_non_preemptibility()".
> > 
> > Cover letter (v1)
> > =
> > 
> > https://lkml.kernel.org/r/20200828010710.5407-1-a.darw...@linutronix.de
> > 
> > Preemption must be disabled before entering a sequence counter write
> > side critical section.  Otherwise the read side section can preempt the
> > write side section and spin for the entire scheduler tick.  If that
> > reader belongs to a real-time scheduling class, it can spin forever and
> > the kernel will livelock.
> > 
> > Disabling preemption cannot be done for PREEMPT_RT though: it can lead
> > to higher latencies, and the write side sections will not be able to
> > acquire locks which become sleeping locks (e.g. spinlock_t).
> > 
> > To remain preemptible, while avoiding a possible livelock caused by the
> > reader preempting the writer, use a different technique: let the reader
> > detect if a seqcount_LOCKNAME_t writer is in progress. If that's the
> > case, acquire then release the associated LOCKNAME writer serialization
> > lock. This will allow any possibly-preempted writer to make progress
> > until the end of its writer serialization lock critical section.
> > 
> > Implement this lock-unlock technique for all seqcount_LOCKNAME_t with
> > an associated (PREEMPT_RT) sleeping lock, and for seqlock_t.
> 
> Reverting this patchset [1] from today's linux-next fixed a splat below. The
> splat looks like a false positive anyway because the existing locking 
> dependency
> chains from the task #1 here:
> 
> >seqcount#2 ---> pidmap_lock
> 
> [  528.078061][ T7867] -> #1 (pidmap_lock){}-{2:2}:
> [  528.078078][ T7867]lock_acquire+0x10c/0x560
> [  528.078089][ T7867]_raw_spin_lock_irqsave+0x64/0xb0
> [  528.078108][ T7867]free_pid+0x5c/0x160
> free_pid at kernel/pid.c:131
> [  528.078127][ T7867]release_task.part.40+0x59c/0x7f0
> __unhash_process at kernel/exit.c:76
> (inlined by) __exit_signal at kernel/exit.c:147
> (inlined by) release_task at kernel/exit.c:198
> [  528.078145][ T7867]do_exit+0x77c/0xda0
> exit_notify at kernel/exit.c:679
> (inlined by) do_exit at kernel/exit.c:826
> [  528.078163][ T7867]kthread+0x148/0x1d0
> [  528.078182][ T7867]ret_from_kernel_thread+0x5c/0x80
> 
> It is write_seqlock(>stats_lock) in __exit_signal(), but the 
> >seqcount#2 
> in read_mems_allowed_begin() is 
> read_seqcount_begin(>mems_allowed_seq), 
> so there should be no deadlock?
> 

I think this happened because seqcount_##lockname##_init() is defined at
function rather than macro, so when the seqcount_init() gets expand in
that function, the lock_class_key of seqcount will be a static variable
of seqcount_##lockname##_init() function, as a result, all
seqcount_##lockname##_t in the same compile unit (in this case it's
kernel/fork.c) share the same lock class key, and lockdep thought they
are the same lock ;-)

Regards,
Boqun

> [1] git revert --no-edit 0c9794c8b678..1909760f5fc3
> 
> [  528.077900][ T7867] WARNING: possible circular locking dependency detected
> [  528.077912][ T7867] 5.9.0-rc5-next-20200914 #1 Not tainted
> [  528.077921][ T7867] --
> [  528.077931][ T7867] runc:[1:CHILD]/7867 is trying to acquire lock:
> [  528.077942][ T7867] c01fce5570c8 (>seqcount#2){}-{0:0}, at: 
> __slab_alloc+0x34/0xf0
> [  528.077972][ T7867] 
> [  528.077972][ T7867] but task is already holding lock:
> [  528.077983][ T7867] c56b0198 (pidmap_lock){}-{2:2}, at: 
> alloc_pid+0x258/0x590
> [  528.078009][ T7867] 
> [  528.078009][ T7867] which lock already depends on the new lock.
> [  528.078009][ T7867] 
> [  528.078031][ T7867] 
> [  528.078031][ T7867] the existing dependency chain (in reverse order) is:
> [  528.078061][ T7867] 
> [  528.078061][ T7867] -> #1 (pidmap_lock){}-{2:2}:
> [  528.078078][ T7867]lock_acquire+0x10c/0x560
> [  528.078089][ T7867]_raw_spin_lock_irqsave+0x64/0xb0
> [  528.078108][ T7867]free_pid+0x5c/0x160
> free_pid at kernel/pid.c:131
> [  528.078127][ T7867]release_task.part.40+0x59c/0x7f0
> __unhash_process at kernel/exit.c:76
> (inlined by) __exit_signal at kernel/exit.c:147
> (inlined by) release_task at kernel/exit.c:198
> [  528.078145][ T7867]do_exit+0x77c/0xda0
> exit_notify at kernel/exit.c:679
> (inlined by) do_exit at kernel/exit.c:826
> [  528.078163][ T7867]

Re: [PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-14 Thread Qian Cai
On Fri, 2020-09-04 at 17:32 +0200, Ahmed S. Darwish wrote:
> Hi,
> 
> Changelog-v2
> 
> 
>   - Standardize on seqcount_LOCKNAME_t as the canonical reference for
> sequence counters with associated locks, instead of v1
> seqcount_LOCKTYPE_t.
> 
>   - Use unique prefix "seqprop_*" for all seqcount_t/seqcount_LOCKNAME_t
> property accessors.
> 
>   - Touch-up the lock-unlock rationale for more clarity. Enforce writer
> non-preemitiblity using "__seq_enforce_writer_non_preemptibility()".
> 
> Cover letter (v1)
> =
> 
> https://lkml.kernel.org/r/20200828010710.5407-1-a.darw...@linutronix.de
> 
> Preemption must be disabled before entering a sequence counter write
> side critical section.  Otherwise the read side section can preempt the
> write side section and spin for the entire scheduler tick.  If that
> reader belongs to a real-time scheduling class, it can spin forever and
> the kernel will livelock.
> 
> Disabling preemption cannot be done for PREEMPT_RT though: it can lead
> to higher latencies, and the write side sections will not be able to
> acquire locks which become sleeping locks (e.g. spinlock_t).
> 
> To remain preemptible, while avoiding a possible livelock caused by the
> reader preempting the writer, use a different technique: let the reader
> detect if a seqcount_LOCKNAME_t writer is in progress. If that's the
> case, acquire then release the associated LOCKNAME writer serialization
> lock. This will allow any possibly-preempted writer to make progress
> until the end of its writer serialization lock critical section.
> 
> Implement this lock-unlock technique for all seqcount_LOCKNAME_t with
> an associated (PREEMPT_RT) sleeping lock, and for seqlock_t.

Reverting this patchset [1] from today's linux-next fixed a splat below. The
splat looks like a false positive anyway because the existing locking dependency
chains from the task #1 here:

>seqcount#2 ---> pidmap_lock

[  528.078061][ T7867] -> #1 (pidmap_lock){}-{2:2}:
[  528.078078][ T7867]lock_acquire+0x10c/0x560
[  528.078089][ T7867]_raw_spin_lock_irqsave+0x64/0xb0
[  528.078108][ T7867]free_pid+0x5c/0x160
free_pid at kernel/pid.c:131
[  528.078127][ T7867]release_task.part.40+0x59c/0x7f0
__unhash_process at kernel/exit.c:76
(inlined by) __exit_signal at kernel/exit.c:147
(inlined by) release_task at kernel/exit.c:198
[  528.078145][ T7867]do_exit+0x77c/0xda0
exit_notify at kernel/exit.c:679
(inlined by) do_exit at kernel/exit.c:826
[  528.078163][ T7867]kthread+0x148/0x1d0
[  528.078182][ T7867]ret_from_kernel_thread+0x5c/0x80

It is write_seqlock(>stats_lock) in __exit_signal(), but the 
>seqcount#2 
in read_mems_allowed_begin() is 
read_seqcount_begin(>mems_allowed_seq), 
so there should be no deadlock?

[1] git revert --no-edit 0c9794c8b678..1909760f5fc3

[  528.077900][ T7867] WARNING: possible circular locking dependency detected
[  528.077912][ T7867] 5.9.0-rc5-next-20200914 #1 Not tainted
[  528.077921][ T7867] --
[  528.077931][ T7867] runc:[1:CHILD]/7867 is trying to acquire lock:
[  528.077942][ T7867] c01fce5570c8 (>seqcount#2){}-{0:0}, at: 
__slab_alloc+0x34/0xf0
[  528.077972][ T7867] 
[  528.077972][ T7867] but task is already holding lock:
[  528.077983][ T7867] c56b0198 (pidmap_lock){}-{2:2}, at: 
alloc_pid+0x258/0x590
[  528.078009][ T7867] 
[  528.078009][ T7867] which lock already depends on the new lock.
[  528.078009][ T7867] 
[  528.078031][ T7867] 
[  528.078031][ T7867] the existing dependency chain (in reverse order) is:
[  528.078061][ T7867] 
[  528.078061][ T7867] -> #1 (pidmap_lock){}-{2:2}:
[  528.078078][ T7867]lock_acquire+0x10c/0x560
[  528.078089][ T7867]_raw_spin_lock_irqsave+0x64/0xb0
[  528.078108][ T7867]free_pid+0x5c/0x160
free_pid at kernel/pid.c:131
[  528.078127][ T7867]release_task.part.40+0x59c/0x7f0
__unhash_process at kernel/exit.c:76
(inlined by) __exit_signal at kernel/exit.c:147
(inlined by) release_task at kernel/exit.c:198
[  528.078145][ T7867]do_exit+0x77c/0xda0
exit_notify at kernel/exit.c:679
(inlined by) do_exit at kernel/exit.c:826
[  528.078163][ T7867]kthread+0x148/0x1d0
[  528.078182][ T7867]ret_from_kernel_thread+0x5c/0x80
[  528.078208][ T7867] 
[  528.078208][ T7867] -> #0 (>seqcount#2){}-{0:0}:
[  528.078241][ T7867]check_prevs_add+0x1c4/0x1120
check_prev_add at kernel/locking/lockdep.c:2820
(inlined by) check_prevs_add at kernel/locking/lockdep.c:2944
[  528.078260][ T7867]__lock_acquire+0x176c/0x1c00
validate_chain at kernel/locking/lockdep.c:3562
(inlined by) __lock_acquire at kernel/locking/lockdep.c:4796
[  528.078278][ T7867]lock_acquire+0x10c/0x560
[  528.078297][ T7867]___slab_alloc+0xa40/0xb40
seqcount_lockdep_reader_access at include/linux/seqlock.h:103
(inlined by) read_mems_allowed_begin at 

[PATCH v2 0/5] seqlock: Introduce PREEMPT_RT support

2020-09-04 Thread Ahmed S. Darwish
Hi,

Changelog-v2


  - Standardize on seqcount_LOCKNAME_t as the canonical reference for
sequence counters with associated locks, instead of v1
seqcount_LOCKTYPE_t.

  - Use unique prefix "seqprop_*" for all seqcount_t/seqcount_LOCKNAME_t
property accessors.

  - Touch-up the lock-unlock rationale for more clarity. Enforce writer
non-preemitiblity using "__seq_enforce_writer_non_preemptibility()".

Cover letter (v1)
=

https://lkml.kernel.org/r/20200828010710.5407-1-a.darw...@linutronix.de

Preemption must be disabled before entering a sequence counter write
side critical section.  Otherwise the read side section can preempt the
write side section and spin for the entire scheduler tick.  If that
reader belongs to a real-time scheduling class, it can spin forever and
the kernel will livelock.

Disabling preemption cannot be done for PREEMPT_RT though: it can lead
to higher latencies, and the write side sections will not be able to
acquire locks which become sleeping locks (e.g. spinlock_t).

To remain preemptible, while avoiding a possible livelock caused by the
reader preempting the writer, use a different technique: let the reader
detect if a seqcount_LOCKNAME_t writer is in progress. If that's the
case, acquire then release the associated LOCKNAME writer serialization
lock. This will allow any possibly-preempted writer to make progress
until the end of its writer serialization lock critical section.

Implement this lock-unlock technique for all seqcount_LOCKNAME_t with
an associated (PREEMPT_RT) sleeping lock, and for seqlock_t.

8<--

Ahmed S. Darwish (5):
  seqlock: seqcount_LOCKNAME_t: Standardize naming convention
  seqlock: Use unique prefix for seqcount_t property accessors
  seqlock: seqcount_t: Implement all read APIs as statement expressions
  seqlock: seqcount_LOCKNAME_t: Introduce PREEMPT_RT support
  seqlock: PREEMPT_RT: Do not starve seqlock_t writers

 include/linux/seqlock.h | 281 
 1 file changed, 167 insertions(+), 114 deletions(-)

base-commit: f75aef392f869018f78cfedf3c320a6b3fcfda6b
--
2.28.0