datapath: Add missing rtnl_dereference() calls.
authorJesse Gross <jesse@nicira.com>
Fri, 24 Dec 2010 00:28:23 +0000 (16:28 -0800)
committerJesse Gross <jesse@nicira.com>
Wed, 29 Dec 2010 17:54:21 +0000 (09:54 -0800)
There are a few additional places where RCU protected pointers
are directly dereferenced because they assume RTNL lock.  These
were previously not reported due to some other sparse errors in
the Linux headers files.  This adds the necessary rtnl_dereference()
calls to make sparse happy and allow lockdep to validate.

Found with sparse.

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

index 548b99dc105de7f37e8f2557c74d9dc4abc21866..ce1d8eb524663afd93f741fc5a550783feca99a0 100644 (file)
@@ -1429,7 +1429,8 @@ int tnl_modify(struct vport *vport, struct odp_port *port)
        struct tnl_mutable_config *mutable;
        int err;
 
-       mutable = kmemdup(tnl_vport->mutable, sizeof(struct tnl_mutable_config), GFP_KERNEL);
+       mutable = kmemdup(rtnl_dereference(tnl_vport->mutable),
+                         sizeof(struct tnl_mutable_config), GFP_KERNEL);
        if (!mutable) {
                err = -ENOMEM;
                goto error;
@@ -1468,13 +1469,13 @@ static void free_port_rcu(struct rcu_head *rcu)
 int tnl_destroy(struct vport *vport)
 {
        struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
-       const struct tnl_mutable_config *old_mutable;
+       const struct tnl_mutable_config *mutable, *old_mutable;
+
+       mutable = rtnl_dereference(tnl_vport->mutable);
 
-       if (vport == tnl_find_port(tnl_vport->mutable->port_config.saddr,
-           tnl_vport->mutable->port_config.daddr,
-           tnl_vport->mutable->port_config.in_key,
-           tnl_vport->mutable->tunnel_type,
-           &old_mutable))
+       if (vport == tnl_find_port(mutable->port_config.saddr,
+           mutable->port_config.daddr, mutable->port_config.in_key,
+           mutable->tunnel_type, &old_mutable))
                del_port(vport);
 
        call_rcu(&tnl_vport->rcu, free_port_rcu);
@@ -1487,7 +1488,8 @@ int tnl_set_mtu(struct vport *vport, int mtu)
        struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
        struct tnl_mutable_config *mutable;
 
-       mutable = kmemdup(tnl_vport->mutable, sizeof(struct tnl_mutable_config), GFP_KERNEL);
+       mutable = kmemdup(rtnl_dereference(tnl_vport->mutable),
+                         sizeof(struct tnl_mutable_config), GFP_KERNEL);
        if (!mutable)
                return -ENOMEM;
 
@@ -1502,7 +1504,8 @@ int tnl_set_addr(struct vport *vport, const unsigned char *addr)
        struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
        struct tnl_mutable_config *mutable;
 
-       mutable = kmemdup(tnl_vport->mutable, sizeof(struct tnl_mutable_config), GFP_KERNEL);
+       mutable = kmemdup(rtnl_dereference(tnl_vport->mutable),
+                         sizeof(struct tnl_mutable_config), GFP_KERNEL);
        if (!mutable)
                return -ENOMEM;
 
index b03c3aa1cb83b73192770e00cf39021ac218a466..ef9778f3c5e1aede4aff6a93f1b9ea01495cfb5f 100644 (file)
@@ -156,7 +156,8 @@ static int patch_modify(struct vport *vport, struct odp_port *port)
        struct device_config *devconf;
        int err;
 
-       devconf = kmemdup(patch_vport->devconf, sizeof(struct device_config), GFP_KERNEL);
+       devconf = kmemdup(rtnl_dereference(patch_vport->devconf),
+                         sizeof(struct device_config), GFP_KERNEL);
        if (!devconf) {
                err = -ENOMEM;
                goto error;
@@ -221,7 +222,8 @@ static int patch_set_mtu(struct vport *vport, int mtu)
        struct patch_vport *patch_vport = patch_vport_priv(vport);
        struct device_config *devconf;
 
-       devconf = kmemdup(patch_vport->devconf, sizeof(struct device_config), GFP_KERNEL);
+       devconf = kmemdup(rtnl_dereference(patch_vport->devconf),
+                         sizeof(struct device_config), GFP_KERNEL);
        if (!devconf)
                return -ENOMEM;
 
@@ -236,7 +238,8 @@ static int patch_set_addr(struct vport *vport, const unsigned char *addr)
        struct patch_vport *patch_vport = patch_vport_priv(vport);
        struct device_config *devconf;
 
-       devconf = kmemdup(patch_vport->devconf, sizeof(struct device_config), GFP_KERNEL);
+       devconf = kmemdup(rtnl_dereference(patch_vport->devconf),
+                         sizeof(struct device_config), GFP_KERNEL);
        if (!devconf)
                return -ENOMEM;