From: Jesse Gross Date: Mon, 6 Dec 2010 23:15:47 +0000 (-0800) Subject: datapath: Convert rcu_dereference() to correct variant. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e33adfd0cea19a8a4dab5cdbe80e2fd636e48374;p=openvswitch datapath: Convert rcu_dereference() to correct variant. Using rcu_dereference() makes lockdep complain if rcu_read_lock is not held. This is OK if the update side lock is held. This adds checks to see if RTNL lock is held, if that is also a correct form of protection. Alternately, it enforces that RTNL must be held. Signed-off-by: Jesse Gross Acked-by: Ben Pfaff --- diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 239e604c..381e2618 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -181,7 +181,7 @@ static int port_cmp(const struct tbl_node *node, void *target) const struct tnl_vport *tnl_vport = tnl_vport_table_cast(node); struct port_lookup_key *lookup = target; - lookup->mutable = rcu_dereference(tnl_vport->mutable); + lookup->mutable = rcu_dereference_rtnl(tnl_vport->mutable); return (lookup->mutable->tunnel_type == lookup->tunnel_type && lookup->mutable->port_config.daddr == lookup->daddr && @@ -313,7 +313,7 @@ struct vport *tnl_find_port(__be32 saddr, __be32 daddr, __be64 key, const struct tnl_mutable_config **mutable) { struct port_lookup_key lookup; - struct tbl *table = rcu_dereference(port_table); + struct tbl *table = rcu_dereference_rtnl(port_table); struct tbl_node *tbl_node; if (unlikely(!table)) @@ -1511,13 +1511,13 @@ const char *tnl_get_name(const struct vport *vport) const unsigned char *tnl_get_addr(const struct vport *vport) { const struct tnl_vport *tnl_vport = tnl_vport_priv(vport); - return rcu_dereference(tnl_vport->mutable)->eth_addr; + return rcu_dereference_rtnl(tnl_vport->mutable)->eth_addr; } int tnl_get_mtu(const struct vport *vport) { const struct tnl_vport *tnl_vport = tnl_vport_priv(vport); - return rcu_dereference(tnl_vport->mutable)->mtu; + return rcu_dereference_rtnl(tnl_vport->mutable)->mtu; } void tnl_free_linked_skbs(struct sk_buff *skb) diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index 88274732..d492d19b 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -279,11 +279,11 @@ struct vport *netdev_get_vport(struct net_device *dev) #else if (likely(rcu_access_pointer(dev->rx_handler) == netdev_frame_hook)) #endif - return (struct vport *)rcu_dereference(dev->rx_handler_data); + return (struct vport *)rcu_dereference_rtnl(dev->rx_handler_data); else return NULL; #else - return (struct vport *)rcu_dereference(dev->br_port); + return (struct vport *)rcu_dereference_rtnl(dev->br_port); #endif } diff --git a/datapath/vport-patch.c b/datapath/vport-patch.c index 8bb204ba..4fdbcf52 100644 --- a/datapath/vport-patch.c +++ b/datapath/vport-patch.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "datapath.h" #include "vport.h" @@ -58,7 +59,7 @@ static void assign_config_rcu(struct vport *vport, struct patch_vport *patch_vport = patch_vport_priv(vport); struct device_config *old_config; - old_config = rcu_dereference(patch_vport->devconf); + old_config = rtnl_dereference(patch_vport->devconf); rcu_assign_pointer(patch_vport->devconf, new_config); call_rcu(&old_config->rcu, free_config); } @@ -228,13 +229,13 @@ static const char *patch_get_name(const struct vport *vport) static const unsigned char *patch_get_addr(const struct vport *vport) { const struct patch_vport *patch_vport = patch_vport_priv(vport); - return rcu_dereference(patch_vport->devconf)->eth_addr; + return rcu_dereference_rtnl(patch_vport->devconf)->eth_addr; } static int patch_get_mtu(const struct vport *vport) { const struct patch_vport *patch_vport = patch_vport_priv(vport); - return rcu_dereference(patch_vport->devconf)->mtu; + return rcu_dereference_rtnl(patch_vport->devconf)->mtu; } static int patch_send(struct vport *vport, struct sk_buff *skb)