xref: /linux-6.15/include/linux/psi_types.h (revision 228cd2db)
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 */
93