From: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
To: linux-hyperv@vger.kernel.org
Cc: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>,
Boqun Feng <boqun.feng@gmail.com>, Wei Liu <wei.liu@kernel.org>,
"K. Y. Srinivasan" <kys@microsoft.com>,
Haiyang Zhang <haiyangz@microsoft.com>,
Dexuan Cui <decui@microsoft.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 2/2] drivers/hv: add CPU offlining support
Date: Fri, 10 Jan 2025 16:59:50 -0500 [thread overview]
Message-ID: <20250110215951.175514-2-hamzamahfooz@linux.microsoft.com> (raw)
In-Reply-To: <20250110215951.175514-1-hamzamahfooz@linux.microsoft.com>
Currently, it is effectively impossible to offline CPUs. Since, most
CPUs will have vmbus channels attached to them. So, as made mention of
in commit d570aec0f2154 ("Drivers: hv: vmbus: Synchronize
init_vp_index() vs. CPU hotplug"), rebind channels associated with CPUs
that a user is trying to offline to a new "randomly" selected CPU.
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
---
v2: remove cpus_read_{un,}lock() from hv_pick_new_cpu() and add
lockdep_assert_cpus_held().
---
drivers/hv/hv.c | 56 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 41 insertions(+), 15 deletions(-)
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 36d9ba097ff5..9fef71403c86 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -433,13 +433,39 @@ static bool hv_synic_event_pending(void)
return pending;
}
+static int hv_pick_new_cpu(struct vmbus_channel *channel,
+ unsigned int current_cpu)
+{
+ int ret = 0;
+ int cpu;
+
+ lockdep_assert_cpus_held();
+ lockdep_assert_held(&vmbus_connection.channel_mutex);
+
+ /*
+ * We can't assume that the relevant interrupts will be sent before
+ * the cpu is offlined on older versions of hyperv.
+ */
+ if (vmbus_proto_version < VERSION_WIN10_V5_3)
+ return -EBUSY;
+
+ cpu = cpumask_next(get_random_u32_below(nr_cpu_ids), cpu_online_mask);
+
+ if (cpu >= nr_cpu_ids || cpu == current_cpu)
+ cpu = VMBUS_CONNECT_CPU;
+
+ ret = vmbus_channel_set_cpu(channel, cpu);
+
+ return ret;
+}
+
/*
* hv_synic_cleanup - Cleanup routine for hv_synic_init().
*/
int hv_synic_cleanup(unsigned int cpu)
{
struct vmbus_channel *channel, *sc;
- bool channel_found = false;
+ int ret = 0;
if (vmbus_connection.conn_state != CONNECTED)
goto always_cleanup;
@@ -456,31 +482,31 @@ int hv_synic_cleanup(unsigned int cpu)
/*
* Search for channels which are bound to the CPU we're about to
- * cleanup. In case we find one and vmbus is still connected, we
- * fail; this will effectively prevent CPU offlining.
- *
- * TODO: Re-bind the channels to different CPUs.
+ * cleanup.
*/
mutex_lock(&vmbus_connection.channel_mutex);
list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
if (channel->target_cpu == cpu) {
- channel_found = true;
- break;
+ ret = hv_pick_new_cpu(channel, cpu);
+
+ if (ret) {
+ mutex_unlock(&vmbus_connection.channel_mutex);
+ return ret;
+ }
}
list_for_each_entry(sc, &channel->sc_list, sc_list) {
if (sc->target_cpu == cpu) {
- channel_found = true;
- break;
+ ret = hv_pick_new_cpu(channel, cpu);
+
+ if (ret) {
+ mutex_unlock(&vmbus_connection.channel_mutex);
+ return ret;
+ }
}
}
- if (channel_found)
- break;
}
mutex_unlock(&vmbus_connection.channel_mutex);
- if (channel_found)
- return -EBUSY;
-
/*
* channel_found == false means that any channels that were previously
* assigned to the CPU have been reassigned elsewhere with a call of
@@ -497,5 +523,5 @@ int hv_synic_cleanup(unsigned int cpu)
hv_synic_disable_regs(cpu);
- return 0;
+ return ret;
}
--
2.47.1
next prev parent reply other threads:[~2025-01-10 22:00 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-10 21:59 [PATCH v2 1/2] drivers/hv: introduce vmbus_channel_set_cpu() Hamza Mahfooz
2025-01-10 21:59 ` Hamza Mahfooz [this message]
2025-01-14 2:43 ` [PATCH v2 2/2] drivers/hv: add CPU offlining support Michael Kelley
2025-01-15 17:22 ` Hamza Mahfooz
2025-01-15 21:02 ` Michael Kelley
2025-01-13 13:01 ` [PATCH v2 1/2] drivers/hv: introduce vmbus_channel_set_cpu() kernel test robot
2025-01-14 2:43 ` Michael Kelley
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=20250110215951.175514-2-hamzamahfooz@linux.microsoft.com \
--to=hamzamahfooz@linux.microsoft.com \
--cc=boqun.feng@gmail.com \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=kys@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=wei.liu@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.