From: tip-bot for Sebastian Andrzej Siewior <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: will.deacon@arm.com, linux-kernel@vger.kernel.org,
bigeasy@linutronix.de, peterz@infradead.org, mingo@kernel.org,
mark.rutland@arm.com, mst@redhat.com, tglx@linutronix.de,
hpa@zytor.com
Subject: [tip:smp/hotplug] net/virtio-net: Convert to hotplug state machine
Date: Fri, 2 Sep 2016 11:18:29 -0700 [thread overview]
Message-ID: <tip-8017c279196ab29174bafc104ac4ebbd42c7ca7f@git.kernel.org> (raw)
In-Reply-To: <1471024183-12666-7-git-send-email-bigeasy@linutronix.de>
Commit-ID: 8017c279196ab29174bafc104ac4ebbd42c7ca7f
Gitweb: http://git.kernel.org/tip/8017c279196ab29174bafc104ac4ebbd42c7ca7f
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
AuthorDate: Fri, 12 Aug 2016 19:49:43 +0200
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 2 Sep 2016 20:05:06 +0200
net/virtio-net: Convert to hotplug state machine
Install the callbacks via the state machine.
The driver supports multiple instances and therefore the new
cpuhp_state_add_instance_nocalls() infrastrucure is used. The driver
currently uses get_online_cpus() to avoid missing a CPU hotplug event while
invoking virtnet_set_affinity(). This could be avoided by using
cpuhp_state_add_instance() variant which holds the hotplug lock and invokes
callback during registration. This is more or less a 1:1 conversion of the
current code.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: netdev@vger.kernel.org
Cc: Will Deacon <will.deacon@arm.com>
Cc: virtualization@lists.linux-foundation.org
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/1471024183-12666-7-git-send-email-bigeasy@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
drivers/net/virtio_net.c | 110 +++++++++++++++++++++++++++++++++++----------
include/linux/cpuhotplug.h | 1 +
2 files changed, 87 insertions(+), 24 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 1b5f531..fad84f3 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -138,8 +138,9 @@ struct virtnet_info {
/* Does the affinity hint is set for virtqueues? */
bool affinity_hint_set;
- /* CPU hot plug notifier */
- struct notifier_block nb;
+ /* CPU hotplug instances for online & dead */
+ struct hlist_node node;
+ struct hlist_node node_dead;
/* Control VQ buffers: protected by the rtnl lock */
struct virtio_net_ctrl_hdr ctrl_hdr;
@@ -1237,25 +1238,53 @@ static void virtnet_set_affinity(struct virtnet_info *vi)
vi->affinity_hint_set = true;
}
-static int virtnet_cpu_callback(struct notifier_block *nfb,
- unsigned long action, void *hcpu)
+static int virtnet_cpu_online(unsigned int cpu, struct hlist_node *node)
{
- struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb);
+ struct virtnet_info *vi = hlist_entry_safe(node, struct virtnet_info,
+ node);
+ virtnet_set_affinity(vi);
+ return 0;
+}
- switch(action & ~CPU_TASKS_FROZEN) {
- case CPU_ONLINE:
- case CPU_DOWN_FAILED:
- case CPU_DEAD:
- virtnet_set_affinity(vi);
- break;
- case CPU_DOWN_PREPARE:
- virtnet_clean_affinity(vi, (long)hcpu);
- break;
- default:
- break;
- }
+static int virtnet_cpu_dead(unsigned int cpu, struct hlist_node *node)
+{
+ struct virtnet_info *vi = hlist_entry_safe(node, struct virtnet_info,
+ node_dead);
+ virtnet_set_affinity(vi);
+ return 0;
+}
- return NOTIFY_OK;
+static int virtnet_cpu_down_prep(unsigned int cpu, struct hlist_node *node)
+{
+ struct virtnet_info *vi = hlist_entry_safe(node, struct virtnet_info,
+ node);
+
+ virtnet_clean_affinity(vi, cpu);
+ return 0;
+}
+
+static enum cpuhp_state virtionet_online;
+
+static int virtnet_cpu_notif_add(struct virtnet_info *vi)
+{
+ int ret;
+
+ ret = cpuhp_state_add_instance_nocalls(virtionet_online, &vi->node);
+ if (ret)
+ return ret;
+ ret = cpuhp_state_add_instance_nocalls(CPUHP_VIRT_NET_DEAD,
+ &vi->node_dead);
+ if (!ret)
+ return ret;
+ cpuhp_state_remove_instance_nocalls(virtionet_online, &vi->node);
+ return ret;
+}
+
+static void virtnet_cpu_notif_remove(struct virtnet_info *vi)
+{
+ cpuhp_state_remove_instance_nocalls(virtionet_online, &vi->node);
+ cpuhp_state_remove_instance_nocalls(CPUHP_VIRT_NET_DEAD,
+ &vi->node_dead);
}
static void virtnet_get_ringparam(struct net_device *dev,
@@ -1879,8 +1908,7 @@ static int virtnet_probe(struct virtio_device *vdev)
virtio_device_ready(vdev);
- vi->nb.notifier_call = &virtnet_cpu_callback;
- err = register_hotcpu_notifier(&vi->nb);
+ err = virtnet_cpu_notif_add(vi);
if (err) {
pr_debug("virtio_net: registering cpu notifier failed\n");
goto free_unregister_netdev;
@@ -1934,7 +1962,7 @@ static void virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
- unregister_hotcpu_notifier(&vi->nb);
+ virtnet_cpu_notif_remove(vi);
/* Make sure no work handler is accessing the device. */
flush_work(&vi->config_work);
@@ -1953,7 +1981,7 @@ static int virtnet_freeze(struct virtio_device *vdev)
struct virtnet_info *vi = vdev->priv;
int i;
- unregister_hotcpu_notifier(&vi->nb);
+ virtnet_cpu_notif_remove(vi);
/* Make sure no work handler is accessing the device */
flush_work(&vi->config_work);
@@ -1997,7 +2025,7 @@ static int virtnet_restore(struct virtio_device *vdev)
virtnet_set_queues(vi, vi->curr_queue_pairs);
rtnl_unlock();
- err = register_hotcpu_notifier(&vi->nb);
+ err = virtnet_cpu_notif_add(vi);
if (err)
return err;
@@ -2039,7 +2067,41 @@ static struct virtio_driver virtio_net_driver = {
#endif
};
-module_virtio_driver(virtio_net_driver);
+static __init int virtio_net_driver_init(void)
+{
+ int ret;
+
+ ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "AP_VIRT_NET_ONLINE",
+ virtnet_cpu_online,
+ virtnet_cpu_down_prep);
+ if (ret < 0)
+ goto out;
+ virtionet_online = ret;
+ ret = cpuhp_setup_state_multi(CPUHP_VIRT_NET_DEAD, "VIRT_NET_DEAD",
+ NULL, virtnet_cpu_dead);
+ if (ret)
+ goto err_dead;
+
+ ret = register_virtio_driver(&virtio_net_driver);
+ if (ret)
+ goto err_virtio;
+ return 0;
+err_virtio:
+ cpuhp_remove_multi_state(CPUHP_VIRT_NET_DEAD);
+err_dead:
+ cpuhp_remove_multi_state(virtionet_online);
+out:
+ return ret;
+}
+module_init(virtio_net_driver_init);
+
+static __exit void virtio_net_driver_exit(void)
+{
+ cpuhp_remove_multi_state(CPUHP_VIRT_NET_DEAD);
+ cpuhp_remove_multi_state(virtionet_online);
+ unregister_virtio_driver(&virtio_net_driver);
+}
+module_exit(virtio_net_driver_exit);
MODULE_DEVICE_TABLE(virtio, id_table);
MODULE_DESCRIPTION("Virtio network driver");
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index dcfe6191..b95f7ad 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -14,6 +14,7 @@ enum cpuhp_state {
CPUHP_PERF_SUPERH,
CPUHP_X86_HPET_DEAD,
CPUHP_X86_APB_DEAD,
+ CPUHP_VIRT_NET_DEAD,
CPUHP_WORKQUEUE_PREP,
CPUHP_POWER_NUMA_PREPARE,
CPUHP_HRTIMERS_PREPARE,
prev parent reply other threads:[~2016-09-02 18:19 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-12 17:49 cpu hotplug: add multi instance support Sebastian Andrzej Siewior
2016-08-12 17:49 ` [PATCH 1/6] cpu/hotplug: Rework callback invocation logic Sebastian Andrzej Siewior
2016-09-02 8:22 ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2016-09-02 18:16 ` tip-bot for Thomas Gleixner
2016-08-12 17:49 ` [PATCH 2/6] cpu/hotplug: Add multi instance support Sebastian Andrzej Siewior
2016-09-02 8:22 ` [tip:smp/hotplug] " tip-bot for Thomas Gleixner
2016-09-02 18:16 ` tip-bot for Thomas Gleixner
2016-08-12 17:49 ` [PATCH 3/6] arm/perf: Use multi instance instead of custom list Sebastian Andrzej Siewior
2016-08-17 17:14 ` [PATCH v2 " Sebastian Andrzej Siewior
2016-08-22 15:07 ` Will Deacon
2016-08-22 19:04 ` Sebastian Andrzej Siewior
2016-09-02 8:23 ` [tip:smp/hotplug] " tip-bot for Sebastian Andrzej Siewior
2016-09-02 18:17 ` tip-bot for Sebastian Andrzej Siewior
2016-08-12 17:49 ` [PATCH 4/6] bus/arm-cci: Use cpu-hp's multi instance support instead " Sebastian Andrzej Siewior
2016-09-02 8:23 ` [tip:smp/hotplug] " tip-bot for Sebastian Andrzej Siewior
2016-09-02 18:17 ` tip-bot for Sebastian Andrzej Siewior
2016-08-12 17:49 ` [PATCH 5/6] bus/arm-ccn: " Sebastian Andrzej Siewior
2016-09-02 8:24 ` [tip:smp/hotplug] " tip-bot for Sebastian Andrzej Siewior
2016-09-02 18:18 ` tip-bot for Sebastian Andrzej Siewior
2016-08-12 17:49 ` [PATCH 6/6] net: virtio-net: Convert to hotplug state machine Sebastian Andrzej Siewior
2016-09-02 8:24 ` [tip:smp/hotplug] net/virtio-net: " tip-bot for Sebastian Andrzej Siewior
2016-09-02 18:18 ` tip-bot for Sebastian Andrzej Siewior [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-8017c279196ab29174bafc104ac4ebbd42c7ca7f@git.kernel.org \
--to=tipbot@zytor.com \
--cc=bigeasy@linutronix.de \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@kernel.org \
--cc=mst@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox