public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* CPU ordering with respect to krefs
@ 2007-04-02 12:47 Oliver Neukum
  2007-04-02 14:33 ` Eric Dumazet
  0 siblings, 1 reply; 4+ messages in thread
From: Oliver Neukum @ 2007-04-02 12:47 UTC (permalink / raw)
  To: Greg KH, linux-kernel

Hi,

some atomic operations are only atomic, not ordered. Thus a CPU is allowed
to reorder memory references to an object to before the reference is
obtained. This fixes it.

	Regards
		Oliver
Signed-off-by: Oliver Neukum <oneukum@suse.de>
------

--- a/lib/kref.c	2007-04-02 14:40:40.000000000 +0200
+++ b/lib/kref.c	2007-04-02 14:40:50.000000000 +0200
@@ -21,6 +21,7 @@
 void kref_init(struct kref *kref)
 {
 	atomic_set(&kref->refcount,1);
+	smp_mb();
 }
 
 /**
@@ -31,6 +32,7 @@
 {
 	WARN_ON(!atomic_read(&kref->refcount));
 	atomic_inc(&kref->refcount);
+	smp_mb__after_atomic_inc();
 }
 
 /**

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: CPU ordering with respect to krefs
  2007-04-02 12:47 CPU ordering with respect to krefs Oliver Neukum
@ 2007-04-02 14:33 ` Eric Dumazet
  2007-04-12  6:27   ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Dumazet @ 2007-04-02 14:33 UTC (permalink / raw)
  To: Oliver Neukum; +Cc: Greg KH, linux-kernel

On Mon, 2 Apr 2007 14:47:59 +0200
Oliver Neukum <oneukum@suse.de> wrote:

> Hi,
> 
> some atomic operations are only atomic, not ordered. Thus a CPU is allowed
> to reorder memory references to an object to before the reference is
> obtained. This fixes it.
> 
> 	Regards
> 		Oliver
> Signed-off-by: Oliver Neukum <oneukum@suse.de>
> ------
> 
> --- a/lib/kref.c	2007-04-02 14:40:40.000000000 +0200
> +++ b/lib/kref.c	2007-04-02 14:40:50.000000000 +0200
> @@ -21,6 +21,7 @@
>  void kref_init(struct kref *kref)
>  {
>  	atomic_set(&kref->refcount,1);
> +	smp_mb();
>  }

I dont understand why smp_mb() is needed here, and not in spinlock_init() for example.

If you have ordering issues, then the caller of kref_init() should take care of it, not kref_init() itself.

Random example taken in drivers/usb/gadget/file_storage.c :

static int __init fsg_alloc(void)
{
...
kref_init(&fsg->ref);
init_completion(&fsg->thread_notifier);

the_fsg = fsg;
}

In this example, "the_fsg = fsg" memory write might be visible before the memory writes done in init_completion().
Doing a smp_mb() in kref_init() wont help.

AFAIK kref implementation doesnt need this extra smp_mb().


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: CPU ordering with respect to krefs
  2007-04-02 14:33 ` Eric Dumazet
@ 2007-04-12  6:27   ` Greg KH
  2007-04-17  5:44     ` Oliver Neukum
  0 siblings, 1 reply; 4+ messages in thread
From: Greg KH @ 2007-04-12  6:27 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Oliver Neukum, Greg KH, linux-kernel

On Mon, Apr 02, 2007 at 04:33:54PM +0200, Eric Dumazet wrote:
> On Mon, 2 Apr 2007 14:47:59 +0200
> Oliver Neukum <oneukum@suse.de> wrote:
> 
> > Hi,
> > 
> > some atomic operations are only atomic, not ordered. Thus a CPU is allowed
> > to reorder memory references to an object to before the reference is
> > obtained. This fixes it.
> > 
> > 	Regards
> > 		Oliver
> > Signed-off-by: Oliver Neukum <oneukum@suse.de>
> > ------
> > 
> > --- a/lib/kref.c	2007-04-02 14:40:40.000000000 +0200
> > +++ b/lib/kref.c	2007-04-02 14:40:50.000000000 +0200
> > @@ -21,6 +21,7 @@
> >  void kref_init(struct kref *kref)
> >  {
> >  	atomic_set(&kref->refcount,1);
> > +	smp_mb();
> >  }
> 
> I dont understand why smp_mb() is needed here, and not in
> spinlock_init() for example.

I think, after reading the Documentation/memory-barriers.txt and
Documentation/atomic_ops.txt documentation, that spin_lock_init() also
needs this kind of memory barrier.

>From what I can tell (Oliver, please correct me if I'm wrong, you know
this much better than I do), the issue is that atomic init has no memory
barrier, and you need to handle that.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: CPU ordering with respect to krefs
  2007-04-12  6:27   ` Greg KH
@ 2007-04-17  5:44     ` Oliver Neukum
  0 siblings, 0 replies; 4+ messages in thread
From: Oliver Neukum @ 2007-04-17  5:44 UTC (permalink / raw)
  To: Greg KH; +Cc: Eric Dumazet, Greg KH, linux-kernel

Am Donnerstag, 12. April 2007 08:27 schrieb Greg KH:
> On Mon, Apr 02, 2007 at 04:33:54PM +0200, Eric Dumazet wrote:
> > On Mon, 2 Apr 2007 14:47:59 +0200
> > Oliver Neukum <oneukum@suse.de> wrote:
> > 
> > > Hi,
> > > 
> > > some atomic operations are only atomic, not ordered. Thus a CPU is allowed
> > > to reorder memory references to an object to before the reference is
> > > obtained. This fixes it.
> > > 
> > > 	Regards
> > > 		Oliver
> > > Signed-off-by: Oliver Neukum <oneukum@suse.de>
> > > ------
> > > 
> > > --- a/lib/kref.c	2007-04-02 14:40:40.000000000 +0200
> > > +++ b/lib/kref.c	2007-04-02 14:40:50.000000000 +0200
> > > @@ -21,6 +21,7 @@
> > >  void kref_init(struct kref *kref)
> > >  {
> > >  	atomic_set(&kref->refcount,1);
> > > +	smp_mb();
> > >  }
> > 
> > I dont understand why smp_mb() is needed here, and not in
> > spinlock_init() for example.
> 
> I think, after reading the Documentation/memory-barriers.txt and
> Documentation/atomic_ops.txt documentation, that spin_lock_init() also
> needs this kind of memory barrier.

spin_lock_init() is not an atomic operation.
In principle, the issue exists. However, the whole issue is a bit of a grey
area. You might take the viewpoint that upping the refcount needs to be
under lock, which needs to take care of ordering issues in case of krefs.
A new spinlock has the same issue. You need to be careful making them
accessible to other CPUs.

If you take code like:

static int producer()
{
	...
	data = kmalloc(...);
	spin_lock_init(&data->lock);
	data->value = some_value;
	data->next = global_pointer;

	global_pointer = data;
	...
}
	
You have an ordering bug anyway, which you can't fix in spin_lock_init().

	Regards
		Oliver

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-04-17  5:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-02 12:47 CPU ordering with respect to krefs Oliver Neukum
2007-04-02 14:33 ` Eric Dumazet
2007-04-12  6:27   ` Greg KH
2007-04-17  5:44     ` Oliver Neukum

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox