As M.S.T mentioned, set affinity will not work very well when
CPU IDs are not consecutive, this can happen with hot unplug.
Fix this bug by traversal the online CPUs.
Cc: Rusty Russell <redacted>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <redacted>
Cc: Eric Dumazet <redacted>
Cc: virtualization@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Signed-off-by: Wanlong Gao <redacted>
---
drivers/net/virtio_net.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
@@ -1016,6 +1016,7 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)staticvoidvirtnet_set_affinity(structvirtnet_info*vi,boolset){inti;+intcpu;/* In multiqueue mode, when the number of cpu is equal to the number of*queuepairs,weletthequeuepairstobeprivatetoonecpuby
Add a cpu notifier to virtio-net, so that we can reset the
virtqueue affinity if the cpu hotplug happens. It improve
the performance through enabling or disabling the virtqueue
affinity after doing cpu hotplug.
Adding the notifier block to virtnet_info is suggested by
Jason, thank you.
Cc: Rusty Russell <redacted>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <redacted>
Cc: Eric Dumazet <redacted>
Cc: virtualization@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Signed-off-by: Wanlong Gao <redacted>
---
drivers/net/virtio_net.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
@@ -123,6 +124,9 @@ struct virtnet_info {/* Does the affinity hint is set for virtqueues? */boolaffinity_hint_set;++/* CPU hot plug notifier */+structnotifier_blocknb;};structskb_vnet_hdr{
@@ -1509,6 +1530,13 @@ static int virtnet_probe(struct virtio_device *vdev)}}+vi->nb.notifier_call=&virtnet_cpu_callback;+err=register_hotcpu_notifier(&vi->nb);+if(err){+pr_debug("virtio_net: registering cpu notifier failed\n");+gotofree_recv_bufs;+}+/* Assume link up if device can't report link status,otherwisegetlinkstatusfromconfig.*/if(virtio_has_feature(vi->vdev,VIRTIO_NET_F_STATUS)){
@@ -1553,6 +1581,8 @@ static void virtnet_remove(struct virtio_device *vdev){structvirtnet_info*vi=vdev->priv;+unregister_hotcpu_notifier(&vi->nb);+/* Prevent config work handler from accessing the device. */mutex_lock(&vi->config_lock);vi->config_enable=false;
From: Jason Wang <hidden> Date: 2013-01-07 07:29:12
On 01/07/2013 03:15 PM, Wanlong Gao wrote:
quoted hunk
Add a cpu notifier to virtio-net, so that we can reset the
virtqueue affinity if the cpu hotplug happens. It improve
the performance through enabling or disabling the virtqueue
affinity after doing cpu hotplug.
Adding the notifier block to virtnet_info is suggested by
Jason, thank you.
Cc: Rusty Russell <redacted>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <redacted>
Cc: Eric Dumazet <redacted>
Cc: virtualization@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Signed-off-by: Wanlong Gao <redacted>
---
drivers/net/virtio_net.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
@@ -123,6 +124,9 @@ struct virtnet_info {/* Does the affinity hint is set for virtqueues? */boolaffinity_hint_set;++/* CPU hot plug notifier */+structnotifier_blocknb;};structskb_vnet_hdr{
I think you'd better fix the .ndo_select_queue() as well (as Michael
said in your V1) since it currently uses smp processor id which may not
work very well in this case also.
Thanks
@@ -1509,6 +1530,13 @@ static int virtnet_probe(struct virtio_device *vdev) } }+ vi->nb.notifier_call = &virtnet_cpu_callback;+ err = register_hotcpu_notifier(&vi->nb);+ if (err) {+ pr_debug("virtio_net: registering cpu notifier failed\n");+ goto free_recv_bufs;+ }+ /* Assume link up if device can't report link status, otherwise get link status from config. */ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1553,6 +1581,8 @@ static void virtnet_remove(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv;+ unregister_hotcpu_notifier(&vi->nb);+ /* Prevent config work handler from accessing the device. */ mutex_lock(&vi->config_lock); vi->config_enable = false;
Add a cpu notifier to virtio-net, so that we can reset the
virtqueue affinity if the cpu hotplug happens. It improve
the performance through enabling or disabling the virtqueue
affinity after doing cpu hotplug.
Adding the notifier block to virtnet_info is suggested by
Jason, thank you.
Cc: Rusty Russell <redacted>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <redacted>
Cc: Eric Dumazet <redacted>
Cc: virtualization@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Signed-off-by: Wanlong Gao <redacted>
---
drivers/net/virtio_net.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
@@ -123,6 +124,9 @@ struct virtnet_info {/* Does the affinity hint is set for virtqueues? */boolaffinity_hint_set;++/* CPU hot plug notifier */+structnotifier_blocknb;};structskb_vnet_hdr{
I think you'd better fix the .ndo_select_queue() as well (as Michael
said in your V1) since it currently uses smp processor id which may not
work very well in this case also.
The bug is we can't get the right txq if the CPU IDs are not consecutive,
right? Do you have any good idea about fixing this?
Thanks,
Wanlong Gao
@@ -1509,6 +1530,13 @@ static int virtnet_probe(struct virtio_device *vdev) } }+ vi->nb.notifier_call = &virtnet_cpu_callback;+ err = register_hotcpu_notifier(&vi->nb);+ if (err) {+ pr_debug("virtio_net: registering cpu notifier failed\n");+ goto free_recv_bufs;+ }+ /* Assume link up if device can't report link status, otherwise get link status from config. */ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1553,6 +1581,8 @@ static void virtnet_remove(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv;+ unregister_hotcpu_notifier(&vi->nb);+ /* Prevent config work handler from accessing the device. */ mutex_lock(&vi->config_lock); vi->config_enable = false;
From: Jason Wang <hidden> Date: 2013-01-07 07:55:26
On 01/07/2013 03:48 PM, Wanlong Gao wrote:
On 01/07/2013 03:28 PM, Jason Wang wrote:
quoted
On 01/07/2013 03:15 PM, Wanlong Gao wrote:
quoted
Add a cpu notifier to virtio-net, so that we can reset the
virtqueue affinity if the cpu hotplug happens. It improve
the performance through enabling or disabling the virtqueue
affinity after doing cpu hotplug.
Adding the notifier block to virtnet_info is suggested by
Jason, thank you.
Cc: Rusty Russell <redacted>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <redacted>
Cc: Eric Dumazet <redacted>
Cc: virtualization@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Signed-off-by: Wanlong Gao <redacted>
---
drivers/net/virtio_net.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
@@ -123,6 +124,9 @@ struct virtnet_info {/* Does the affinity hint is set for virtqueues? */boolaffinity_hint_set;++/* CPU hot plug notifier */+structnotifier_blocknb;};structskb_vnet_hdr{
I think you'd better fix the .ndo_select_queue() as well (as Michael
said in your V1) since it currently uses smp processor id which may not
work very well in this case also.
The bug is we can't get the right txq if the CPU IDs are not consecutive,
right? Do you have any good idea about fixing this?
Thanks,
Wanlong Gao
The point is make the virtqueue private to a specific cpu when the
number of queue pairs is equal to the number of cpus. So after you bind
the vq affinity to a specific cpu, you'd better use the reverse mapping
of this affinity to do .ndo_select_queue(). One possible idea, as
Michael suggested, is a per-cpu structure to record the preferable
virtqueue and do both .ndo_select_queue() and affinity hint setting
based on this.
@@ -1509,6 +1530,13 @@ static int virtnet_probe(struct virtio_device *vdev) } }+ vi->nb.notifier_call = &virtnet_cpu_callback;+ err = register_hotcpu_notifier(&vi->nb);+ if (err) {+ pr_debug("virtio_net: registering cpu notifier failed\n");+ goto free_recv_bufs;+ }+ /* Assume link up if device can't report link status, otherwise get link status from config. */ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1553,6 +1581,8 @@ static void virtnet_remove(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv;+ unregister_hotcpu_notifier(&vi->nb);+ /* Prevent config work handler from accessing the device. */ mutex_lock(&vi->config_lock); vi->config_enable = false;
Add a cpu notifier to virtio-net, so that we can reset the
virtqueue affinity if the cpu hotplug happens. It improve
the performance through enabling or disabling the virtqueue
affinity after doing cpu hotplug.
Adding the notifier block to virtnet_info is suggested by
Jason, thank you.
Cc: Rusty Russell <redacted>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <redacted>
Cc: Eric Dumazet <redacted>
Cc: virtualization@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Signed-off-by: Wanlong Gao <redacted>
---
drivers/net/virtio_net.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
@@ -123,6 +124,9 @@ struct virtnet_info {/* Does the affinity hint is set for virtqueues? */boolaffinity_hint_set;++/* CPU hot plug notifier */+structnotifier_blocknb;};structskb_vnet_hdr{
I think you'd better fix the .ndo_select_queue() as well (as Michael
said in your V1) since it currently uses smp processor id which may not
work very well in this case also.
The bug is we can't get the right txq if the CPU IDs are not consecutive,
right? Do you have any good idea about fixing this?
Thanks,
Wanlong Gao
The point is make the virtqueue private to a specific cpu when the
number of queue pairs is equal to the number of cpus. So after you bind
the vq affinity to a specific cpu, you'd better use the reverse mapping
of this affinity to do .ndo_select_queue(). One possible idea, as
Michael suggested, is a per-cpu structure to record the preferable
virtqueue and do both .ndo_select_queue() and affinity hint setting
based on this.
Yeah, I think I got it now, will address it in V3. thank you. ;)
Regards,
Wanlong Gao
@@ -1509,6 +1530,13 @@ static int virtnet_probe(struct virtio_device *vdev) } }+ vi->nb.notifier_call = &virtnet_cpu_callback;+ err = register_hotcpu_notifier(&vi->nb);+ if (err) {+ pr_debug("virtio_net: registering cpu notifier failed\n");+ goto free_recv_bufs;+ }+ /* Assume link up if device can't report link status, otherwise get link status from config. */ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1553,6 +1581,8 @@ static void virtnet_remove(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv;+ unregister_hotcpu_notifier(&vi->nb);+ /* Prevent config work handler from accessing the device. */ mutex_lock(&vi->config_lock); vi->config_enable = false;