aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c76
1 files changed, 40 insertions, 36 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fda214a5426a..2f6fe9b6b17b 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1016,51 +1016,55 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
1016 return 0; 1016 return 0;
1017} 1017}
1018 1018
1019static void virtnet_set_affinity(struct virtnet_info *vi, bool set) 1019static void virtnet_clean_affinity(struct virtnet_info *vi, long hcpu)
1020{ 1020{
1021 int i; 1021 int i;
1022 int cpu; 1022 int cpu;
1023 1023
1024 /* In multiqueue mode, when the number of cpu is equal to the number of 1024 if (vi->affinity_hint_set) {
1025 * queue pairs, we let the queue pairs to be private to one cpu by 1025 for (i = 0; i < vi->max_queue_pairs; i++) {
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++) {
1053 virtqueue_set_affinity(vi->rq[i].vq, -1); 1026 virtqueue_set_affinity(vi->rq[i].vq, -1);
1054 virtqueue_set_affinity(vi->sq[i].vq, -1); 1027 virtqueue_set_affinity(vi->sq[i].vq, -1);
1055 } 1028 }
1056 1029
1057 i = 0; 1030 vi->affinity_hint_set = false;
1058 for_each_online_cpu(cpu) 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) = 1038 *per_cpu_ptr(vi->vq_index, cpu) =
1060 ++i % vi->curr_queue_pairs; 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} 1068}
1065 1069
1066static void virtnet_get_ringparam(struct net_device *dev, 1070static void virtnet_get_ringparam(struct net_device *dev,
@@ -1110,7 +1114,7 @@ static int virtnet_set_channels(struct net_device *dev,
1110 netif_set_real_num_tx_queues(dev, queue_pairs); 1114 netif_set_real_num_tx_queues(dev, queue_pairs);
1111 netif_set_real_num_rx_queues(dev, queue_pairs); 1115 netif_set_real_num_rx_queues(dev, queue_pairs);
1112 1116
1113 virtnet_set_affinity(vi, true); 1117 virtnet_set_affinity(vi);
1114 } 1118 }
1115 put_online_cpus(); 1119 put_online_cpus();
1116 1120
@@ -1279,7 +1283,7 @@ static void virtnet_del_vqs(struct virtnet_info *vi)
1279{ 1283{
1280 struct virtio_device *vdev = vi->vdev; 1284 struct virtio_device *vdev = vi->vdev;
1281 1285
1282 virtnet_set_affinity(vi, false); 1286 virtnet_clean_affinity(vi, -1);
1283 1287
1284 vdev->config->del_vqs(vdev); 1288 vdev->config->del_vqs(vdev);
1285 1289
@@ -1403,7 +1407,7 @@ static int init_vqs(struct virtnet_info *vi)
1403 goto err_free; 1407 goto err_free;
1404 1408
1405 get_online_cpus(); 1409 get_online_cpus();
1406 virtnet_set_affinity(vi, true); 1410 virtnet_set_affinity(vi);
1407 put_online_cpus(); 1411 put_online_cpus();
1408 1412
1409 return 0; 1413 return 0;