workqueue/lockdep: 'Fix' flush_work() annotation
authorPeter Zijlstra <[email protected]>
Wed, 23 Aug 2017 10:52:32 +0000 (12:52 +0200)
committerIngo Molnar <[email protected]>
Fri, 25 Aug 2017 09:06:32 +0000 (11:06 +0200)
commita1d14934ea4b9db816a8dbfeab1c3e7204a0d871
treef2d6a33fdf8eed83fbe4e2d04c7989700aab2138
parente91498589746065e3ae95d9a00b068e525eec34f
workqueue/lockdep: 'Fix' flush_work() annotation

The flush_work() annotation as introduced by commit:

  e159489baa71 ("workqueue: relax lockdep annotation on flush_work()")

hits on the lockdep problem with recursive read locks.

The situation as described is:

Work W1:                Work W2:        Task:

ARR(Q)                  ARR(Q) flush_workqueue(Q)
A(W1)                   A(W2)             A(Q)
  flush_work(W2)   R(Q)
    A(W2)
    R(W2)
    if (special)
      A(Q)
    else
      ARR(Q)
    R(Q)

where: A - acquire, ARR - acquire-read-recursive, R - release.

Where under 'special' conditions we want to trigger a lock recursion
deadlock, but otherwise allow the flush_work(). The allowing is done
by using recursive read locks (ARR), but lockdep is broken for
recursive stuff.

However, there appears to be no need to acquire the lock if we're not
'special', so if we remove the 'else' clause things become much
simpler and no longer need the recursion thing at all.

Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Acked-by: Tejun Heo <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Ingo Molnar <[email protected]>
kernel/workqueue.c