All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: Johannes Berg <johannes@sipsolutions.net>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>,
	linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org,
	Johannes Berg <johannes.berg@intel.com>
Subject: Re: [PATCH 1/2] workqueue: skip lockdep wq dependency in cancel_work_sync()
Date: Tue, 21 Aug 2018 09:08:14 -0700	[thread overview]
Message-ID: <20180821160814.GP3978217@devbig004.ftw2.facebook.com> (raw)
In-Reply-To: <20180821120317.4115-2-johannes@sipsolutions.net>

On Tue, Aug 21, 2018 at 02:03:16PM +0200, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> In cancel_work_sync(), we can only have one of two cases, even
> with an ordered workqueue:
>  * the work isn't running, just cancelled before it started
>  * the work is running, but then nothing else can be on the
>    workqueue before it
> 
> Thus, we need to skip the lockdep workqueue dependency handling,
> otherwise we get false positive reports from lockdep saying that
> we have a potential deadlock when the workqueue also has other
> work items with locking, e.g.
> 
>   work1_function() { mutex_lock(&mutex); ... }
>   work2_function() { /* nothing */ }
> 
>   other_function() {
>     queue_work(ordered_wq, &work1);
>     queue_work(ordered_wq, &work2);
>     mutex_lock(&mutex);
>     cancel_work_sync(&work2);
>   }
> 
> As described above, this isn't a problem, but lockdep will
> currently flag it as if cancel_work_sync() was flush_work(),
> which *is* a problem.
> 
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
>  kernel/workqueue.c | 37 ++++++++++++++++++++++---------------
>  1 file changed, 22 insertions(+), 15 deletions(-)
> 
> diff --git a/kernel/workqueue.c b/kernel/workqueue.c
> index 78b192071ef7..a6c2b823f348 100644
> --- a/kernel/workqueue.c
> +++ b/kernel/workqueue.c
> @@ -2843,7 +2843,8 @@ void drain_workqueue(struct workqueue_struct *wq)
>  }
>  EXPORT_SYMBOL_GPL(drain_workqueue);
>  
> -static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
> +static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr,
> +			     bool from_cancel)
>  {
>  	struct worker *worker = NULL;
>  	struct worker_pool *pool;
> @@ -2885,7 +2886,8 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
>  	 * workqueues the deadlock happens when the rescuer stalls, blocking
>  	 * forward progress.
>  	 */
> -	if (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer) {
> +	if (!from_cancel &&
> +	    (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer)) {
>  		lock_map_acquire(&pwq->wq->lockdep_map);
>  		lock_map_release(&pwq->wq->lockdep_map);
>  	}

But this can lead to a deadlock.  I'd much rather err on the side of
discouraging complex lock dancing around ordered workqueues, no?

Thanks.

-- 
tejun

  reply	other threads:[~2018-08-21 19:29 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-21 12:03 [PATCH 0/2] workqueue lockdep limitations/bugs Johannes Berg
2018-08-21 12:03 ` [PATCH 1/2] workqueue: skip lockdep wq dependency in cancel_work_sync() Johannes Berg
2018-08-21 16:08   ` Tejun Heo [this message]
2018-08-21 17:18     ` Johannes Berg
2018-08-21 17:27       ` Tejun Heo
2018-08-21 17:30         ` Johannes Berg
2018-08-21 17:55           ` Tejun Heo
2018-08-21 19:20             ` Johannes Berg
2018-08-22  2:45               ` Byungchul Park
2018-08-22  4:02                 ` Johannes Berg
2018-08-22  5:47                   ` Byungchul Park
2018-08-22  7:07                     ` Johannes Berg
2018-08-22  7:50                       ` Byungchul Park
2018-08-22  8:02                         ` Johannes Berg
2018-08-22  9:15                           ` Byungchul Park
2018-08-22  9:42                             ` Johannes Berg
2018-08-22 12:47                               ` Byungchul Park
2018-08-21 12:03 ` [PATCH 2/2] workqueue: create lockdep dependency in flush_work() Johannes Berg
2018-08-21 16:09   ` Tejun Heo
2018-08-21 17:19     ` Johannes Berg
2018-08-21 16:00 ` [PATCH 0/2] workqueue lockdep limitations/bugs Tejun Heo
2018-08-21 17:15   ` Johannes Berg

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=20180821160814.GP3978217@devbig004.ftw2.facebook.com \
    --to=tj@kernel.org \
    --cc=jiangshanlai@gmail.com \
    --cc=johannes.berg@intel.com \
    --cc=johannes@sipsolutions.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.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.