Pull cgroup fix from Tejun Heo: "One commit to fix a possible A-A deadlock around u64_stats_sync on 32bit machines caused by updating it without disabling IRQ when it may be read from IRQ context" * 'for-5.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cgroup: rstat: fix A-A deadlock on 32bit around u64_stats_sync
Showing the changes to kernel (1 of 2 files). Show all
Unified · Split
| @@ -347,19 +347,20 @@ static void cgroup_base_stat_flush(struct cgroup *cgrp, int cpu) · 346 unmodified lines | ||
| 347 | 347 | } |
| 348 | 348 | |
| 349 | 349 | static struct cgroup_rstat_cpu * |
| 350 | −cgroup_base_stat_cputime_account_begin(struct cgroup *cgrp) | |
| 350 | +cgroup_base_stat_cputime_account_begin(struct cgroup *cgrp, unsigned long *flags) | |
| 351 | 351 | { |
| 352 | 352 | struct cgroup_rstat_cpu *rstatc; |
| 353 | 353 | |
| 354 | 354 | rstatc = get_cpu_ptr(cgrp->rstat_cpu); |
| 355 | − u64_stats_update_begin(&rstatc->bsync); | |
| 355 | + *flags = u64_stats_update_begin_irqsave(&rstatc->bsync); | |
| 356 | 356 | return rstatc; |
| 357 | 357 | } |
| 358 | 358 | |
| 359 | 359 | static void cgroup_base_stat_cputime_account_end(struct cgroup *cgrp, |
| 360 | − struct cgroup_rstat_cpu *rstatc) | |
| 360 | + struct cgroup_rstat_cpu *rstatc, | |
| 361 | + unsigned long flags) | |
| 361 | 362 | { |
| 362 | − u64_stats_update_end(&rstatc->bsync); | |
| 363 | + u64_stats_update_end_irqrestore(&rstatc->bsync, flags); | |
| 363 | 364 | cgroup_rstat_updated(cgrp, smp_processor_id()); |
| 364 | 365 | put_cpu_ptr(rstatc); |
| 365 | 366 | } |
| @@ -367,18 +368,20 @@ static void cgroup_base_stat_cputime_account_end(struct cgroup *cgrp, · 1 unmodified line | ||
| 367 | 368 | void __cgroup_account_cputime(struct cgroup *cgrp, u64 delta_exec) |
| 368 | 369 | { |
| 369 | 370 | struct cgroup_rstat_cpu *rstatc; |
| 371 | + unsigned long flags; | |
| 370 | 372 | |
| 371 | − rstatc = cgroup_base_stat_cputime_account_begin(cgrp); | |
| 373 | + rstatc = cgroup_base_stat_cputime_account_begin(cgrp, &flags); | |
| 372 | 374 | rstatc->bstat.cputime.sum_exec_runtime += delta_exec; |
| 373 | − cgroup_base_stat_cputime_account_end(cgrp, rstatc); | |
| 375 | + cgroup_base_stat_cputime_account_end(cgrp, rstatc, flags); | |
| 374 | 376 | } |
| 375 | 377 | |
| 376 | 378 | void __cgroup_account_cputime_field(struct cgroup *cgrp, |
| 377 | 379 | enum cpu_usage_stat index, u64 delta_exec) |
| 378 | 380 | { |
| 379 | 381 | struct cgroup_rstat_cpu *rstatc; |
| 382 | + unsigned long flags; | |
| 380 | 383 | |
| 381 | − rstatc = cgroup_base_stat_cputime_account_begin(cgrp); | |
| 384 | + rstatc = cgroup_base_stat_cputime_account_begin(cgrp, &flags); | |
| 382 | 385 | |
| 383 | 386 | switch (index) { |
| 384 | 387 | case CPUTIME_USER: |
| @@ -394,7 +397,7 @@ void __cgroup_account_cputime_field(struct cgroup *cgrp, · 9 unmodified lines | ||
| 394 | 397 | break; |
| 395 | 398 | } |
| 396 | 399 | |
| 397 | − cgroup_base_stat_cputime_account_end(cgrp, rstatc); | |
| 400 | + cgroup_base_stat_cputime_account_end(cgrp, rstatc, flags); | |
| 398 | 401 | } |
| 399 | 402 | |
| 400 | 403 | /* |