diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 2d2efb877975..6df80cad40a2 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -49,7 +49,7 @@ const char vlan_version[] = DRV_VERSION; static int vlan_group_prealloc_vid(struct vlan_group *vg, __be16 vlan_proto, u16 vlan_id) { - struct net_device **array; + struct net_device __rcu **array; unsigned int vidx; unsigned int size; int pidx; diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index c41caaf94095..3cb4c8294130 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -22,8 +22,8 @@ enum vlan_protos { struct vlan_group { unsigned int nr_vlan_devs; struct hlist_node hlist; /* linked list */ - struct net_device **vlan_devices_arrays[VLAN_PROTO_NUM] - [VLAN_GROUP_ARRAY_SPLIT_PARTS]; + struct net_device __rcu **vlan_devices_arrays[VLAN_PROTO_NUM] + [VLAN_GROUP_ARRAY_SPLIT_PARTS]; }; struct vlan_info { @@ -54,7 +54,7 @@ static inline struct net_device *__vlan_group_get_device(struct vlan_group *vg, unsigned int pidx, u16 vlan_id) { - struct net_device **array; + struct net_device __rcu **array; array = vg->vlan_devices_arrays[pidx] [vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; @@ -62,7 +62,7 @@ static inline struct net_device *__vlan_group_get_device(struct vlan_group *vg, /* paired with smp_wmb() in vlan_group_prealloc_vid() */ smp_rmb(); - return array ? array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] : NULL; + return array ? rcu_dereference_raw(array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN]) : NULL; } static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, @@ -82,13 +82,13 @@ static inline void vlan_group_set_device(struct vlan_group *vg, struct net_device *dev) { int pidx = vlan_proto_idx(vlan_proto); - struct net_device **array; + struct net_device __rcu **array; if (!vg || pidx < 0) return; array = vg->vlan_devices_arrays[pidx] [vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; - array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; + rcu_assign_pointer(array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN], dev); } /* Must be invoked with rcu_read_lock or with RTNL. */