public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Ming Lei <tom.leiming@gmail.com>
Cc: gregkh@suse.de, akpm@linux-foundation.org,
	linux-kernel@vger.kernel.org, ostrikov@nvidia.com,
	adobriyan@gmail.com, eric.dumazet@gmail.com, mingo@elte.hu,
	Oliver Neukum <oneukum@suse.de>
Subject: Re: [PATCH 3/3] kref: Remove the memory barriers
Date: Sun, 11 Dec 2011 21:42:28 +0100	[thread overview]
Message-ID: <1323636148.16764.44.camel@twins> (raw)
In-Reply-To: <1323617738.16764.21.camel@twins>

On Sun, 2011-12-11 at 16:35 +0100, Peter Zijlstra wrote:
> On Sun, 2011-12-11 at 20:59 +0800, Ming Lei wrote:
> > 
> > The implicit rule about kref is that use should make sure
> > that kref can not be touched once it is released. 
> 
> The only transition for with order makes any difference what so ever is
> 1 -> 0, you just said that should be done by external means (I agree and
> have argued thusly), therefore any memory barriers outside of these
> external means are superfluous.
> 
> Thus the proposed patch is correct.

Also, this was an entirely different issue than was raised in the
original changelog. Memory barriers in general are about ordering
visibility between multiple operations done on one cpu vs them being
visible on another.

The important point being that there need to be multiple operations on
one cpu in order for them to be able to make a difference. And the whole
issue in the past few emails only had a single operation on each cpu.
Therefore memory barriers are completely irrelevant.

Ever so more because atomic_t is atomic on the variable regardless of
visibility by a second party.

Anyway, one more way to illustrate my point; there's three distinct
phases in the life cycle of a kref managed object: insert, lookup and
removal. They are as follows:

INSERT:
	obj = alloc_obj();
	init_obj(obj);
	  kref_set(&obj->ref, 1);

	LOCK
	insert(obj);
	UNLOCK

LOOKUP:
	LOCK
	obj = lookup(key);
	if (obj)
	  kref_get();
	UNLOCK

	...

	kref_put(); /* assuming obj != NULL */

REMOVAL: /* assumes obj was acquired using a preceding LOOKUP */
	LOCK
	remove(obj);
	UNLOCK

	kref_sub(&obj->ref, 2); /* lookup + insert */


Before the insert() our obj isn't visible to other CPUs doing lookup(),
therefore there can be no concurrency on the kref, after insert the
insert's UNLOCK + lookup's LOCK provide the full memory barrier
separating the last write to the object and the first read of it.

Multiple lookup()s can be concurrent with each other and the last
remove(). Concurrent lookups are completely non-interesting since they
can't ever trigger the ->0 transition.

A lookup interleaved with a removal is serialized on the lock around our
data-structure, after the removal no new lookups will succeed, and thus
no new kref_get()s will be issued and all that happens is decrements
until we hit 0.

The issue from the original changelog was that within a lookup, reads
and writes to the obj might be re-ordered with the acquisition of the
refcount. IOW. something like:

  LOCK
  obj = lookup(); /* lets assume obj != NULL */
  kref_get(&obj->ref);
  UNLOCK

  value = obj->member;

  kref_put(&obj->ref);

Now, under our memory model, the read from obj->member can both happen,
or be observed to happen before the increment from kref_get() is
processed.

I completely fail to see how that is an issue, nor when it is, why kref
should care. If you rely on that, you're doing something weird and
exotic and had better place the appropriate memory barriers yourself.



  reply	other threads:[~2011-12-11 20:43 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-10 10:43 [PATCH 0/3] kref: inline and barriers Peter Zijlstra
2011-12-10 10:43 ` [PATCH 1/3] kref: Inline all functions Peter Zijlstra
2011-12-10 14:32   ` Ming Lei
2011-12-10 14:59     ` Peter Zijlstra
2011-12-12 22:11   ` Greg KH
2011-12-13  9:36     ` Peter Zijlstra
2011-12-13 17:15       ` Greg KH
2011-12-13 18:52         ` Peter Zijlstra
2011-12-13 19:11           ` Greg KH
2011-12-13 19:36             ` Peter Zijlstra
2011-12-10 10:43 ` [PATCH 2/3] kref: Implement kref_put in terms of kref_sub Peter Zijlstra
2011-12-10 10:43 ` [PATCH 3/3] kref: Remove the memory barriers Peter Zijlstra
2011-12-10 14:07   ` Ming Lei
2011-12-10 14:58     ` Peter Zijlstra
2011-12-10 15:57       ` Ming Lei
2011-12-10 19:49         ` Peter Zijlstra
2011-12-11  2:22           ` Ming Lei
2011-12-11 12:47             ` Peter Zijlstra
2011-12-11 12:59               ` Ming Lei
2011-12-11 15:35                 ` Peter Zijlstra
2011-12-11 20:42                   ` Peter Zijlstra [this message]
2011-12-12  3:48                     ` Ming Lei
2011-12-12  8:54                       ` Peter Zijlstra
2011-12-12  9:57                         ` Ming Lei
2011-12-12 10:12                           ` Peter Zijlstra
2011-12-12 10:32                             ` Ming Lei
2011-12-12 11:05                               ` Peter Zijlstra
2011-12-12 11:19                                 ` Ming Lei
2011-12-12 11:13                               ` Eric Dumazet
2011-12-12 11:15                               ` Oliver Neukum
2011-12-12 10:20                           ` Oliver Neukum
2011-12-12 19:30                             ` Greg KH
2011-12-12 22:56                               ` Oliver Neukum
2011-12-12 23:14                                 ` Greg KH
2011-12-13 11:51                                   ` Oliver Neukum
2011-12-13  9:12                                 ` Peter Zijlstra
2011-12-13  9:49                                   ` Oliver Neukum
2011-12-12  8:55                       ` Peter Zijlstra
2011-12-12 15:24                         ` Greg KH
2011-12-12  8:56                       ` Peter Zijlstra
2011-12-12 10:10                         ` Ming Lei

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=1323636148.16764.44.camel@twins \
    --to=peterz@infradead.org \
    --cc=adobriyan@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=eric.dumazet@gmail.com \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=oneukum@suse.de \
    --cc=ostrikov@nvidia.com \
    --cc=tom.leiming@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox