Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

cgroup/cpuset: record DL BW alloc CPU for attach rollback

cpuset_can_attach() allocates DL bandwidth only when migrating
deadline tasks to a disjoint CPU mask, but cpuset_cancel_attach()
rolls back based only on nr_migrate_dl_tasks. This makes the DL
bandwidth alloc/free paths asymmetric: rollback can call dl_bw_free()
even when no dl_bw_alloc() was done.

Rollback also needs to undo the reservation against the same CPU/root
domain that was charged. Record the CPU used by dl_bw_alloc() and use
that state in cpuset_cancel_attach(). If no allocation happened,
dl_bw_cpu stays at -1 and rollback skips dl_bw_free(). If allocation
did happen, bandwidth is returned to the same CPU/root domain.

Successful attach paths are unchanged. This only fixes failed attach
rollback accounting.

Fixes: 2ef269ef1ac0 ("cgroup/cpuset: Free DL BW in case can_attach() fails")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Reviewed-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

Guopeng Zhang and committed by
Tejun Heo
41d701dd c802f460

+14 -4
+5
kernel/cgroup/cpuset-internal.h
··· 168 168 int nr_deadline_tasks; 169 169 int nr_migrate_dl_tasks; 170 170 u64 sum_migrate_dl_bw; 171 + /* 172 + * CPU used for temporary DL bandwidth allocation during attach; 173 + * -1 if no DL bandwidth was allocated in the current attach. 174 + */ 175 + int dl_bw_cpu; 171 176 172 177 /* Invalid partition error code, not lock protected */ 173 178 enum prs_errcode prs_err;
+9 -4
kernel/cgroup/cpuset.c
··· 288 288 .flags = BIT(CS_CPU_EXCLUSIVE) | 289 289 BIT(CS_MEM_EXCLUSIVE) | BIT(CS_SCHED_LOAD_BALANCE), 290 290 .partition_root_state = PRS_ROOT, 291 + .dl_bw_cpu = -1, 291 292 }; 292 293 293 294 /** ··· 579 578 kzalloc_obj(*cs); 580 579 if (!trial) 581 580 return NULL; 581 + 582 + trial->dl_bw_cpu = -1; 582 583 583 584 /* Setup cpumask pointer array */ 584 585 cpumask_var_t *pmask[4] = { ··· 2983 2980 { 2984 2981 cs->nr_migrate_dl_tasks = 0; 2985 2982 cs->sum_migrate_dl_bw = 0; 2983 + cs->dl_bw_cpu = -1; 2986 2984 } 2987 2985 2988 2986 /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */ ··· 3060 3056 reset_migrate_dl_data(cs); 3061 3057 goto out_unlock; 3062 3058 } 3059 + 3060 + cs->dl_bw_cpu = cpu; 3063 3061 } 3064 3062 3065 3063 out_success: ··· 3086 3080 mutex_lock(&cpuset_mutex); 3087 3081 dec_attach_in_progress_locked(cs); 3088 3082 3089 - if (cs->nr_migrate_dl_tasks) { 3090 - int cpu = cpumask_any(cs->effective_cpus); 3083 + if (cs->dl_bw_cpu >= 0) 3084 + dl_bw_free(cs->dl_bw_cpu, cs->sum_migrate_dl_bw); 3091 3085 3092 - dl_bw_free(cpu, cs->sum_migrate_dl_bw); 3086 + if (cs->nr_migrate_dl_tasks) 3093 3087 reset_migrate_dl_data(cs); 3094 - } 3095 3088 3096 3089 mutex_unlock(&cpuset_mutex); 3097 3090 }