summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/psi.h28
-rw-r--r--include/linux/psi_types.h92
-rw-r--r--include/linux/sched.h10
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
9extern bool psi_disabled;
10
11void psi_init(void);
12
13void psi_task_change(struct task_struct *task, int clear, int set);
14
15void psi_memstall_tick(struct task_struct *task, int cpu);
16void psi_memstall_enter(unsigned long *flags);
17void psi_memstall_leave(unsigned long *flags);
18
19#else /* CONFIG_PSI */
20
21static inline void psi_init(void) {}
22
23static inline void psi_memstall_enter(unsigned long *flags) {}
24static 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 */
10enum 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 */
23enum 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 */
36enum 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
47struct 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
68struct 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
88struct 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 */