]> Pileus Git - ~andy/linux/blobdiff - drivers/net/macvtap.c
Merge branch 'linus' into x86/urgent
[~andy/linux] / drivers / net / macvtap.c
index fc27a9926d9e52c28a63d6be8852518e5cebb4da..6696e56e63206024c7f529331f7088c72406982d 100644 (file)
@@ -39,7 +39,7 @@ struct macvtap_queue {
        struct socket sock;
        struct socket_wq wq;
        int vnet_hdr_sz;
-       struct macvlan_dev *vlan;
+       struct macvlan_dev __rcu *vlan;
        struct file *file;
        unsigned int flags;
 };
@@ -141,7 +141,8 @@ static void macvtap_put_queue(struct macvtap_queue *q)
        struct macvlan_dev *vlan;
 
        spin_lock(&macvtap_lock);
-       vlan = rcu_dereference(q->vlan);
+       vlan = rcu_dereference_protected(q->vlan,
+                                        lockdep_is_held(&macvtap_lock));
        if (vlan) {
                int index = get_slot(vlan, q);
 
@@ -219,7 +220,8 @@ static void macvtap_del_queues(struct net_device *dev)
        /* macvtap_put_queue can free some slots, so go through all slots */
        spin_lock(&macvtap_lock);
        for (i = 0; i < MAX_MACVTAP_QUEUES && vlan->numvtaps; i++) {
-               q = rcu_dereference(vlan->taps[i]);
+               q = rcu_dereference_protected(vlan->taps[i],
+                                             lockdep_is_held(&macvtap_lock));
                if (q) {
                        qlist[j++] = q;
                        rcu_assign_pointer(vlan->taps[i], NULL);
@@ -570,7 +572,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q,
        }
 
        rcu_read_lock_bh();
-       vlan = rcu_dereference(q->vlan);
+       vlan = rcu_dereference_bh(q->vlan);
        if (vlan)
                macvlan_start_xmit(skb, vlan->dev);
        else
@@ -584,7 +586,7 @@ err_kfree:
 
 err:
        rcu_read_lock_bh();
-       vlan = rcu_dereference(q->vlan);
+       vlan = rcu_dereference_bh(q->vlan);
        if (vlan)
                vlan->dev->stats.tx_dropped++;
        rcu_read_unlock_bh();
@@ -632,7 +634,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
        ret = skb_copy_datagram_const_iovec(skb, 0, iv, vnet_hdr_len, len);
 
        rcu_read_lock_bh();
-       vlan = rcu_dereference(q->vlan);
+       vlan = rcu_dereference_bh(q->vlan);
        if (vlan)
                macvlan_count_rx(vlan, len, ret == 0, 0);
        rcu_read_unlock_bh();
@@ -728,7 +730,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
 
        case TUNGETIFF:
                rcu_read_lock_bh();
-               vlan = rcu_dereference(q->vlan);
+               vlan = rcu_dereference_bh(q->vlan);
                if (vlan)
                        dev_hold(vlan->dev);
                rcu_read_unlock_bh();
@@ -737,7 +739,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
                        return -ENOLINK;
 
                ret = 0;
-               if (copy_to_user(&ifr->ifr_name, q->vlan->dev->name, IFNAMSIZ) ||
+               if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) ||
                    put_user(q->flags, &ifr->ifr_flags))
                        ret = -EFAULT;
                dev_put(vlan->dev);