diff options
author | Wanlong Gao <gaowanlong@cn.fujitsu.com> | 2013-01-24 18:51:30 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-27 01:22:51 -0500 |
commit | 8898c21cf37d04041863e7ecf53707dff504bda0 (patch) | |
tree | 0be8fed3a644ffdb86ba349bab442bdda9ddb328 /drivers/net/virtio_net.c | |
parent | 47be24796c13e7d9f087005c2bedc68ee0709f7b (diff) |
virtio-net: split out clean affinity function
Split out the clean affinity function to virtnet_clean_affinity().
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Eric Dumazet <erdnetdev@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: virtualization@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 76 |
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 | ||
1019 | static void virtnet_set_affinity(struct virtnet_info *vi, bool set) | 1019 | static 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; | 1044 | static 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 | ||
1066 | static void virtnet_get_ringparam(struct net_device *dev, | 1070 | static 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; |