virtio_net.c (47be24796c13e7d9f087005c2bedc68ee0709f7b) | virtio_net.c (8898c21cf37d04041863e7ecf53707dff504bda0) |
---|---|
1/* A network driver using virtio. 2 * 3 * Copyright 2007 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. --- 1002 unchanged lines hidden (view full) --- 1011 sg_init_one(&sg, &vid, sizeof(vid)); 1012 1013 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, 1014 VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0)) 1015 dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid); 1016 return 0; 1017} 1018 | 1/* A network driver using virtio. 2 * 3 * Copyright 2007 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. --- 1002 unchanged lines hidden (view full) --- 1011 sg_init_one(&sg, &vid, sizeof(vid)); 1012 1013 if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, 1014 VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0)) 1015 dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid); 1016 return 0; 1017} 1018 |
1019static void virtnet_set_affinity(struct virtnet_info *vi, bool set) | 1019static void virtnet_clean_affinity(struct virtnet_info *vi, long hcpu) |
1020{ 1021 int i; 1022 int cpu; 1023 | 1020{ 1021 int i; 1022 int cpu; 1023 |
1024 /* In multiqueue mode, when the number of cpu is equal to the number of 1025 * queue pairs, we let the queue pairs to be private to one cpu by 1026 * setting the affinity hint to eliminate the contention. 1027 */ 1028 if ((vi->curr_queue_pairs == 1 || 1029 vi->max_queue_pairs != num_online_cpus()) && set) { 1030 if (vi->affinity_hint_set) { 1031 set = false; 1032 } else { 1033 i = 0; 1034 for_each_online_cpu(cpu) 1035 *per_cpu_ptr(vi->vq_index, cpu) = 1036 ++i % vi->curr_queue_pairs; 1037 return; 1038 } 1039 } 1040 1041 if (set) { 1042 i = 0; 1043 for_each_online_cpu(cpu) { 1044 virtqueue_set_affinity(vi->rq[i].vq, cpu); 1045 virtqueue_set_affinity(vi->sq[i].vq, cpu); 1046 *per_cpu_ptr(vi->vq_index, cpu) = i; 1047 i++; 1048 } 1049 1050 vi->affinity_hint_set = true; 1051 } else { 1052 for(i = 0; i < vi->max_queue_pairs; i++) { | 1024 if (vi->affinity_hint_set) { 1025 for (i = 0; i < vi->max_queue_pairs; i++) { |
1053 virtqueue_set_affinity(vi->rq[i].vq, -1); 1054 virtqueue_set_affinity(vi->sq[i].vq, -1); 1055 } 1056 | 1026 virtqueue_set_affinity(vi->rq[i].vq, -1); 1027 virtqueue_set_affinity(vi->sq[i].vq, -1); 1028 } 1029 |
1057 i = 0; 1058 for_each_online_cpu(cpu) | 1030 vi->affinity_hint_set = false; 1031 } 1032 1033 i = 0; 1034 for_each_online_cpu(cpu) { 1035 if (cpu == hcpu) { 1036 *per_cpu_ptr(vi->vq_index, cpu) = -1; 1037 } else { |
1059 *per_cpu_ptr(vi->vq_index, cpu) = 1060 ++i % vi->curr_queue_pairs; | 1038 *per_cpu_ptr(vi->vq_index, cpu) = 1039 ++i % vi->curr_queue_pairs; |
1040 } 1041 } 1042} |
|
1061 | 1043 |
1062 vi->affinity_hint_set = false; | 1044static void virtnet_set_affinity(struct virtnet_info *vi) 1045{ 1046 int i; 1047 int cpu; 1048 1049 /* In multiqueue mode, when the number of cpu is equal to the number of 1050 * queue pairs, we let the queue pairs to be private to one cpu by 1051 * setting the affinity hint to eliminate the contention. 1052 */ 1053 if (vi->curr_queue_pairs == 1 || 1054 vi->max_queue_pairs != num_online_cpus()) { 1055 virtnet_clean_affinity(vi, -1); 1056 return; |
1063 } | 1057 } |
1058 1059 i = 0; 1060 for_each_online_cpu(cpu) { 1061 virtqueue_set_affinity(vi->rq[i].vq, cpu); 1062 virtqueue_set_affinity(vi->sq[i].vq, cpu); 1063 *per_cpu_ptr(vi->vq_index, cpu) = i; 1064 i++; 1065 } 1066 1067 vi->affinity_hint_set = true; |
|
1064} 1065 1066static void virtnet_get_ringparam(struct net_device *dev, 1067 struct ethtool_ringparam *ring) 1068{ 1069 struct virtnet_info *vi = netdev_priv(dev); 1070 1071 ring->rx_max_pending = virtqueue_get_vring_size(vi->rq[0].vq); --- 33 unchanged lines hidden (view full) --- 1105 return -EINVAL; 1106 1107 get_online_cpus(); 1108 err = virtnet_set_queues(vi, queue_pairs); 1109 if (!err) { 1110 netif_set_real_num_tx_queues(dev, queue_pairs); 1111 netif_set_real_num_rx_queues(dev, queue_pairs); 1112 | 1068} 1069 1070static void virtnet_get_ringparam(struct net_device *dev, 1071 struct ethtool_ringparam *ring) 1072{ 1073 struct virtnet_info *vi = netdev_priv(dev); 1074 1075 ring->rx_max_pending = virtqueue_get_vring_size(vi->rq[0].vq); --- 33 unchanged lines hidden (view full) --- 1109 return -EINVAL; 1110 1111 get_online_cpus(); 1112 err = virtnet_set_queues(vi, queue_pairs); 1113 if (!err) { 1114 netif_set_real_num_tx_queues(dev, queue_pairs); 1115 netif_set_real_num_rx_queues(dev, queue_pairs); 1116 |
1113 virtnet_set_affinity(vi, true); | 1117 virtnet_set_affinity(vi); |
1114 } 1115 put_online_cpus(); 1116 1117 return err; 1118} 1119 1120static void virtnet_get_channels(struct net_device *dev, 1121 struct ethtool_channels *channels) --- 152 unchanged lines hidden (view full) --- 1274 BUG_ON(vi->rq[i].num != 0); 1275 } 1276} 1277 1278static void virtnet_del_vqs(struct virtnet_info *vi) 1279{ 1280 struct virtio_device *vdev = vi->vdev; 1281 | 1118 } 1119 put_online_cpus(); 1120 1121 return err; 1122} 1123 1124static void virtnet_get_channels(struct net_device *dev, 1125 struct ethtool_channels *channels) --- 152 unchanged lines hidden (view full) --- 1278 BUG_ON(vi->rq[i].num != 0); 1279 } 1280} 1281 1282static void virtnet_del_vqs(struct virtnet_info *vi) 1283{ 1284 struct virtio_device *vdev = vi->vdev; 1285 |
1282 virtnet_set_affinity(vi, false); | 1286 virtnet_clean_affinity(vi, -1); |
1283 1284 vdev->config->del_vqs(vdev); 1285 1286 virtnet_free_queues(vi); 1287} 1288 1289static int virtnet_find_vqs(struct virtnet_info *vi) 1290{ --- 107 unchanged lines hidden (view full) --- 1398 if (ret) 1399 goto err; 1400 1401 ret = virtnet_find_vqs(vi); 1402 if (ret) 1403 goto err_free; 1404 1405 get_online_cpus(); | 1287 1288 vdev->config->del_vqs(vdev); 1289 1290 virtnet_free_queues(vi); 1291} 1292 1293static int virtnet_find_vqs(struct virtnet_info *vi) 1294{ --- 107 unchanged lines hidden (view full) --- 1402 if (ret) 1403 goto err; 1404 1405 ret = virtnet_find_vqs(vi); 1406 if (ret) 1407 goto err_free; 1408 1409 get_online_cpus(); |
1406 virtnet_set_affinity(vi, true); | 1410 virtnet_set_affinity(vi); |
1407 put_online_cpus(); 1408 1409 return 0; 1410 1411err_free: 1412 virtnet_free_queues(vi); 1413err: 1414 return ret; --- 289 unchanged lines hidden --- | 1411 put_online_cpus(); 1412 1413 return 0; 1414 1415err_free: 1416 virtnet_free_queues(vi); 1417err: 1418 return ret; --- 289 unchanged lines hidden --- |