|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen stable-4.18] xen/sched: fix error handling in cpu_schedule_up()
commit bfae66cc4c2d65bb5a788b79e9b3dbd275d096b5
Author: Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Thu Aug 8 13:52:26 2024 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Aug 8 13:52:26 2024 +0200
xen/sched: fix error handling in cpu_schedule_up()
In case cpu_schedule_up() is failing, it needs to undo all externally
visible changes it has done before.
Reason is that cpu_schedule_callback() won't be called with the
CPU_UP_CANCELED notifier in case cpu_schedule_up() did fail.
Fixes: 207589dbacd4 ("xen/sched: move per cpu scheduler private data into
struct sched_resource")
Reported-by: Jan Beulich <jbeulich@xxxxxxxx>
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
master commit: 44a7d4f0a5e9eae41a44a162e54ff6d2ebe5b7d6
master date: 2024-07-31 14:50:18 +0200
---
xen/common/sched/core.c | 63 ++++++++++++++++++++++++++-----------------------
1 file changed, 33 insertions(+), 30 deletions(-)
diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
index 3c2403ebcf..cbaa292bb2 100644
--- a/xen/common/sched/core.c
+++ b/xen/common/sched/core.c
@@ -2760,6 +2760,36 @@ static struct sched_resource *sched_alloc_res(void)
return sr;
}
+static void cf_check sched_res_free(struct rcu_head *head)
+{
+ struct sched_resource *sr = container_of(head, struct sched_resource, rcu);
+
+ free_cpumask_var(sr->cpus);
+ if ( sr->sched_unit_idle )
+ sched_free_unit_mem(sr->sched_unit_idle);
+ xfree(sr);
+}
+
+static void cpu_schedule_down(unsigned int cpu)
+{
+ struct sched_resource *sr;
+
+ rcu_read_lock(&sched_res_rculock);
+
+ sr = get_sched_res(cpu);
+
+ kill_timer(&sr->s_timer);
+
+ cpumask_clear_cpu(cpu, &sched_res_mask);
+ set_sched_res(cpu, NULL);
+
+ /* Keep idle unit. */
+ sr->sched_unit_idle = NULL;
+ call_rcu(&sr->rcu, sched_res_free);
+
+ rcu_read_unlock(&sched_res_rculock);
+}
+
static int cpu_schedule_up(unsigned int cpu)
{
struct sched_resource *sr;
@@ -2799,7 +2829,10 @@ static int cpu_schedule_up(unsigned int cpu)
idle_vcpu[cpu]->sched_unit->res = sr;
if ( idle_vcpu[cpu] == NULL )
+ {
+ cpu_schedule_down(cpu);
return -ENOMEM;
+ }
idle_vcpu[cpu]->sched_unit->rendezvous_in_cnt = 0;
@@ -2817,36 +2850,6 @@ static int cpu_schedule_up(unsigned int cpu)
return 0;
}
-static void cf_check sched_res_free(struct rcu_head *head)
-{
- struct sched_resource *sr = container_of(head, struct sched_resource, rcu);
-
- free_cpumask_var(sr->cpus);
- if ( sr->sched_unit_idle )
- sched_free_unit_mem(sr->sched_unit_idle);
- xfree(sr);
-}
-
-static void cpu_schedule_down(unsigned int cpu)
-{
- struct sched_resource *sr;
-
- rcu_read_lock(&sched_res_rculock);
-
- sr = get_sched_res(cpu);
-
- kill_timer(&sr->s_timer);
-
- cpumask_clear_cpu(cpu, &sched_res_mask);
- set_sched_res(cpu, NULL);
-
- /* Keep idle unit. */
- sr->sched_unit_idle = NULL;
- call_rcu(&sr->rcu, sched_res_free);
-
- rcu_read_unlock(&sched_res_rculock);
-}
-
void sched_rm_cpu(unsigned int cpu)
{
int rc;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.18
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |