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 | struct cgroup_file procs_file; /* handle for "cgroup.procs" */ | 428 | struct cgroup_file procs_file; /* handle for "cgroup.procs" */ |
| 429 | struct cgroup_file events_file; /* handle for "cgroup.events" */ | 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 | * The bitmask of subsystems enabled on the child cgroups. | 435 | * The bitmask of subsystems enabled on the child cgroups. |
| 433 | * ->subtree_control is the one configured through | 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 | pr_cont_kernfs_path(cgrp->kn); | 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 | bool cgroup_psi_enabled(void); | 685 | bool cgroup_psi_enabled(void); |
| 691 | 686 | ||
| 692 | static inline void cgroup_init_kthreadd(void) | 687 | static inline void cgroup_init_kthreadd(void) |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
| 8 | #include <linux/poll.h> | 8 | #include <linux/poll.h> |
| 9 | #include <linux/cgroup-defs.h> | 9 | #include <linux/cgroup-defs.h> |
| 10 | #include <linux/cgroup.h> | ||
| 10 | 11 | ||
| 11 | struct seq_file; | 12 | struct seq_file; |
| 12 | struct css_set; | 13 | struct css_set; |
| @@ -18,10 +19,6 @@ extern struct psi_group psi_system; · 5 unmodified lines | |||
| 18 | 19 | ||
| 19 | void psi_init(void); | 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 | void psi_memstall_enter(unsigned long *flags); | 22 | void psi_memstall_enter(unsigned long *flags); |
| 26 | void psi_memstall_leave(unsigned long *flags); | 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 | poll_table *wait); | 31 | poll_table *wait); |
| 35 | 32 | ||
| 36 | #ifdef CONFIG_CGROUPS | 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 | int psi_cgroup_alloc(struct cgroup *cgrp); | 39 | int psi_cgroup_alloc(struct cgroup *cgrp); |
| 38 | void psi_cgroup_free(struct cgroup *cgrp); | 40 | void psi_cgroup_free(struct cgroup *cgrp); |
| 39 | void cgroup_move_task(struct task_struct *p, struct css_set *to); | 41 | void cgroup_move_task(struct task_struct *p, struct css_set *to); |
| 42 | void psi_cgroup_restart(struct psi_group *group); | ||
| 40 | #endif | 43 | #endif |
| 41 | 44 | ||
| 42 | #else /* CONFIG_PSI */ | 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 | rcu_assign_pointer(p->cgroups, to); | 62 | rcu_assign_pointer(p->cgroups, to); |
| 60 | } | 63 | } |
| 64 | static inline void psi_cgroup_restart(struct psi_group *group) {} | ||
| 61 | #endif | 65 | #endif |
| 62 | 66 | ||
| 63 | #endif /* CONFIG_PSI */ | 67 | #endif /* CONFIG_PSI */ |
| @@ -15,13 +15,6 @@ enum psi_task_count { · 14 unmodified lines | |||
| 15 | NR_IOWAIT, | 15 | NR_IOWAIT, |
| 16 | NR_MEMSTALL, | 16 | NR_MEMSTALL, |
| 17 | NR_RUNNING, | 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 | * For IO and CPU stalls the presence of running/oncpu tasks | 19 | * For IO and CPU stalls the presence of running/oncpu tasks |
| 27 | * in the domain means a partial rather than a full stall. | 20 | * in the domain means a partial rather than a full stall. |
| @@ -32,22 +25,27 @@ enum psi_task_count { · 4 unmodified lines | |||
| 32 | * threads and memstall ones. | 25 | * threads and memstall ones. |
| 33 | */ | 26 | */ |
| 34 | NR_MEMSTALL_RUNNING, | 27 | NR_MEMSTALL_RUNNING, |
| 35 | NR_PSI_TASK_COUNTS = 5, | 28 | NR_PSI_TASK_COUNTS = 4, |
| 36 | }; | 29 | }; |
| 37 | 30 | ||
| 38 | /* Task state bitmasks */ | 31 | /* Task state bitmasks */ |
| 39 | #define TSK_IOWAIT (1 << NR_IOWAIT) | 32 | #define TSK_IOWAIT (1 << NR_IOWAIT) |
| 40 | #define TSK_MEMSTALL (1 << NR_MEMSTALL) | 33 | #define TSK_MEMSTALL (1 << NR_MEMSTALL) |
| 41 | #define TSK_RUNNING (1 << NR_RUNNING) | 34 | #define TSK_RUNNING (1 << NR_RUNNING) |
| 42 | #define TSK_ONCPU (1 << NR_ONCPU) | ||
| 43 | #define TSK_MEMSTALL_RUNNING (1 << NR_MEMSTALL_RUNNING) | 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 | /* Resources that workloads could be stalled on */ | 40 | /* Resources that workloads could be stalled on */ |
| 46 | enum psi_res { | 41 | enum psi_res { |
| 47 | PSI_IO, | 42 | PSI_IO, |
| 48 | PSI_MEM, | 43 | PSI_MEM, |
| 49 | PSI_CPU, | 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 | PSI_MEM_FULL, | 61 | PSI_MEM_FULL, |
| 64 | PSI_CPU_SOME, | 62 | PSI_CPU_SOME, |
| 65 | PSI_CPU_FULL, | 63 | PSI_CPU_FULL, |
| 64 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING | ||
| 65 | PSI_IRQ_FULL, | ||
| 66 | #endif | ||
| 66 | /* Only per-CPU, to weigh the CPU in the global average: */ | 67 | /* Only per-CPU, to weigh the CPU in the global average: */ |
| 67 | PSI_NONIDLE, | 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 | enum psi_aggregators { | 75 | enum psi_aggregators { |
| 72 | PSI_AVGS = 0, | 76 | PSI_AVGS = 0, |
| 73 | PSI_POLL, | 77 | PSI_POLL, |
| @@ -147,6 +151,9 @@ struct psi_trigger { · 73 unmodified lines | |||
| 147 | }; | 151 | }; |
| 148 | 152 | ||
| 149 | struct psi_group { | 153 | struct psi_group { |
| 154 | struct psi_group *parent; | ||
| 155 | bool enabled; | ||
| 156 | |||
| 150 | /* Protects data used by the aggregator */ | 157 | /* Protects data used by the aggregator */ |
| 151 | struct mutex avgs_lock; | 158 | struct mutex avgs_lock; |
| 152 | 159 | ||
| @@ -188,6 +195,8 @@ struct psi_group { · 35 unmodified lines | |||
| 188 | 195 | ||
| 189 | #else /* CONFIG_PSI */ | 196 | #else /* CONFIG_PSI */ |
| 190 | 197 | ||
| 198 | #define NR_PSI_RESOURCES 0 | ||
| 199 | |||
| 191 | struct psi_group { }; | 200 | struct psi_group { }; |
| 192 | 201 | ||
| 193 | #endif /* CONFIG_PSI */ | 202 | #endif /* CONFIG_PSI */ |