Subject: RE: unsafe locks seen with netperf on net-2.6.29 tree

From: Peter Zijlstra <[email-masked]>
Date: Sat, 27 Dec 2008 21:38:28 +0100

On Sat, 2008-12-27 at 12:38 -0700, Tantilov, Emil S wrote:
> Peter Zijlstra wrote:

> > index 9007ccd..a074d77 100644
> > --- a/include/linux/percpu_counter.h
> > +++ b/include/linux/percpu_counter.h
> > @@ -30,8 +30,16 @@ struct percpu_counter {
> >  #define FBC_BATCH    (NR_CPUS*4)
> >  #endif
> >
> > -int percpu_counter_init(struct percpu_counter *fbc, s64 amount);
> > -int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount);
> > +int __percpu_counter_init(struct percpu_counter *fbc, s64 amount,
> > +                       struct lock_class_key *key);
> > +
> > +#define percpu_counter_init(fbc, value)                                      \
> > +     do {                                                            \
> > +             static struct lock_class_key __key;                     \
> > +                                                                     \
> > +             __percpu_counter_init(fbc, value, &__key);              \
> > +     } while (0)
> > +
> >  void percpu_counter_destroy(struct percpu_counter *fbc);
> >  void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
> >  void __percpu_counter_add(struct percpu_counter *fbc, s64 amount,

> This patch fails to compile:
> 
> mm/backing-dev.c: In function 'bdi_init':
> mm/backing-dev.c:226: error: expected expression bedore 'do'

Ah indeed, stupid me...

Please try something like this instead of the above hunk:

@@ -30,8 +30,16 @@ struct percpu_counter {
 #define FBC_BATCH      (NR_CPUS*4)
 #endif

-int percpu_counter_init(struct percpu_counter *fbc, s64 amount);
-int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount);
+int __percpu_counter_init(struct percpu_counter *fbc, s64 amount,
+                         struct lock_class_key *key);
+
+#define percpu_counter_init(fbc, value)                                        \
+       ({                                                              \
+               static struct lock_class_key __key;                     \
+                                                                       \
+               __percpu_counter_init(fbc, value, &__key);              \
+       })
+
 void percpu_counter_destroy(struct percpu_counter *fbc);
 void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
 void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)