All of lore.kernel.org
 help / color / mirror / Atom feed
From: Byungchul Park <byungchul.park@lge.com>
To: Boqun Feng <boqun.feng@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	peterz@infradead.org, walken@google.com, kirill@shutemov.name,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	akpm@linux-foundation.org, willy@infradead.org,
	npiggin@gmail.com, kernel-team@lge.com
Subject: Re: [PATCH v8 00/14] lockdep: Implement crossrelease feature
Date: Wed, 16 Aug 2017 13:37:46 +0900	[thread overview]
Message-ID: <20170816043746.GQ20323@X58A-UD3R> (raw)
In-Reply-To: <20170816035842.p33z5st3rr2gwssh@tardis>

On Wed, Aug 16, 2017 at 12:05:31PM +0800, Boqun Feng wrote:
> On Wed, Aug 16, 2017 at 09:16:37AM +0900, Byungchul Park wrote:
> > On Tue, Aug 15, 2017 at 10:20:20AM +0200, Ingo Molnar wrote:
> > > 
> > > So with the latest fixes there's a new lockdep warning on one of my testboxes:
> > > 
> > > [   11.322487] EXT4-fs (sda2): mounted filesystem with ordered data mode. Opts: (null)
> > > 
> > > [   11.495661] ======================================================
> > > [   11.502093] WARNING: possible circular locking dependency detected
> > > [   11.508507] 4.13.0-rc5-00497-g73135c58-dirty #1 Not tainted
> > > [   11.514313] ------------------------------------------------------
> > > [   11.520725] umount/533 is trying to acquire lock:
> > > [   11.525657]  ((complete)&barr->done){+.+.}, at: [<ffffffff810fdbb3>] flush_work+0x213/0x2f0
> > > [   11.534411] 
> > >                but task is already holding lock:
> > > [   11.540661]  (lock#3){+.+.}, at: [<ffffffff8122678d>] lru_add_drain_all_cpuslocked+0x3d/0x190
> > > [   11.549613] 
> > >                which lock already depends on the new lock.
> > > 
> > > The full splat is below. The kernel config is nothing fancy - distro derived, 
> > > pretty close to defconfig, with lockdep enabled.
> > 
> > I see...
> > 
> > Worker A : acquired of wfc.work -> wait for cpu_hotplug_lock to be released
> > Task   B : acquired of cpu_hotplug_lock -> wait for lock#3 to be released
> > Task   C : acquired of lock#3 -> wait for completion of barr->done
> 
> >From the stack trace below, this barr->done is for flush_work() in
> lru_add_drain_all_cpuslocked(), i.e. for work "per_cpu(lru_add_drain_work)"
> 
> > Worker D : wait for wfc.work to be released -> will complete barr->done
> 
> and this barr->done is for work "wfc.work".

I think it can be the same instance. wait_for_completion() in flush_work()
e.g. at task C in my example, waits for completion which we expect to be
done by a worker e.g. worker D in my example.

I think the problem is caused by a write-acquisition of wfc.work in
process_one_work(). The acquisition of wfc.work should be reenterable,
that is, read-acquisition, shouldn't it?

I might be wrong... Please fix me if so.

Thank you,
Byungchul

> So those two barr->done could not be the same instance, IIUC. Therefore
> the deadlock case is not possible.
> 
> The problem here is all barr->done instances are initialized at
> insert_wq_barrier() and they belongs to the same lock class, to fix
> this, we need to differ barr->done with different lock classes based on
> the corresponding works.
> 
> How about the this(only compilation test):
> 
> ----------------->8
> diff --git a/kernel/workqueue.c b/kernel/workqueue.c
> index e86733a8b344..d14067942088 100644
> --- a/kernel/workqueue.c
> +++ b/kernel/workqueue.c
> @@ -2431,6 +2431,27 @@ struct wq_barrier {
>  	struct task_struct	*task;	/* purely informational */
>  };
>  
> +#ifdef CONFIG_LOCKDEP_COMPLETE
> +# define INIT_WQ_BARRIER_ONSTACK(barr, func, target)				\
> +do {										\
> +	INIT_WORK_ONSTACK(&(barr)->work, func);					\
> +	__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&(barr)->work));	\
> +	lockdep_init_map_crosslock((struct lockdep_map *)&(barr)->done.map,	\
> +				   "(complete)" #barr,				\
> +				   (target)->lockdep_map.key, 1); 		\
> +	__init_completion(&barr->done);						\
> +	barr->task = current;							\
> +} while (0)
> +#else
> +# define INIT_WQ_BARRIER_ONSTACK(barr, func, target)				\
> +do {										\
> +	INIT_WORK_ONSTACK(&(barr)->work, func);					\
> +	__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&(barr)->work));	\
> +	init_completion(&barr->done);						\
> +	barr->task = current;							\
> +} while (0)
> +#endif
> +
>  static void wq_barrier_func(struct work_struct *work)
>  {
>  	struct wq_barrier *barr = container_of(work, struct wq_barrier, work);
> @@ -2474,10 +2495,7 @@ static void insert_wq_barrier(struct pool_workqueue *pwq,
>  	 * checks and call back into the fixup functions where we
>  	 * might deadlock.
>  	 */
> -	INIT_WORK_ONSTACK(&barr->work, wq_barrier_func);
> -	__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&barr->work));
> -	init_completion(&barr->done);
> -	barr->task = current;
> +	INIT_WQ_BARRIER_ONSTACK(barr, wq_barrier_func, target);
>  
>  	/*
>  	 * If @target is currently being executed, schedule the

WARNING: multiple messages have this Message-ID (diff)
From: Byungchul Park <byungchul.park@lge.com>
To: Boqun Feng <boqun.feng@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	peterz@infradead.org, walken@google.com, kirill@shutemov.name,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	akpm@linux-foundation.org, willy@infradead.org,
	npiggin@gmail.com, kernel-team@lge.com
Subject: Re: [PATCH v8 00/14] lockdep: Implement crossrelease feature
Date: Wed, 16 Aug 2017 13:37:46 +0900	[thread overview]
Message-ID: <20170816043746.GQ20323@X58A-UD3R> (raw)
In-Reply-To: <20170816035842.p33z5st3rr2gwssh@tardis>

On Wed, Aug 16, 2017 at 12:05:31PM +0800, Boqun Feng wrote:
> On Wed, Aug 16, 2017 at 09:16:37AM +0900, Byungchul Park wrote:
> > On Tue, Aug 15, 2017 at 10:20:20AM +0200, Ingo Molnar wrote:
> > > 
> > > So with the latest fixes there's a new lockdep warning on one of my testboxes:
> > > 
> > > [   11.322487] EXT4-fs (sda2): mounted filesystem with ordered data mode. Opts: (null)
> > > 
> > > [   11.495661] ======================================================
> > > [   11.502093] WARNING: possible circular locking dependency detected
> > > [   11.508507] 4.13.0-rc5-00497-g73135c58-dirty #1 Not tainted
> > > [   11.514313] ------------------------------------------------------
> > > [   11.520725] umount/533 is trying to acquire lock:
> > > [   11.525657]  ((complete)&barr->done){+.+.}, at: [<ffffffff810fdbb3>] flush_work+0x213/0x2f0
> > > [   11.534411] 
> > >                but task is already holding lock:
> > > [   11.540661]  (lock#3){+.+.}, at: [<ffffffff8122678d>] lru_add_drain_all_cpuslocked+0x3d/0x190
> > > [   11.549613] 
> > >                which lock already depends on the new lock.
> > > 
> > > The full splat is below. The kernel config is nothing fancy - distro derived, 
> > > pretty close to defconfig, with lockdep enabled.
> > 
> > I see...
> > 
> > Worker A : acquired of wfc.work -> wait for cpu_hotplug_lock to be released
> > Task   B : acquired of cpu_hotplug_lock -> wait for lock#3 to be released
> > Task   C : acquired of lock#3 -> wait for completion of barr->done
> 
> >From the stack trace below, this barr->done is for flush_work() in
> lru_add_drain_all_cpuslocked(), i.e. for work "per_cpu(lru_add_drain_work)"
> 
> > Worker D : wait for wfc.work to be released -> will complete barr->done
> 
> and this barr->done is for work "wfc.work".

I think it can be the same instance. wait_for_completion() in flush_work()
e.g. at task C in my example, waits for completion which we expect to be
done by a worker e.g. worker D in my example.

I think the problem is caused by a write-acquisition of wfc.work in
process_one_work(). The acquisition of wfc.work should be reenterable,
that is, read-acquisition, shouldn't it?

I might be wrong... Please fix me if so.

Thank you,
Byungchul

> So those two barr->done could not be the same instance, IIUC. Therefore
> the deadlock case is not possible.
> 
> The problem here is all barr->done instances are initialized at
> insert_wq_barrier() and they belongs to the same lock class, to fix
> this, we need to differ barr->done with different lock classes based on
> the corresponding works.
> 
> How about the this(only compilation test):
> 
> ----------------->8
> diff --git a/kernel/workqueue.c b/kernel/workqueue.c
> index e86733a8b344..d14067942088 100644
> --- a/kernel/workqueue.c
> +++ b/kernel/workqueue.c
> @@ -2431,6 +2431,27 @@ struct wq_barrier {
>  	struct task_struct	*task;	/* purely informational */
>  };
>  
> +#ifdef CONFIG_LOCKDEP_COMPLETE
> +# define INIT_WQ_BARRIER_ONSTACK(barr, func, target)				\
> +do {										\
> +	INIT_WORK_ONSTACK(&(barr)->work, func);					\
> +	__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&(barr)->work));	\
> +	lockdep_init_map_crosslock((struct lockdep_map *)&(barr)->done.map,	\
> +				   "(complete)" #barr,				\
> +				   (target)->lockdep_map.key, 1); 		\
> +	__init_completion(&barr->done);						\
> +	barr->task = current;							\
> +} while (0)
> +#else
> +# define INIT_WQ_BARRIER_ONSTACK(barr, func, target)				\
> +do {										\
> +	INIT_WORK_ONSTACK(&(barr)->work, func);					\
> +	__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&(barr)->work));	\
> +	init_completion(&barr->done);						\
> +	barr->task = current;							\
> +} while (0)
> +#endif
> +
>  static void wq_barrier_func(struct work_struct *work)
>  {
>  	struct wq_barrier *barr = container_of(work, struct wq_barrier, work);
> @@ -2474,10 +2495,7 @@ static void insert_wq_barrier(struct pool_workqueue *pwq,
>  	 * checks and call back into the fixup functions where we
>  	 * might deadlock.
>  	 */
> -	INIT_WORK_ONSTACK(&barr->work, wq_barrier_func);
> -	__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&barr->work));
> -	init_completion(&barr->done);
> -	barr->task = current;
> +	INIT_WQ_BARRIER_ONSTACK(barr, wq_barrier_func, target);
>  
>  	/*
>  	 * If @target is currently being executed, schedule the

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2017-08-16  4:39 UTC|newest]

Thread overview: 152+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-07  7:12 [PATCH v8 00/14] lockdep: Implement crossrelease feature Byungchul Park
2017-08-07  7:12 ` Byungchul Park
2017-08-07  7:12 ` [PATCH v8 01/14] lockdep: Refactor lookup_chain_cache() Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-10 12:18   ` [tip:locking/core] locking/lockdep: " tip-bot for Byungchul Park
2017-08-07  7:12 ` [PATCH v8 02/14] lockdep: Add a function building a chain between two classes Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-10 12:18   ` [tip:locking/core] locking/lockdep: " tip-bot for Byungchul Park
2017-08-07  7:12 ` [PATCH v8 03/14] lockdep: Change the meaning of check_prev_add()'s return value Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-10 12:19   ` [tip:locking/core] locking/lockdep: " tip-bot for Byungchul Park
2017-08-07  7:12 ` [PATCH v8 04/14] lockdep: Make check_prev_add() able to handle external stack_trace Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-10 12:19   ` [tip:locking/core] locking/lockdep: " tip-bot for Byungchul Park
2017-08-07  7:12 ` [PATCH v8 05/14] lockdep: Implement crossrelease feature Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-09 14:05   ` Peter Zijlstra
2017-08-09 14:05     ` Peter Zijlstra
2017-08-10  1:30     ` Byungchul Park
2017-08-10  1:30       ` Byungchul Park
2017-08-10  9:21       ` Peter Zijlstra
2017-08-10  9:21         ` Peter Zijlstra
2017-08-10 12:19   ` [tip:locking/core] locking/lockdep: Implement the 'crossrelease' feature tip-bot for Byungchul Park
2017-08-07  7:12 ` [PATCH v8 06/14] lockdep: Detect and handle hist_lock ring buffer overwrite Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-09 14:16   ` Peter Zijlstra
2017-08-09 14:16     ` Peter Zijlstra
2017-08-10  1:32     ` Byungchul Park
2017-08-10  1:32       ` Byungchul Park
2017-08-10  9:22       ` Peter Zijlstra
2017-08-10  9:22         ` Peter Zijlstra
2017-08-10 10:32     ` Byungchul Park
2017-08-10 10:32       ` Byungchul Park
2017-08-10 11:59   ` Boqun Feng
2017-08-10 12:11     ` Byungchul Park
2017-08-10 12:11       ` Byungchul Park
2017-08-10 12:51       ` Boqun Feng
2017-08-10 13:17         ` Boqun Feng
2017-08-10 13:17           ` Boqun Feng
2017-08-11  0:44           ` Byungchul Park
2017-08-11  0:44             ` Byungchul Park
2017-08-11  3:43           ` Byungchul Park
2017-08-11  3:43             ` Byungchul Park
2017-08-11  8:03             ` Boqun Feng
2017-08-11  8:52               ` Byungchul Park
2017-08-11  8:52                 ` Byungchul Park
2017-08-11  9:44                 ` Byungchul Park
2017-08-11  9:44                   ` Byungchul Park
2017-08-11 13:06                   ` Byungchul Park
2017-08-11 13:06                     ` Byungchul Park
2017-08-14  7:05                     ` Boqun Feng
2017-08-14  7:22                       ` Byungchul Park
2017-08-14  7:22                         ` Byungchul Park
2017-08-14  7:29                       ` Byungchul Park
2017-08-14  7:29                         ` Byungchul Park
2017-08-11  0:40         ` Byungchul Park
2017-08-11  0:40           ` Byungchul Park
2017-08-11  1:03           ` Boqun Feng
2017-08-10 12:20   ` [tip:locking/core] locking/lockdep: " tip-bot for Byungchul Park
2017-08-07  7:12 ` [PATCH v8 07/14] lockdep: Handle non(or multi)-acquisition of a crosslock Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-10 12:20   ` [tip:locking/core] locking/lockdep: " tip-bot for Byungchul Park
2017-08-07  7:12 ` [PATCH v8 08/14] lockdep: Make print_circular_bug() aware of crossrelease Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-10 12:21   ` [tip:locking/core] locking/lockdep: " tip-bot for Byungchul Park
2017-08-07  7:12 ` [PATCH v8 09/14] lockdep: Apply crossrelease to completions Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-07 10:20   ` kbuild test robot
2017-08-07 11:45   ` kbuild test robot
2017-08-09  9:51   ` Peter Zijlstra
2017-08-09  9:51     ` Peter Zijlstra
2017-08-09 10:24     ` Peter Zijlstra
2017-08-09 10:24       ` Peter Zijlstra
2017-08-10  1:24       ` Byungchul Park
2017-08-10  1:24         ` Byungchul Park
2017-08-10 12:21   ` [tip:locking/core] locking/lockdep: " tip-bot for Byungchul Park
2017-08-14  8:50   ` [PATCH v8 09/14] lockdep: " Arnd Bergmann
2017-08-14  8:50     ` Arnd Bergmann
2017-08-18 23:43     ` Boqun Feng
2017-08-18 23:43       ` Boqun Feng
2017-08-19 12:51       ` Arnd Bergmann
2017-08-19 12:51         ` Arnd Bergmann
2017-08-19 13:34         ` Arnd Bergmann
2017-08-19 13:34           ` Arnd Bergmann
2017-08-23 14:43           ` Boqun Feng
2017-08-20  3:18         ` Boqun Feng
2017-08-07  7:12 ` [PATCH v8 10/14] pagemap.h: Remove trailing white space Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-07  7:12 ` [PATCH v8 11/14] lockdep: Apply crossrelease to PG_locked locks Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-07 10:36   ` kbuild test robot
2017-08-10  1:35   ` Byungchul Park
2017-08-10  1:35     ` Byungchul Park
2017-08-10  9:25     ` Peter Zijlstra
2017-08-10  9:25       ` Peter Zijlstra
2017-09-05  1:03   ` Byungchul Park
2017-09-05  1:03     ` Byungchul Park
2017-08-07  7:12 ` [PATCH v8 12/14] lockdep: Apply lock_acquire(release) on __Set(__Clear)PageLocked Byungchul Park
2017-08-07  7:12   ` Byungchul Park
2017-08-07  7:13 ` [PATCH v8 13/14] lockdep: Move data of CONFIG_LOCKDEP_PAGELOCK from page to page_ext Byungchul Park
2017-08-07  7:13   ` Byungchul Park
2017-08-07 10:43   ` kbuild test robot
2017-08-07  7:13 ` [PATCH v8 14/14] lockdep: Crossrelease feature documentation Byungchul Park
2017-08-07  7:13   ` Byungchul Park
2017-08-07 15:58   ` kbuild test robot
2017-08-10 12:22   ` [tip:locking/core] locking/lockdep: Add 'crossrelease' " tip-bot for Byungchul Park
2017-08-09 15:50 ` [PATCH v8 00/14] lockdep: Implement crossrelease feature Peter Zijlstra
2017-08-09 15:50   ` Peter Zijlstra
2017-08-10  0:55   ` Byungchul Park
2017-08-10  0:55     ` Byungchul Park
2017-08-10  3:47     ` Byungchul Park
2017-08-10  3:47       ` Byungchul Park
2017-08-10 10:52     ` Byungchul Park
2017-08-10 10:52       ` Byungchul Park
2017-08-10  9:37   ` Byungchul Park
2017-08-10  9:37     ` Byungchul Park
2017-08-10 10:52     ` Peter Zijlstra
2017-08-10 10:52       ` Peter Zijlstra
2017-08-10 11:10 ` Ingo Molnar
2017-08-10 11:10   ` Ingo Molnar
2017-08-10 11:45   ` Byungchul Park
2017-08-10 11:45     ` Byungchul Park
2017-08-14 10:57     ` Ingo Molnar
2017-08-14 10:57       ` Ingo Molnar
2017-08-14 11:10       ` Byungchul Park
2017-08-14 11:10         ` Byungchul Park
2017-08-15  8:20 ` Ingo Molnar
2017-08-15  8:20   ` Ingo Molnar
2017-08-16  0:16   ` Byungchul Park
2017-08-16  0:16     ` Byungchul Park
2017-08-16  4:05     ` Boqun Feng
2017-08-16  4:05       ` Boqun Feng
2017-08-16  4:37       ` Byungchul Park [this message]
2017-08-16  4:37         ` Byungchul Park
2017-08-16  5:40         ` Boqun Feng
2017-08-16  6:37           ` Byungchul Park
2017-08-16  6:37             ` Byungchul Park
2017-08-16  5:05       ` Byungchul Park
2017-08-16  5:05         ` Byungchul Park
2017-08-16  5:58         ` Boqun Feng
2017-08-16  7:14           ` Byungchul Park
2017-08-16  7:14             ` Byungchul Park
2017-08-16  8:06             ` Byungchul Park
2017-08-16  8:06               ` Byungchul Park
2017-08-16  9:38               ` Byungchul Park
2017-08-16  9:38                 ` Byungchul Park
2017-08-17  7:48       ` Ingo Molnar
2017-08-17  7:48         ` Ingo Molnar
2017-08-17  8:04         ` Boqun Feng
2017-08-17  8:12           ` Ingo Molnar
2017-08-17  8:12             ` Ingo Molnar
2017-08-17  8:33             ` Boqun Feng

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=20170816043746.GQ20323@X58A-UD3R \
    --to=byungchul.park@lge.com \
    --cc=akpm@linux-foundation.org \
    --cc=boqun.feng@gmail.com \
    --cc=kernel-team@lge.com \
    --cc=kirill@shutemov.name \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mingo@kernel.org \
    --cc=npiggin@gmail.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=walken@google.com \
    --cc=willy@infradead.org \
    /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.