#ifndef _LINUX_PSI_TYPES_H #define _LINUX_PSI_TYPES_H #include <linux/seqlock.h> #include <linux/types.h> #ifdef CONFIG_PSI /* Tracked task states */ enum psi_task_count { NR_IOWAIT, NR_MEMSTALL, NR_RUNNING, NR_PSI_TASK_COUNTS, }; /* Task state bitmasks */ #define TSK_IOWAIT (1 << NR_IOWAIT) #define TSK_MEMSTALL (1 << NR_MEMSTALL) #define TSK_RUNNING (1 << NR_RUNNING) /* Resources that workloads could be stalled on */ enum psi_res { PSI_IO, PSI_MEM, PSI_CPU, NR_PSI_RESOURCES, }; /* * Pressure states for each resource: * * SOME: Stalled tasks & working tasks * FULL: Stalled tasks & no working tasks */ enum psi_states { PSI_IO_SOME, PSI_IO_FULL, PSI_MEM_SOME, PSI_MEM_FULL, PSI_CPU_SOME, /* Only per-CPU, to weigh the CPU in the global average: */ PSI_NONIDLE, NR_PSI_STATES, }; struct psi_group_cpu { /* 1st cacheline updated by the scheduler */ /* Aggregator needs to know of concurrent changes */ seqcount_t seq ____cacheline_aligned_in_smp; /* States of the tasks belonging to this group */ unsigned int tasks[NR_PSI_TASK_COUNTS]; /* Period time sampling buckets for each state of interest (ns) */ u32 times[NR_PSI_STATES]; /* Time of last task change in this group (rq_clock) */ u64 state_start; /* 2nd cacheline updated by the aggregator */ /* Delta detection against the sampling buckets */ u32 times_prev[NR_PSI_STATES] ____cacheline_aligned_in_smp; }; struct psi_group { /* Protects data updated during an aggregation */ struct mutex stat_lock; /* Per-cpu task state & time tracking */ struct psi_group_cpu __percpu *pcpu; /* Periodic aggregation state */ u64 total_prev[NR_PSI_STATES - 1]; u64 last_update; u64 next_update; struct delayed_work clock_work; /* Total stall times and sampled pressure averages */ u64 total[NR_PSI_STATES - 1]; unsigned long avg[NR_PSI_STATES - 1][3]; }; #else /* CONFIG_PSI */ struct psi_group { }; #endif /* CONFIG_PSI */ #endif /* _LINUX_PSI_TYPES_H */