From: Jesse Gross Date: Fri, 24 Dec 2010 04:31:39 +0000 (-0800) Subject: datapath: Fix table sparse annotations. X-Git-Tag: v1.1.0~557 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=4885254becfd531f8a24adb33f8c62c2f17debb0;p=sliver-openvswitch.git datapath: Fix table sparse annotations. 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 Acked-by: Ben Pfaff --- diff --git a/datapath/table.c b/datapath/table.c index d2432e89d..5c1b82a4b 100644 --- a/datapath/table.c +++ b/datapath/table.c @@ -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; diff --git a/datapath/table.h b/datapath/table.h index 2fd569b6e..f186600b2 100644 --- a/datapath/table.h +++ b/datapath/table.h @@ -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 *); };