hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/kernel/cgroup/cpuset.c
....@@ -165,6 +165,14 @@
165165 */
166166 int use_parent_ecpus;
167167 int child_ecpus_count;
168
+
169
+ /*
170
+ * number of SCHED_DEADLINE tasks attached to this cpuset, so that we
171
+ * know when to rebuild associated root domain bandwidth information.
172
+ */
173
+ int nr_deadline_tasks;
174
+ int nr_migrate_dl_tasks;
175
+ u64 sum_migrate_dl_bw;
168176 };
169177
170178 /*
....@@ -208,6 +216,20 @@
208216 static inline struct cpuset *parent_cs(struct cpuset *cs)
209217 {
210218 return css_cs(cs->css.parent);
219
+}
220
+
221
+void inc_dl_tasks_cs(struct task_struct *p)
222
+{
223
+ struct cpuset *cs = task_cs(p);
224
+
225
+ cs->nr_deadline_tasks++;
226
+}
227
+
228
+void dec_dl_tasks_cs(struct task_struct *p)
229
+{
230
+ struct cpuset *cs = task_cs(p);
231
+
232
+ cs->nr_deadline_tasks--;
211233 }
212234
213235 /* bits in struct cpuset flags field */
....@@ -339,6 +361,17 @@
339361 */
340362
341363 static DEFINE_MUTEX(cpuset_mutex);
364
+
365
+void cpuset_lock(void)
366
+{
367
+ mutex_lock(&cpuset_mutex);
368
+}
369
+
370
+void cpuset_unlock(void)
371
+{
372
+ mutex_unlock(&cpuset_mutex);
373
+}
374
+
342375 static DEFINE_SPINLOCK(callback_lock);
343376
344377 static struct workqueue_struct *cpuset_migrate_mm_wq;
....@@ -925,10 +958,13 @@
925958 return ndoms;
926959 }
927960
928
-static void update_tasks_root_domain(struct cpuset *cs)
961
+static void dl_update_tasks_root_domain(struct cpuset *cs)
929962 {
930963 struct css_task_iter it;
931964 struct task_struct *task;
965
+
966
+ if (cs->nr_deadline_tasks == 0)
967
+ return;
932968
933969 css_task_iter_start(&cs->css, 0, &it);
934970
....@@ -938,7 +974,7 @@
938974 css_task_iter_end(&it);
939975 }
940976
941
-static void rebuild_root_domains(void)
977
+static void dl_rebuild_rd_accounting(void)
942978 {
943979 struct cpuset *cs = NULL;
944980 struct cgroup_subsys_state *pos_css;
....@@ -966,7 +1002,7 @@
9661002
9671003 rcu_read_unlock();
9681004
969
- update_tasks_root_domain(cs);
1005
+ dl_update_tasks_root_domain(cs);
9701006
9711007 rcu_read_lock();
9721008 css_put(&cs->css);
....@@ -980,7 +1016,7 @@
9801016 {
9811017 mutex_lock(&sched_domains_mutex);
9821018 partition_sched_domains_locked(ndoms_new, doms_new, dattr_new);
983
- rebuild_root_domains();
1019
+ dl_rebuild_rd_accounting();
9841020 mutex_unlock(&sched_domains_mutex);
9851021 }
9861022
....@@ -2171,16 +2207,23 @@
21712207
21722208 static struct cpuset *cpuset_attach_old_cs;
21732209
2210
+static void reset_migrate_dl_data(struct cpuset *cs)
2211
+{
2212
+ cs->nr_migrate_dl_tasks = 0;
2213
+ cs->sum_migrate_dl_bw = 0;
2214
+}
2215
+
21742216 /* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */
21752217 static int cpuset_can_attach(struct cgroup_taskset *tset)
21762218 {
21772219 struct cgroup_subsys_state *css;
2178
- struct cpuset *cs;
2220
+ struct cpuset *cs, *oldcs;
21792221 struct task_struct *task;
21802222 int ret;
21812223
21822224 /* used later by cpuset_attach() */
21832225 cpuset_attach_old_cs = task_cs(cgroup_taskset_first(tset, &css));
2226
+ oldcs = cpuset_attach_old_cs;
21842227 cs = css_cs(css);
21852228
21862229 mutex_lock(&cpuset_mutex);
....@@ -2192,14 +2235,39 @@
21922235 goto out_unlock;
21932236
21942237 cgroup_taskset_for_each(task, css, tset) {
2195
- ret = task_can_attach(task, cs->effective_cpus);
2238
+ ret = task_can_attach(task);
21962239 if (ret)
21972240 goto out_unlock;
21982241 ret = security_task_setscheduler(task);
21992242 if (ret)
22002243 goto out_unlock;
2244
+
2245
+ if (dl_task(task)) {
2246
+ cs->nr_migrate_dl_tasks++;
2247
+ cs->sum_migrate_dl_bw += task->dl.dl_bw;
2248
+ }
22012249 }
22022250
2251
+ if (!cs->nr_migrate_dl_tasks)
2252
+ goto out_success;
2253
+
2254
+ if (!cpumask_intersects(oldcs->effective_cpus, cs->effective_cpus)) {
2255
+ int cpu = cpumask_any_and(cpu_active_mask, cs->effective_cpus);
2256
+
2257
+ if (unlikely(cpu >= nr_cpu_ids)) {
2258
+ reset_migrate_dl_data(cs);
2259
+ ret = -EINVAL;
2260
+ goto out_unlock;
2261
+ }
2262
+
2263
+ ret = dl_bw_alloc(cpu, cs->sum_migrate_dl_bw);
2264
+ if (ret) {
2265
+ reset_migrate_dl_data(cs);
2266
+ goto out_unlock;
2267
+ }
2268
+ }
2269
+
2270
+out_success:
22032271 /*
22042272 * Mark attach is in progress. This makes validate_change() fail
22052273 * changes which zero cpus/mems_allowed.
....@@ -2214,11 +2282,23 @@
22142282 static void cpuset_cancel_attach(struct cgroup_taskset *tset)
22152283 {
22162284 struct cgroup_subsys_state *css;
2285
+ struct cpuset *cs;
22172286
22182287 cgroup_taskset_first(tset, &css);
2288
+ cs = css_cs(css);
22192289
22202290 mutex_lock(&cpuset_mutex);
2221
- css_cs(css)->attach_in_progress--;
2291
+ cs->attach_in_progress--;
2292
+ if (!cs->attach_in_progress)
2293
+ wake_up(&cpuset_attach_wq);
2294
+
2295
+ if (cs->nr_migrate_dl_tasks) {
2296
+ int cpu = cpumask_any(cs->effective_cpus);
2297
+
2298
+ dl_bw_free(cpu, cs->sum_migrate_dl_bw);
2299
+ reset_migrate_dl_data(cs);
2300
+ }
2301
+
22222302 mutex_unlock(&cpuset_mutex);
22232303 }
22242304
....@@ -2291,6 +2371,12 @@
22912371
22922372 cs->old_mems_allowed = cpuset_attach_nodemask_to;
22932373
2374
+ if (cs->nr_migrate_dl_tasks) {
2375
+ cs->nr_deadline_tasks += cs->nr_migrate_dl_tasks;
2376
+ oldcs->nr_deadline_tasks -= cs->nr_migrate_dl_tasks;
2377
+ reset_migrate_dl_data(cs);
2378
+ }
2379
+
22942380 cs->attach_in_progress--;
22952381 if (!cs->attach_in_progress)
22962382 wake_up(&cpuset_attach_wq);