[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] xen/sched: fix error handling in cpu_schedule_up()
commit 44a7d4f0a5e9eae41a44a162e54ff6d2ebe5b7d6 Author: Juergen Gross <jgross@xxxxxxxx> AuthorDate: Wed Jul 31 14:50:18 2024 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Wed Jul 31 14:50:18 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> --- 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 1a3ff5ae4d..d6296d99fd 100644 --- a/xen/common/sched/core.c +++ b/xen/common/sched/core.c @@ -2756,6 +2756,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; @@ -2795,7 +2825,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; @@ -2813,36 +2846,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#staging
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |