diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/psi.h | 28 | ||||
-rw-r--r-- | include/linux/psi_types.h | 92 | ||||
-rw-r--r-- | include/linux/sched.h | 10 |
3 files changed, 130 insertions, 0 deletions
diff --git a/include/linux/psi.h b/include/linux/psi.h new file mode 100644 index 000000000000..b0daf050de58 --- /dev/null +++ b/include/linux/psi.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef _LINUX_PSI_H | ||
2 | #define _LINUX_PSI_H | ||
3 | |||
4 | #include <linux/psi_types.h> | ||
5 | #include <linux/sched.h> | ||
6 | |||
7 | #ifdef CONFIG_PSI | ||
8 | |||
9 | extern bool psi_disabled; | ||
10 | |||
11 | void psi_init(void); | ||
12 | |||
13 | void psi_task_change(struct task_struct *task, int clear, int set); | ||
14 | |||
15 | void psi_memstall_tick(struct task_struct *task, int cpu); | ||
16 | void psi_memstall_enter(unsigned long *flags); | ||
17 | void psi_memstall_leave(unsigned long *flags); | ||
18 | |||
19 | #else /* CONFIG_PSI */ | ||
20 | |||
21 | static inline void psi_init(void) {} | ||
22 | |||
23 | static inline void psi_memstall_enter(unsigned long *flags) {} | ||
24 | static inline void psi_memstall_leave(unsigned long *flags) {} | ||
25 | |||
26 | #endif /* CONFIG_PSI */ | ||
27 | |||
28 | #endif /* _LINUX_PSI_H */ | ||
diff --git a/include/linux/psi_types.h b/include/linux/psi_types.h new file mode 100644 index 000000000000..2cf422db5d18 --- /dev/null +++ b/include/linux/psi_types.h | |||
@@ -0,0 +1,92 @@ | |||
1 | #ifndef _LINUX_PSI_TYPES_H | ||
2 | #define _LINUX_PSI_TYPES_H | ||
3 | |||
4 | #include <linux/seqlock.h> | ||
5 | #include <linux/types.h> | ||
6 | |||
7 | #ifdef CONFIG_PSI | ||
8 | |||
9 | /* Tracked task states */ | ||
10 | enum psi_task_count { | ||
11 | NR_IOWAIT, | ||
12 | NR_MEMSTALL, | ||
13 | NR_RUNNING, | ||
14 | NR_PSI_TASK_COUNTS, | ||
15 | }; | ||
16 | |||
17 | /* Task state bitmasks */ | ||
18 | #define TSK_IOWAIT (1 << NR_IOWAIT) | ||
19 | #define TSK_MEMSTALL (1 << NR_MEMSTALL) | ||
20 | #define TSK_RUNNING (1 << NR_RUNNING) | ||
21 | |||
22 | /* Resources that workloads could be stalled on */ | ||
23 | enum psi_res { | ||
24 | PSI_IO, | ||
25 | PSI_MEM, | ||
26 | PSI_CPU, | ||
27 | NR_PSI_RESOURCES, | ||
28 | }; | ||
29 | |||
30 | /* | ||
31 | * Pressure states for each resource: | ||
32 | * | ||
33 | * SOME: Stalled tasks & working tasks | ||
34 | * FULL: Stalled tasks & no working tasks | ||
35 | */ | ||
36 | enum psi_states { | ||
37 | PSI_IO_SOME, | ||
38 | PSI_IO_FULL, | ||
39 | PSI_MEM_SOME, | ||
40 | PSI_MEM_FULL, | ||
41 | PSI_CPU_SOME, | ||
42 | /* Only per-CPU, to weigh the CPU in the global average: */ | ||
43 | PSI_NONIDLE, | ||
44 | NR_PSI_STATES, | ||
45 | }; | ||
46 | |||
47 | struct psi_group_cpu { | ||
48 | /* 1st cacheline updated by the scheduler */ | ||
49 | |||
50 | /* Aggregator needs to know of concurrent changes */ | ||
51 | seqcount_t seq ____cacheline_aligned_in_smp; | ||
52 | |||
53 | /* States of the tasks belonging to this group */ | ||
54 | unsigned int tasks[NR_PSI_TASK_COUNTS]; | ||
55 | |||
56 | /* Period time sampling buckets for each state of interest (ns) */ | ||
57 | u32 times[NR_PSI_STATES]; | ||
58 | |||
59 | /* Time of last task change in this group (rq_clock) */ | ||
60 | u64 state_start; | ||
61 | |||
62 | /* 2nd cacheline updated by the aggregator */ | ||
63 | |||
64 | /* Delta detection against the sampling buckets */ | ||
65 | u32 times_prev[NR_PSI_STATES] ____cacheline_aligned_in_smp; | ||
66 | }; | ||
67 | |||
68 | struct psi_group { | ||
69 | /* Protects data updated during an aggregation */ | ||
70 | struct mutex stat_lock; | ||
71 | |||
72 | /* Per-cpu task state & time tracking */ | ||
73 | struct psi_group_cpu __percpu *pcpu; | ||
74 | |||
75 | /* Periodic aggregation state */ | ||
76 | u64 total_prev[NR_PSI_STATES - 1]; | ||
77 | u64 last_update; | ||
78 | u64 next_update; | ||
79 | struct delayed_work clock_work; | ||
80 | |||
81 | /* Total stall times and sampled pressure averages */ | ||
82 | u64 total[NR_PSI_STATES - 1]; | ||
83 | unsigned long avg[NR_PSI_STATES - 1][3]; | ||
84 | }; | ||
85 | |||
86 | #else /* CONFIG_PSI */ | ||
87 | |||
88 | struct psi_group { }; | ||
89 | |||
90 | #endif /* CONFIG_PSI */ | ||
91 | |||
92 | #endif /* _LINUX_PSI_TYPES_H */ | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index adfb3f9a7597..b8fcc6b3080c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/latencytop.h> | 25 | #include <linux/latencytop.h> |
26 | #include <linux/sched/prio.h> | 26 | #include <linux/sched/prio.h> |
27 | #include <linux/signal_types.h> | 27 | #include <linux/signal_types.h> |
28 | #include <linux/psi_types.h> | ||
28 | #include <linux/mm_types_task.h> | 29 | #include <linux/mm_types_task.h> |
29 | #include <linux/task_io_accounting.h> | 30 | #include <linux/task_io_accounting.h> |
30 | #include <linux/rseq.h> | 31 | #include <linux/rseq.h> |
@@ -706,6 +707,10 @@ struct task_struct { | |||
706 | unsigned sched_contributes_to_load:1; | 707 | unsigned sched_contributes_to_load:1; |
707 | unsigned sched_migrated:1; | 708 | unsigned sched_migrated:1; |
708 | unsigned sched_remote_wakeup:1; | 709 | unsigned sched_remote_wakeup:1; |
710 | #ifdef CONFIG_PSI | ||
711 | unsigned sched_psi_wake_requeue:1; | ||
712 | #endif | ||
713 | |||
709 | /* Force alignment to the next boundary: */ | 714 | /* Force alignment to the next boundary: */ |
710 | unsigned :0; | 715 | unsigned :0; |
711 | 716 | ||
@@ -965,6 +970,10 @@ struct task_struct { | |||
965 | kernel_siginfo_t *last_siginfo; | 970 | kernel_siginfo_t *last_siginfo; |
966 | 971 | ||
967 | struct task_io_accounting ioac; | 972 | struct task_io_accounting ioac; |
973 | #ifdef CONFIG_PSI | ||
974 | /* Pressure stall state */ | ||
975 | unsigned int psi_flags; | ||
976 | #endif | ||
968 | #ifdef CONFIG_TASK_XACCT | 977 | #ifdef CONFIG_TASK_XACCT |
969 | /* Accumulated RSS usage: */ | 978 | /* Accumulated RSS usage: */ |
970 | u64 acct_rss_mem1; | 979 | u64 acct_rss_mem1; |
@@ -1391,6 +1400,7 @@ extern struct pid *cad_pid; | |||
1391 | #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ | 1400 | #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ |
1392 | #define PF_RANDOMIZE 0x00400000 /* Randomize virtual address space */ | 1401 | #define PF_RANDOMIZE 0x00400000 /* Randomize virtual address space */ |
1393 | #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ | 1402 | #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ |
1403 | #define PF_MEMSTALL 0x01000000 /* Stalled due to lack of memory */ | ||
1394 | #define PF_NO_SETAFFINITY 0x04000000 /* Userland is not allowed to meddle with cpus_allowed */ | 1404 | #define PF_NO_SETAFFINITY 0x04000000 /* Userland is not allowed to meddle with cpus_allowed */ |
1395 | #define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */ | 1405 | #define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */ |
1396 | #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ | 1406 | #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ |