]> Pileus Git - ~andy/linux/blobdiff - drivers/net/virtio_net.c
net: Explicitly initialize u64_stats_sync structures for lockdep
[~andy/linux] / drivers / net / virtio_net.c
index defec2b3c5a408ff035889d015d717f040e2864c..ee384f3d612b2b576d0e10e617f08aa3bd6737cd 100644 (file)
@@ -938,7 +938,9 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
                return -EINVAL;
        } else {
                vi->curr_queue_pairs = queue_pairs;
-               schedule_delayed_work(&vi->refill, 0);
+               /* virtnet_open() will refill when device is going to up. */
+               if (dev->flags & IFF_UP)
+                       schedule_delayed_work(&vi->refill, 0);
        }
 
        return 0;
@@ -1116,6 +1118,11 @@ static int virtnet_cpu_callback(struct notifier_block *nfb,
 {
        struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb);
 
+       mutex_lock(&vi->config_lock);
+
+       if (!vi->config_enable)
+               goto done;
+
        switch(action & ~CPU_TASKS_FROZEN) {
        case CPU_ONLINE:
        case CPU_DOWN_FAILED:
@@ -1128,6 +1135,9 @@ static int virtnet_cpu_callback(struct notifier_block *nfb,
        default:
                break;
        }
+
+done:
+       mutex_unlock(&vi->config_lock);
        return NOTIFY_OK;
 }
 
@@ -1559,6 +1569,14 @@ static int virtnet_probe(struct virtio_device *vdev)
        if (vi->stats == NULL)
                goto free;
 
+       for_each_possible_cpu(i) {
+               struct virtnet_stats *virtnet_stats;
+               virtnet_stats = per_cpu_ptr(vi->stats, i);
+               u64_stats_init(&virtnet_stats->tx_syncp);
+               u64_stats_init(&virtnet_stats->rx_syncp);
+       }
+
+
        vi->vq_index = alloc_percpu(int);
        if (vi->vq_index == NULL)
                goto free_stats;
@@ -1733,7 +1751,9 @@ static int virtnet_restore(struct virtio_device *vdev)
        vi->config_enable = true;
        mutex_unlock(&vi->config_lock);
 
+       rtnl_lock();
        virtnet_set_queues(vi, vi->curr_queue_pairs);
+       rtnl_unlock();
 
        return 0;
 }