Skip to content

Commit e7cc988

Browse files
Waiman-Longhtejun
authored andcommitted
cgroup/cpuset: Enable event notification when partition state changes
A valid cpuset partition can become invalid if all its CPUs are offlined or somehow removed. This can happen through external events without "cpuset.cpus.partition" being touched at all. Users that rely on the property of a partition being present do not currently have a simple way to get such an event notified other than constant periodic polling which is both inefficient and cumbersome. To make life easier for those users, event notification is now enabled for "cpuset.cpus.partition" whenever its state changes. Suggested-by: Tejun Heo <[email protected]> Signed-off-by: Waiman Long <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent b4cc619 commit e7cc988

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed

kernel/cgroup/cpuset.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ struct cpuset {
160160
*/
161161
int use_parent_ecpus;
162162
int child_ecpus_count;
163+
164+
/* Handle for cpuset.cpus.partition */
165+
struct cgroup_file partition_file;
163166
};
164167

165168
/*
@@ -263,6 +266,16 @@ static inline int is_partition_root(const struct cpuset *cs)
263266
return cs->partition_root_state > 0;
264267
}
265268

269+
/*
270+
* Send notification event of whenever partition_root_state changes.
271+
*/
272+
static inline void notify_partition_change(struct cpuset *cs,
273+
int old_prs, int new_prs)
274+
{
275+
if (old_prs != new_prs)
276+
cgroup_file_notify(&cs->partition_file);
277+
}
278+
266279
static struct cpuset top_cpuset = {
267280
.flags = ((1 << CS_ONLINE) | (1 << CS_CPU_EXCLUSIVE) |
268281
(1 << CS_MEM_EXCLUSIVE)),
@@ -1148,7 +1161,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
11481161
struct cpuset *parent = parent_cs(cpuset);
11491162
int adding; /* Moving cpus from effective_cpus to subparts_cpus */
11501163
int deleting; /* Moving cpus from subparts_cpus to effective_cpus */
1151-
int new_prs;
1164+
int old_prs, new_prs;
11521165
bool part_error = false; /* Partition error? */
11531166

11541167
percpu_rwsem_assert_held(&cpuset_rwsem);
@@ -1184,7 +1197,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
11841197
* A cpumask update cannot make parent's effective_cpus become empty.
11851198
*/
11861199
adding = deleting = false;
1187-
new_prs = cpuset->partition_root_state;
1200+
old_prs = new_prs = cpuset->partition_root_state;
11881201
if (cmd == partcmd_enable) {
11891202
cpumask_copy(tmp->addmask, cpuset->cpus_allowed);
11901203
adding = true;
@@ -1274,7 +1287,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
12741287
parent->subparts_cpus);
12751288
}
12761289

1277-
if (!adding && !deleting && (new_prs == cpuset->partition_root_state))
1290+
if (!adding && !deleting && (new_prs == old_prs))
12781291
return 0;
12791292

12801293
/*
@@ -1302,9 +1315,11 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
13021315

13031316
parent->nr_subparts_cpus = cpumask_weight(parent->subparts_cpus);
13041317

1305-
if (cpuset->partition_root_state != new_prs)
1318+
if (old_prs != new_prs)
13061319
cpuset->partition_root_state = new_prs;
1320+
13071321
spin_unlock_irq(&callback_lock);
1322+
notify_partition_change(cpuset, old_prs, new_prs);
13081323

13091324
return cmd == partcmd_update;
13101325
}
@@ -1326,7 +1341,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
13261341
struct cpuset *cp;
13271342
struct cgroup_subsys_state *pos_css;
13281343
bool need_rebuild_sched_domains = false;
1329-
int new_prs;
1344+
int old_prs, new_prs;
13301345

13311346
rcu_read_lock();
13321347
cpuset_for_each_descendant_pre(cp, pos_css, cs) {
@@ -1366,8 +1381,8 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
13661381
* update_tasks_cpumask() again for tasks in the parent
13671382
* cpuset if the parent's subparts_cpus changes.
13681383
*/
1369-
new_prs = cp->partition_root_state;
1370-
if ((cp != cs) && new_prs) {
1384+
old_prs = new_prs = cp->partition_root_state;
1385+
if ((cp != cs) && old_prs) {
13711386
switch (parent->partition_root_state) {
13721387
case PRS_DISABLED:
13731388
/*
@@ -1438,10 +1453,11 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
14381453
}
14391454
}
14401455

1441-
if (new_prs != cp->partition_root_state)
1456+
if (new_prs != old_prs)
14421457
cp->partition_root_state = new_prs;
14431458

14441459
spin_unlock_irq(&callback_lock);
1460+
notify_partition_change(cp, old_prs, new_prs);
14451461

14461462
WARN_ON(!is_in_v2_mode() &&
14471463
!cpumask_equal(cp->cpus_allowed, cp->effective_cpus));
@@ -2023,6 +2039,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
20232039
spin_lock_irq(&callback_lock);
20242040
cs->partition_root_state = new_prs;
20252041
spin_unlock_irq(&callback_lock);
2042+
notify_partition_change(cs, old_prs, new_prs);
20262043
}
20272044

20282045
free_cpumasks(NULL, &tmpmask);
@@ -2708,6 +2725,7 @@ static struct cftype dfl_files[] = {
27082725
.write = sched_partition_write,
27092726
.private = FILE_PARTITION_ROOT,
27102727
.flags = CFTYPE_NOT_ON_ROOT,
2728+
.file_offset = offsetof(struct cpuset, partition_file),
27112729
},
27122730

27132731
{
@@ -3103,11 +3121,17 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
31033121
*/
31043122
if ((parent->partition_root_state == PRS_ERROR) ||
31053123
cpumask_empty(&new_cpus)) {
3124+
int old_prs;
3125+
31063126
update_parent_subparts_cpumask(cs, partcmd_disable,
31073127
NULL, tmp);
3108-
spin_lock_irq(&callback_lock);
3109-
cs->partition_root_state = PRS_ERROR;
3110-
spin_unlock_irq(&callback_lock);
3128+
old_prs = cs->partition_root_state;
3129+
if (old_prs != PRS_ERROR) {
3130+
spin_lock_irq(&callback_lock);
3131+
cs->partition_root_state = PRS_ERROR;
3132+
spin_unlock_irq(&callback_lock);
3133+
notify_partition_change(cs, old_prs, PRS_ERROR);
3134+
}
31113135
}
31123136
cpuset_force_rebuild();
31133137
}

0 commit comments

Comments
 (0)