Pull PSI updates from Ingo Molnar: - Various performance optimizations, resulting in a 4%-9% speedup in the mmtests/config-scheduler-perfpipe micro-benchmark. - New interface to turn PSI on/off on a per cgroup level. * tag 'sched-psi-2022-10-14' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: sched/psi: Per-cgroup PSI accounting disable/re-enable interface sched/psi: Cache parent psi_group to speed up group iteration sched/psi: Consolidate cgroup_psi() sched/psi: Add PSI_IRQ to track IRQ/SOFTIRQ pressure sched/psi: Remove NR_ONCPU task accounting sched/psi: Optimize task switch inside shared cgroups again sched/psi: Move private helpers to sched/stats.h sched/psi: Save percpu memory when !psi_cgroups_enabled sched/psi: Don't create cgroup PSI files when psi_disabled sched/psi: Fix periodic aggregation shut off
Showing the changes to include (4 of 9 files). Show all
Unified · Split
| @@ -428,6 +428,9 @@ struct cgroup { · 427 unmodified lines | ||
| 428 | 428 | struct cgroup_file procs_file; /* handle for "cgroup.procs" */ |
| 429 | 429 | struct cgroup_file events_file; /* handle for "cgroup.events" */ |
| 430 | 430 | |
| 431 | + /* handles for "{cpu,memory,io,irq}.pressure" */ | |
| 432 | + struct cgroup_file psi_files[NR_PSI_RESOURCES]; | |
| 433 | + | |
| 431 | 434 | /* |
| 432 | 435 | * The bitmask of subsystems enabled on the child cgroups. |
| 433 | 436 | * ->subtree_control is the one configured through |
| @@ -682,11 +682,6 @@ static inline void pr_cont_cgroup_path(struct cgroup *cgrp) · 681 unmodified lines | ||
| 682 | 682 | pr_cont_kernfs_path(cgrp->kn); |
| 683 | 683 | } |
| 684 | 684 | |
| 685 | −static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) | |
| 686 | −{ | |
| 687 | − return cgrp->psi; | |
| 688 | −} | |
| 689 | − | |
| 690 | 685 | bool cgroup_psi_enabled(void); |
| 691 | 686 | |
| 692 | 687 | static inline void cgroup_init_kthreadd(void) |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/sched.h> |
| 8 | 8 | #include <linux/poll.h> |
| 9 | 9 | #include <linux/cgroup-defs.h> |
| 10 | +#include <linux/cgroup.h> | |
| 10 | 11 | |
| 11 | 12 | struct seq_file; |
| 12 | 13 | struct css_set; |
| @@ -18,10 +19,6 @@ extern struct psi_group psi_system; · 5 unmodified lines | ||
| 18 | 19 | |
| 19 | 20 | void psi_init(void); |
| 20 | 21 | |
| 21 | −void psi_task_change(struct task_struct *task, int clear, int set); | |
| 22 | −void psi_task_switch(struct task_struct *prev, struct task_struct *next, | |
| 23 | − bool sleep); | |
| 24 | − | |
| 25 | 22 | void psi_memstall_enter(unsigned long *flags); |
| 26 | 23 | void psi_memstall_leave(unsigned long *flags); |
| 27 | 24 | |
| @@ -34,9 +31,15 @@ __poll_t psi_trigger_poll(void **trigger_ptr, struct file *file, · 6 unmodified lines | ||
| 34 | 31 | poll_table *wait); |
| 35 | 32 | |
| 36 | 33 | #ifdef CONFIG_CGROUPS |
| 34 | +static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) | |
| 35 | +{ | |
| 36 | + return cgroup_ino(cgrp) == 1 ? &psi_system : cgrp->psi; | |
| 37 | +} | |
| 38 | + | |
| 37 | 39 | int psi_cgroup_alloc(struct cgroup *cgrp); |
| 38 | 40 | void psi_cgroup_free(struct cgroup *cgrp); |
| 39 | 41 | void cgroup_move_task(struct task_struct *p, struct css_set *to); |
| 42 | +void psi_cgroup_restart(struct psi_group *group); | |
| 40 | 43 | #endif |
| 41 | 44 | |
| 42 | 45 | #else /* CONFIG_PSI */ |
| @@ -58,6 +61,7 @@ static inline void cgroup_move_task(struct task_struct *p, struct css_set *to) · 15 unmodified lines | ||
| 58 | 61 | { |
| 59 | 62 | rcu_assign_pointer(p->cgroups, to); |
| 60 | 63 | } |
| 64 | +static inline void psi_cgroup_restart(struct psi_group *group) {} | |
| 61 | 65 | #endif |
| 62 | 66 | |
| 63 | 67 | #endif /* CONFIG_PSI */ |
| @@ -15,13 +15,6 @@ enum psi_task_count { · 14 unmodified lines | ||
| 15 | 15 | NR_IOWAIT, |
| 16 | 16 | NR_MEMSTALL, |
| 17 | 17 | NR_RUNNING, |
| 18 | − /* | |
| 19 | − * This can't have values other than 0 or 1 and could be | |
| 20 | − * implemented as a bit flag. But for now we still have room | |
| 21 | − * in the first cacheline of psi_group_cpu, and this way we | |
| 22 | − * don't have to special case any state tracking for it. | |
| 23 | − */ | |
| 24 | − NR_ONCPU, | |
| 25 | 18 | /* |
| 26 | 19 | * For IO and CPU stalls the presence of running/oncpu tasks |
| 27 | 20 | * in the domain means a partial rather than a full stall. |
| @@ -32,22 +25,27 @@ enum psi_task_count { · 4 unmodified lines | ||
| 32 | 25 | * threads and memstall ones. |
| 33 | 26 | */ |
| 34 | 27 | NR_MEMSTALL_RUNNING, |
| 35 | − NR_PSI_TASK_COUNTS = 5, | |
| 28 | + NR_PSI_TASK_COUNTS = 4, | |
| 36 | 29 | }; |
| 37 | 30 | |
| 38 | 31 | /* Task state bitmasks */ |
| 39 | 32 | #define TSK_IOWAIT (1 << NR_IOWAIT) |
| 40 | 33 | #define TSK_MEMSTALL (1 << NR_MEMSTALL) |
| 41 | 34 | #define TSK_RUNNING (1 << NR_RUNNING) |
| 42 | −#define TSK_ONCPU (1 << NR_ONCPU) | |
| 43 | 35 | #define TSK_MEMSTALL_RUNNING (1 << NR_MEMSTALL_RUNNING) |
| 44 | 36 | |
| 37 | +/* Only one task can be scheduled, no corresponding task count */ | |
| 38 | +#define TSK_ONCPU (1 << NR_PSI_TASK_COUNTS) | |
| 39 | + | |
| 45 | 40 | /* Resources that workloads could be stalled on */ |
| 46 | 41 | enum psi_res { |
| 47 | 42 | PSI_IO, |
| 48 | 43 | PSI_MEM, |
| 49 | 44 | PSI_CPU, |
| 50 | − NR_PSI_RESOURCES = 3, | |
| 45 | +#ifdef CONFIG_IRQ_TIME_ACCOUNTING | |
| 46 | + PSI_IRQ, | |
| 47 | +#endif | |
| 48 | + NR_PSI_RESOURCES, | |
| 51 | 49 | }; |
| 52 | 50 | |
| 53 | 51 | /* |
| @@ -63,11 +61,17 @@ enum psi_states { · 9 unmodified lines | ||
| 63 | 61 | PSI_MEM_FULL, |
| 64 | 62 | PSI_CPU_SOME, |
| 65 | 63 | PSI_CPU_FULL, |
| 64 | +#ifdef CONFIG_IRQ_TIME_ACCOUNTING | |
| 65 | + PSI_IRQ_FULL, | |
| 66 | +#endif | |
| 66 | 67 | /* Only per-CPU, to weigh the CPU in the global average: */ |
| 67 | 68 | PSI_NONIDLE, |
| 68 | − NR_PSI_STATES = 7, | |
| 69 | + NR_PSI_STATES, | |
| 69 | 70 | }; |
| 70 | 71 | |
| 72 | +/* Use one bit in the state mask to track TSK_ONCPU */ | |
| 73 | +#define PSI_ONCPU (1 << NR_PSI_STATES) | |
| 74 | + | |
| 71 | 75 | enum psi_aggregators { |
| 72 | 76 | PSI_AVGS = 0, |
| 73 | 77 | PSI_POLL, |
| @@ -147,6 +151,9 @@ struct psi_trigger { · 73 unmodified lines | ||
| 147 | 151 | }; |
| 148 | 152 | |
| 149 | 153 | struct psi_group { |
| 154 | + struct psi_group *parent; | |
| 155 | + bool enabled; | |
| 156 | + | |
| 150 | 157 | /* Protects data used by the aggregator */ |
| 151 | 158 | struct mutex avgs_lock; |
| 152 | 159 | |
| @@ -188,6 +195,8 @@ struct psi_group { · 35 unmodified lines | ||
| 188 | 195 | |
| 189 | 196 | #else /* CONFIG_PSI */ |
| 190 | 197 | |
| 198 | +#define NR_PSI_RESOURCES 0 | |
| 199 | + | |
| 191 | 200 | struct psi_group { }; |
| 192 | 201 | |
| 193 | 202 | #endif /* CONFIG_PSI */ |