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 ---