From e1040c772fbebc3abe9e7222f9c540112c4dca81 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Sat, 4 Dec 2010 11:50:53 -0800 Subject: [PATCH] datapath: Add usage of __rcu annotation. Sparse can warn about incorrect usage of RCU via direct access to points when used in conjuction with __rcu and CONFIG_SPARSE_RCU. This adds the necessary annotations. Signed-off-by: Jesse Gross Acked-by: Ben Pfaff --- datapath/datapath.c | 2 +- datapath/datapath.h | 6 +++--- datapath/flow.h | 2 +- datapath/table.c | 10 +++++----- datapath/table.h | 2 +- datapath/tunnel.c | 3 +-- datapath/tunnel.h | 4 ++-- datapath/vport-patch.c | 7 ++----- 8 files changed, 16 insertions(+), 20 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index 98685c0c..5e2821a5 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -67,7 +67,7 @@ EXPORT_SYMBOL(dp_ioctl_hook); * It is safe to access the datapath and vport structures with just * dp_mutex. */ -static struct datapath *dps[ODP_MAX]; +static struct datapath __rcu *dps[ODP_MAX]; static DEFINE_MUTEX(dp_mutex); static int new_vport(struct datapath *, struct odp_port *, int port_no); diff --git a/datapath/datapath.h b/datapath/datapath.h index 66ade3e1..e4c6534f 100644 --- a/datapath/datapath.h +++ b/datapath/datapath.h @@ -66,7 +66,7 @@ struct dp_stats_percpu { * @queues: %DP_N_QUEUES sets of queued packets for userspace to handle. * @waitqueue: Waitqueue, for waiting for new packets in @queues. * @n_flows: Number of flows currently in flow table. - * @table: Current flow table (RCU protected). + * @table: Current flow table. * @n_ports: Number of ports currently in @ports. * @ports: Map from port number to &struct vport. %ODPP_LOCAL port * always exists, other ports may be %NULL. @@ -88,11 +88,11 @@ struct datapath { wait_queue_head_t waitqueue; /* Flow table. */ - struct tbl *table; + struct tbl __rcu *table; /* Switch ports. */ unsigned int n_ports; - struct vport *ports[DP_MAX_PORTS]; + struct vport __rcu *ports[DP_MAX_PORTS]; struct list_head port_list; /* Stats. */ diff --git a/datapath/flow.h b/datapath/flow.h index 61ffcd75..07644827 100644 --- a/datapath/flow.h +++ b/datapath/flow.h @@ -34,7 +34,7 @@ struct sw_flow { struct tbl_node tbl_node; struct odp_flow_key key; - struct sw_flow_actions *sf_acts; + struct sw_flow_actions __rcu *sf_acts; atomic_t refcnt; bool dead; diff --git a/datapath/table.c b/datapath/table.c index c6614e13..28063085 100644 --- a/datapath/table.c +++ b/datapath/table.c @@ -161,7 +161,7 @@ void tbl_deferred_destroy(struct tbl *table, void (*destructor)(struct tbl_node call_rcu(&table->rcu, destroy_table_rcu); } -static struct tbl_bucket **find_bucket(struct tbl *table, u32 hash) +static struct tbl_bucket __rcu **find_bucket(struct tbl *table, u32 hash) { unsigned int l1 = (hash & (table->n_buckets - 1)) >> TBL_L1_SHIFT; unsigned int l2 = hash & ((1 << TBL_L2_BITS) - 1); @@ -197,7 +197,7 @@ static int search_bucket(const struct tbl_bucket *bucket, void *target, u32 hash struct tbl_node *tbl_lookup(struct tbl *table, void *target, u32 hash, int (*cmp)(const struct tbl_node *, void *)) { - struct tbl_bucket **bucketp = find_bucket(table, hash); + struct tbl_bucket __rcu **bucketp = find_bucket(table, hash); struct tbl_bucket *bucket = rcu_dereference(*bucketp); int index; @@ -230,7 +230,7 @@ int tbl_foreach(struct tbl *table, { unsigned int i, j, k; for (i = 0; i < table->n_buckets >> TBL_L1_BITS; i++) { - struct tbl_bucket **l2 = table->buckets[i]; + struct tbl_bucket __rcu **l2 = table->buckets[i]; for (j = 0; j < TBL_L1_SIZE; j++) { struct tbl_bucket *bucket = rcu_dereference(l2[j]); if (!bucket) @@ -318,7 +318,7 @@ static void free_bucket_rcu(struct rcu_head *rcu) */ int tbl_insert(struct tbl *table, struct tbl_node *target, u32 hash) { - struct tbl_bucket **oldp = find_bucket(table, hash); + struct tbl_bucket __rcu **oldp = find_bucket(table, hash); struct tbl_bucket *old = rcu_dereference(*oldp); unsigned int n = old ? old->n_objs : 0; struct tbl_bucket *new = bucket_alloc(n + 1); @@ -356,7 +356,7 @@ int tbl_insert(struct tbl *table, struct tbl_node *target, u32 hash) */ int tbl_remove(struct tbl *table, struct tbl_node *target) { - struct tbl_bucket **oldp = find_bucket(table, target->hash); + struct tbl_bucket __rcu **oldp = find_bucket(table, target->hash); struct tbl_bucket *old = rcu_dereference(*oldp); unsigned int n = old->n_objs; struct tbl_bucket *new; diff --git a/datapath/table.h b/datapath/table.h index dac57476..609d9b14 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 ***buckets; + struct tbl_bucket ** __rcu *buckets; unsigned int count; void (*obj_destructor)(struct tbl_node *); }; diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 1e402931..d2ede147 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -68,8 +68,7 @@ #define CACHE_DATA_ALIGN 16 -/* Protected by RCU. */ -static struct tbl *port_table __read_mostly; +static struct tbl __rcu *port_table __read_mostly; static void cache_cleaner(struct work_struct *work); static DECLARE_DELAYED_WORK(cache_cleaner_wq, cache_cleaner); diff --git a/datapath/tunnel.h b/datapath/tunnel.h index 5615f6ad..aa859f6e 100644 --- a/datapath/tunnel.h +++ b/datapath/tunnel.h @@ -161,7 +161,7 @@ struct tnl_vport { char name[IFNAMSIZ]; const struct tnl_ops *tnl_ops; - struct tnl_mutable_config *mutable; /* Protected by RCU. */ + struct tnl_mutable_config __rcu *mutable; /* * ID of last fragment sent (for tunnel protocols with direct support @@ -171,7 +171,7 @@ struct tnl_vport { atomic_t frag_id; spinlock_t cache_lock; - struct tnl_cache *cache; /* Protected by RCU/cache_lock. */ + struct tnl_cache __rcu *cache; /* Protected by RCU/cache_lock. */ #ifdef NEED_CACHE_TIMEOUT /* diff --git a/datapath/vport-patch.c b/datapath/vport-patch.c index d27509a1..8bb204ba 100644 --- a/datapath/vport-patch.c +++ b/datapath/vport-patch.c @@ -30,11 +30,8 @@ struct patch_vport { char peer_name[IFNAMSIZ]; struct hlist_node hash_node; - /* Protected by RCU. */ - struct vport *peer; - - /* Protected by RCU. */ - struct device_config *devconf; + struct vport __rcu *peer; + struct device_config __rcu *devconf; }; /* Protected by RTNL lock. */ -- 2.30.2