aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/virtio_net.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 2f6fe9b6b17b..35c00c5ea02a 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -26,6 +26,7 @@
26#include <linux/scatterlist.h> 26#include <linux/scatterlist.h>
27#include <linux/if_vlan.h> 27#include <linux/if_vlan.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/cpu.h>
29 30
30static int napi_weight = 128; 31static int napi_weight = 128;
31module_param(napi_weight, int, 0444); 32module_param(napi_weight, int, 0444);
@@ -126,6 +127,9 @@ struct virtnet_info {
126 127
127 /* Per-cpu variable to show the mapping from CPU to virtqueue */ 128 /* Per-cpu variable to show the mapping from CPU to virtqueue */
128 int __percpu *vq_index; 129 int __percpu *vq_index;
130
131 /* CPU hot plug notifier */
132 struct notifier_block nb;
129}; 133};
130 134
131struct skb_vnet_hdr { 135struct skb_vnet_hdr {
@@ -1067,6 +1071,26 @@ static void virtnet_set_affinity(struct virtnet_info *vi)
1067 vi->affinity_hint_set = true; 1071 vi->affinity_hint_set = true;
1068} 1072}
1069 1073
1074static int virtnet_cpu_callback(struct notifier_block *nfb,
1075 unsigned long action, void *hcpu)
1076{
1077 struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb);
1078
1079 switch(action & ~CPU_TASKS_FROZEN) {
1080 case CPU_ONLINE:
1081 case CPU_DOWN_FAILED:
1082 case CPU_DEAD:
1083 virtnet_set_affinity(vi);
1084 break;
1085 case CPU_DOWN_PREPARE:
1086 virtnet_clean_affinity(vi, (long)hcpu);
1087 break;
1088 default:
1089 break;
1090 }
1091 return NOTIFY_OK;
1092}
1093
1070static void virtnet_get_ringparam(struct net_device *dev, 1094static void virtnet_get_ringparam(struct net_device *dev,
1071 struct ethtool_ringparam *ring) 1095 struct ethtool_ringparam *ring)
1072{ 1096{
@@ -1541,6 +1565,13 @@ static int virtnet_probe(struct virtio_device *vdev)
1541 } 1565 }
1542 } 1566 }
1543 1567
1568 vi->nb.notifier_call = &virtnet_cpu_callback;
1569 err = register_hotcpu_notifier(&vi->nb);
1570 if (err) {
1571 pr_debug("virtio_net: registering cpu notifier failed\n");
1572 goto free_recv_bufs;
1573 }
1574
1544 /* Assume link up if device can't report link status, 1575 /* Assume link up if device can't report link status,
1545 otherwise get link status from config. */ 1576 otherwise get link status from config. */
1546 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { 1577 if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1587,6 +1618,8 @@ static void virtnet_remove(struct virtio_device *vdev)
1587{ 1618{
1588 struct virtnet_info *vi = vdev->priv; 1619 struct virtnet_info *vi = vdev->priv;
1589 1620
1621 unregister_hotcpu_notifier(&vi->nb);
1622
1590 /* Prevent config work handler from accessing the device. */ 1623 /* Prevent config work handler from accessing the device. */
1591 mutex_lock(&vi->config_lock); 1624 mutex_lock(&vi->config_lock);
1592 vi->config_enable = false; 1625 vi->config_enable = false;