datapath: Fix table sparse annotations.
authorJesse Gross <jesse@nicira.com>
Fri, 24 Dec 2010 04:31:39 +0000 (20:31 -0800)
committerJesse Gross <jesse@nicira.com>
Wed, 29 Dec 2010 18:30:09 +0000 (10:30 -0800)
Several of the pointers in table.c were missing the correct
__rcu annotation and the pointer type in the actual declaration
of struct tbl was incorrect, so this fixes that.  It also adds
usage of rcu_dereference() to access an RCU protected pointer,
which is not strictly correct since an update side lock should
be held.  However, since the table is used in different pieces
of code and therefore different locks are used it is difficult
to know which lock to check without threading the information
though, which is ugly.  Since other places in table.c have this
same problem and this code should go away in the future it is
left as is.

Found with sparse.

Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
datapath/table.c
datapath/table.h

index d2432e89da2ceacf34eaf7dd390196ab8f40d8c7..5c1b82a4b69ac8938a340305b2b913ac9de14632 100644 (file)
@@ -40,17 +40,18 @@ static struct tbl_bucket *bucket_alloc(int n_objs)
        return kmalloc(bucket_size(n_objs), GFP_KERNEL);
 }
 
-static void free_buckets(struct tbl_bucket ***l1, unsigned int n_buckets,
+static void free_buckets(struct tbl_bucket __rcu ***l1,
+                        unsigned int n_buckets,
                         void (*free_obj)(struct tbl_node *))
 {
        unsigned int i;
 
        for (i = 0; i < n_buckets >> TBL_L1_SHIFT; i++) {
-               struct tbl_bucket **l2 = l1[i];
+               struct tbl_bucket __rcu **l2 = l1[i];
                unsigned int j;
 
                for (j = 0; j < TBL_L2_SIZE; j++) {
-                       struct tbl_bucket *bucket = l2[j];
+                       struct tbl_bucket *bucket = rcu_dereference(l2[j]);
                        if (!bucket)
                                continue;
 
@@ -66,9 +67,9 @@ static void free_buckets(struct tbl_bucket ***l1, unsigned int n_buckets,
        kfree(l1);
 }
 
-static struct tbl_bucket ***alloc_buckets(unsigned int n_buckets)
+static struct tbl_bucket __rcu ***alloc_buckets(unsigned int n_buckets)
 {
-       struct tbl_bucket ***l1;
+       struct tbl_bucket __rcu ***l1;
        unsigned int i;
 
        l1 = kmalloc((n_buckets >> TBL_L1_SHIFT) * sizeof(struct tbl_bucket **),
@@ -76,7 +77,7 @@ static struct tbl_bucket ***alloc_buckets(unsigned int n_buckets)
        if (!l1)
                return NULL;
        for (i = 0; i < n_buckets >> TBL_L1_SHIFT; i++) {
-               l1[i] = (struct tbl_bucket **)get_zeroed_page(GFP_KERNEL);
+               l1[i] = (struct tbl_bucket __rcu **)get_zeroed_page(GFP_KERNEL);
                if (!l1[i]) {
                        free_buckets(l1, i << TBL_L1_SHIFT, NULL);
                        return NULL;
index 2fd569b6e00eec109b2aa15db49d91d5c4db0793..f186600b21cb3cd3d786c862a161a8bc9a1e5f62 100644 (file)
@@ -34,7 +34,7 @@ struct tbl_node {
 struct tbl {
        struct rcu_head rcu;
        unsigned int n_buckets;
-       struct tbl_bucket ** __rcu *buckets;
+       struct tbl_bucket __rcu ***buckets;
        unsigned int count;
        void (*obj_destructor)(struct tbl_node *);
 };