617a4ba0ec
Psi monitor aims to provide a low-latency short-term pressure detection mechanism configurable by users. It allows users to monitor psi metrics growth and trigger events whenever a metric raises above user-defined threshold within user-defined time window. Time window and threshold are both expressed in usecs. Multiple psi resources with different thresholds and window sizes can be monitored concurrently. Psi monitors activate when system enters stall state for the monitored psi metric and deactivate upon exit from the stall state. While system is in the stall state psi signal growth is monitored at a rate of 10 times per tracking window. Min window size is 500ms, therefore the min monitoring interval is 50ms. Max window size is 10s with monitoring interval of 1s. When activated psi monitor stays active for at least the duration of one tracking window to avoid repeated activations/deactivations when psi signal is bouncing. Notifications to the users are rate-limited to one per tracking window. Signed-off-by: Suren Baghdasaryan <surenb@google.com> Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> (not upstream yet, latest version published at: https://lore.kernel.org/patchwork/patch/1052418/) Bug: 127712811 Bug: 129157727 Test: lmkd in PSI mode Change-Id: I860049d32420485346ad545c4650f990fe0c08e3 Signed-off-by: Suren Baghdasaryan <surenb@google.com>
62 lines
1.5 KiB
C
62 lines
1.5 KiB
C
#ifndef _LINUX_PSI_H
|
|
#define _LINUX_PSI_H
|
|
|
|
#include <linux/jump_label.h>
|
|
#include <linux/psi_types.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/poll.h>
|
|
|
|
struct seq_file;
|
|
struct css_set;
|
|
|
|
#ifdef CONFIG_PSI
|
|
|
|
extern struct static_key_false psi_disabled;
|
|
|
|
void psi_init(void);
|
|
|
|
void psi_task_change(struct task_struct *task, int clear, int set);
|
|
|
|
void psi_memstall_tick(struct task_struct *task, int cpu);
|
|
void psi_memstall_enter(unsigned long *flags);
|
|
void psi_memstall_leave(unsigned long *flags);
|
|
|
|
int psi_show(struct seq_file *s, struct psi_group *group, enum psi_res res);
|
|
|
|
#ifdef CONFIG_CGROUPS
|
|
int psi_cgroup_alloc(struct cgroup *cgrp);
|
|
void psi_cgroup_free(struct cgroup *cgrp);
|
|
void cgroup_move_task(struct task_struct *p, struct css_set *to);
|
|
|
|
struct psi_trigger *psi_trigger_create(struct psi_group *group,
|
|
char *buf, size_t nbytes, enum psi_res res);
|
|
void psi_trigger_replace(void **trigger_ptr, struct psi_trigger *t);
|
|
|
|
__poll_t psi_trigger_poll(void **trigger_ptr, struct file *file,
|
|
poll_table *wait);
|
|
#endif
|
|
|
|
#else /* CONFIG_PSI */
|
|
|
|
static inline void psi_init(void) {}
|
|
|
|
static inline void psi_memstall_enter(unsigned long *flags) {}
|
|
static inline void psi_memstall_leave(unsigned long *flags) {}
|
|
|
|
#ifdef CONFIG_CGROUPS
|
|
static inline int psi_cgroup_alloc(struct cgroup *cgrp)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline void psi_cgroup_free(struct cgroup *cgrp)
|
|
{
|
|
}
|
|
static inline void cgroup_move_task(struct task_struct *p, struct css_set *to)
|
|
{
|
|
rcu_assign_pointer(p->cgroups, to);
|
|
}
|
|
#endif
|
|
|
|
#endif /* CONFIG_PSI */
|
|
|
|
#endif /* _LINUX_PSI_H */
|