mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 06:41:39 -04:00
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: 2ef269ef1a ("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>
This commit is contained in:
@@ -168,6 +168,11 @@ struct cpuset {
|
||||
int nr_deadline_tasks;
|
||||
int nr_migrate_dl_tasks;
|
||||
u64 sum_migrate_dl_bw;
|
||||
/*
|
||||
* CPU used for temporary DL bandwidth allocation during attach;
|
||||
* -1 if no DL bandwidth was allocated in the current attach.
|
||||
*/
|
||||
int dl_bw_cpu;
|
||||
|
||||
/* Invalid partition error code, not lock protected */
|
||||
enum prs_errcode prs_err;
|
||||
|
||||
@@ -288,6 +288,7 @@ struct cpuset top_cpuset = {
|
||||
.flags = BIT(CS_CPU_EXCLUSIVE) |
|
||||
BIT(CS_MEM_EXCLUSIVE) | BIT(CS_SCHED_LOAD_BALANCE),
|
||||
.partition_root_state = PRS_ROOT,
|
||||
.dl_bw_cpu = -1,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -579,6 +580,8 @@ static struct cpuset *dup_or_alloc_cpuset(struct cpuset *cs)
|
||||
if (!trial)
|
||||
return NULL;
|
||||
|
||||
trial->dl_bw_cpu = -1;
|
||||
|
||||
/* Setup cpumask pointer array */
|
||||
cpumask_var_t *pmask[4] = {
|
||||
&trial->cpus_allowed,
|
||||
@@ -2980,6 +2983,7 @@ static void reset_migrate_dl_data(struct cpuset *cs)
|
||||
{
|
||||
cs->nr_migrate_dl_tasks = 0;
|
||||
cs->sum_migrate_dl_bw = 0;
|
||||
cs->dl_bw_cpu = -1;
|
||||
}
|
||||
|
||||
/* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */
|
||||
@@ -3056,6 +3060,8 @@ static int cpuset_can_attach(struct cgroup_taskset *tset)
|
||||
reset_migrate_dl_data(cs);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
cs->dl_bw_cpu = cpu;
|
||||
}
|
||||
|
||||
out_success:
|
||||
@@ -3080,12 +3086,11 @@ static void cpuset_cancel_attach(struct cgroup_taskset *tset)
|
||||
mutex_lock(&cpuset_mutex);
|
||||
dec_attach_in_progress_locked(cs);
|
||||
|
||||
if (cs->nr_migrate_dl_tasks) {
|
||||
int cpu = cpumask_any(cs->effective_cpus);
|
||||
if (cs->dl_bw_cpu >= 0)
|
||||
dl_bw_free(cs->dl_bw_cpu, cs->sum_migrate_dl_bw);
|
||||
|
||||
dl_bw_free(cpu, cs->sum_migrate_dl_bw);
|
||||
if (cs->nr_migrate_dl_tasks)
|
||||
reset_migrate_dl_data(cs);
|
||||
}
|
||||
|
||||
mutex_unlock(&cpuset_mutex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user