All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Byungchul Park <byungchul.park@lge.com>
Cc: mingo@kernel.org, linux-kernel@vger.kernel.org, walken@google.com
Subject: Re: [PATCH] lockdep: Add a document describing crossrelease feature
Date: Fri, 1 Jul 2016 12:45:21 +0200	[thread overview]
Message-ID: <20160701104521.GG30154@twins.programming.kicks-ass.net> (raw)
In-Reply-To: <1467346538-1579-1-git-send-email-byungchul.park@lge.com>


So I really could not understand your initial changelogs, this text
seem to be somewhat better, so let me try and comment on this.

On Fri, Jul 01, 2016 at 01:15:38PM +0900, Byungchul Park wrote:

> +++ b/Documentation/locking/crossrelease.txt
> @@ -0,0 +1,276 @@
> +Crossrelease lock dependency check
> +==================================
> +
> +Started by Byungchul Park <byungchul.park@lge.com>
> +
> +Contents:
> +
> + (*) What is a problem?
> +
> +     - Original lockdep's assumptions.
> +     - Original lockdep's limitation.

Their form doesn't make sense if we ever commit this. Nobody knows or
cares about an 'original' lockdep. There is only now.

> +Original lockdep's assumptions
> +------------------------------
> +
> +Original lockdep (not crossrelease featured lockdep) assumes that,
> +
> +1. A lock will be unlocked within the context holding the lock.

This is lock owner semantics; that is, each lock has a clear owner.
Which is a sane assumption, and a hard requirement for PI. Remember, all
this comes from the RT tree.

!owner locks cannot do PI and thus cannot be used for code you want to
provide deterministic behaviour with.

> +2. A lock has dependency with all locks already held in held_locks.

That's not really an assumption, given 1, this is a fact. An owner lock
can only depend on locks currently held. This is a corner stone of
proving things.

> +2. Acquiring is more important than releasing, to check its dependency.

s/2/3/

That's not an assumption; that's a hard requirement. Since the acquire
is the one blocking, you _have_ to check for cycles before you block,
otherwise you'll hit the deadlock and not get a report, because you're
deadlocked.

> +Original lockdep's limitation
> +-----------------------------
> +
> +Therefore, the original lockdep has limitations. It can be applied only
> +to typical lock operations, e.g. spin_lock, mutex, semaphore and the

This is wrong, semaphores are very much not covered by lockdep since
they do not have owner semantics (what you call crossmuck). (this is
the distinction between a binary semaphore and a mutex)

> +What causes deadlock
> +--------------------
> +
> +Not only lock operations, but also any operations causing to wait or
> +spin it e.g. all wait operations for an event, lock_page() and so on
> +can cause deadlock unless it's eventually released by someone. The most
> +important point here is that the waiting or spinning must be *released*
> +by someone. In other words, we have to focus whether the waiting and
> +spinning can be *released* or not to avoid deadlock, rather than
> +waiting or spinning it itself.

But since its the blocking that _is_ the deadlock, you'll never get your
report.

IOW, you rely on future behaviour to tell if now can make forwards
progress. This already implies a well formed program. You're inverting
causality.

> +Relax the assumptions
> +---------------------
> +
> +We can relax the assumtions the original lockdep has, which is not
> +necessary to check dependency and detect a deadlock.
> +
> +1. A lock can be unlocked in any context, unless the context itself
> +   causes a deadlock e.g. acquiring a lock in irq-safe context before
> +   releasing the lock in irq-unsafe context.

You fail to say how this preserves correctness. By relaxing this you
loose the held_lock dependencies and you destroy the entire proof that
currently underpins lockdep.

> +2. A lock has dependency with all locks in the releasing context, having
> +   been held since the lock was held.

But you cannot tell this. The 'since the lock was held' thing fully
depends on timing and is not fundamentally correct.

			lock(A)
			unlock(A)
	lock(A)
	wait_for(B)
	unlock(A)
			wake(B)

Between the wait_for(B) and wake(B), _nothing_ has been held, yet still
there's the deadlock potential.

And note that if the timing was 'right', you would never get to wake(B)
because deadlock, so you'd never establish that there would be a
deadlock.

>                                        Thus we can check the dependency
> +   only after we identify the releasing context at first. Of course,
> +   if we consider only typical lock e.g. spin lock, mutex, semaphore
> +   and so on, then we can identify the releasing context at the time
> +   acquiring a lock because the releasing context is same as the
> +   releasing context for the typical lock. However, generally we have to
> +   wait until the lock having been held will be eventually released to
> +   identify the releasing context. We can say that the original lockdep
> +   is a special case among all cases this crossrelease feature can deal
> +   with.

I'm not sure you can say this at all; you've no proof of correctness
from which this special case flows.

> +3. Releasing is more important than acquiring to check its dependency.
> +   Compare to the third assumption of original lockdep.

Again, you're inverting causality afaict. You depend on the future
happening to say now is correct.

> +Introduce "crosslock"
> +---------------------
> +
> +Crossrelease feature names a lock "crosslock" if it is releasable by a
> +different context from the context having acquired the lock. All locks
> +having been held in the context unlocking the crosslock until
> +eventually the crosslock will be unlocked, have dependency with the
> +crosslock. That's the key idea to implement crossrelease feature.

_all_ locks? That implies infinite storage, which is hardly feasible. If
you limit it, the limit would seem arbitrary and you loose your proof
(in so far as I can see, because you're not actually giving any).


Please, give a coherent, mathematical proof of correctness.

Because I'm not seeing how this thing would work.

  reply	other threads:[~2016-07-01 10:46 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-20  4:55 [RFC 00/12] lockdep: Implement crossrelease feature Byungchul Park
2016-06-20  4:55 ` [RFC 01/12] lockdep: Refactor lookup_chain_cache() Byungchul Park
2016-06-20  4:55 ` [RFC 02/12] lockdep: Add a function building a chain between two hlocks Byungchul Park
2016-06-20  4:55 ` [RFC 03/12] lockdep: Make check_prev_add can use a stack_trace of other context Byungchul Park
2016-06-20  4:55 ` [RFC 04/12] lockdep: Make save_trace can copy from other stack_trace Byungchul Park
2016-06-20  4:55 ` [RFC 05/12] lockdep: Implement crossrelease feature Byungchul Park
2016-06-30 13:03   ` Peter Zijlstra
2016-06-30 23:28     ` Byungchul Park
2016-06-20  4:55 ` [RFC 06/12] lockdep: Apply crossrelease to completion Byungchul Park
2016-06-20  4:55 ` [RFC 07/12] pagemap.h: Remove trailing white space Byungchul Park
2016-06-20  4:55 ` [RFC 08/12] lockdep: Apply crossrelease to PG_locked lock Byungchul Park
2016-06-30 13:04   ` Peter Zijlstra
2016-06-30 23:21     ` Byungchul Park
2016-07-01  8:10       ` Peter Zijlstra
2016-07-01 11:18       ` Kirill A. Shutemov
2016-07-04  4:30         ` Byungchul Park
2016-06-20  4:55 ` [RFC 09/12] cifs/file.c: Remove trailing white space Byungchul Park
2016-06-20  4:55 ` [RFC 10/12] mm/swap_state.c: " Byungchul Park
2016-06-20  4:55 ` [RFC 11/12] lockdep: Call lock_acquire(release) when accessing PG_locked manually Byungchul Park
2016-06-20  4:55 ` [RFC 12/12] x86/dumpstack: Optimize save_stack_trace Byungchul Park
2016-06-20  7:29   ` xinhui
2016-06-20  7:50     ` byungchul.park
2016-06-29 12:43       ` Byungchul Park
2016-06-30 10:38         ` xinhui
2016-06-30 23:06           ` Byungchul Park
2016-06-23 23:37 ` [RFC 00/12] lockdep: Implement crossrelease feature Byungchul Park
2016-06-24  7:08   ` Peter Zijlstra
2016-06-24 11:13     ` Byungchul Park
2016-06-24 11:26   ` Nikolay Borisov
2016-06-27  1:34     ` Byungchul Park
2016-07-01  4:15 ` [PATCH] lockdep: Add a document describing " Byungchul Park
2016-07-01 10:45   ` Peter Zijlstra [this message]
2016-07-04  6:42     ` Byungchul Park
2016-07-06  0:49       ` Boqun Feng
2016-07-06  2:17         ` Byungchul Park
2016-07-06  5:33           ` Byungchul Park
2016-07-06  7:56             ` Peter Zijlstra
2016-07-06  8:12               ` Byungchul Park

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=20160701104521.GG30154@twins.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=byungchul.park@lge.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=walken@google.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.