79 lines
2.9 KiB
C
79 lines
2.9 KiB
C
#ifndef __LINUX_VMPRESSURE_H
|
|
#define __LINUX_VMPRESSURE_H
|
|
|
|
#include <linux/mutex.h>
|
|
#include <linux/list.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/gfp.h>
|
|
#include <linux/types.h>
|
|
#include <linux/cgroup.h>
|
|
|
|
enum vmpressure_levels {
|
|
VMPRESSURE_LOW = 0,
|
|
VMPRESSURE_MEDIUM,
|
|
VMPRESSURE_CRITICAL,
|
|
VMPRESSURE_NUM_LEVELS,
|
|
};
|
|
|
|
struct vmpressure {
|
|
/*
|
|
* The window size is the number of scanned pages before
|
|
* we try to analyze scanned/reclaimed ratio. Using small window
|
|
* sizes can cause lot of false positives, but too big window size will
|
|
* delay the notifications.
|
|
*
|
|
* In order to reduce the amount of false positives for low and medium
|
|
* levels, those levels aren't reported until we've seen multiple
|
|
* windows at those respective pressure levels. This makes sure
|
|
* sure that we don't delay notifications when encountering critical
|
|
* levels of memory pressure, but also don't spam userspace in case
|
|
* nothing serious is going on. The number of windows seen at each
|
|
* pressure level is kept in nr_windows below.
|
|
*
|
|
* For the root mem cgroup, the window size is computed based on the
|
|
* total amount of pages available in the system. For non-root cgroups,
|
|
* we compute the window size based on the hard memory limit, or if
|
|
* that is not set, we fall back to the default window size.
|
|
*/
|
|
unsigned long window_size;
|
|
/* The number of windows we've seen each pressure level occur for */
|
|
unsigned int nr_windows[VMPRESSURE_NUM_LEVELS];
|
|
unsigned long scanned;
|
|
unsigned long reclaimed;
|
|
/* The lock is used to keep the members above in sync. */
|
|
struct mutex sr_lock;
|
|
|
|
/* The list of vmpressure_event structs. */
|
|
struct list_head events;
|
|
/* Have to grab the lock on events traversal or modifications. */
|
|
struct mutex events_lock;
|
|
|
|
struct work_struct work;
|
|
};
|
|
|
|
struct mem_cgroup;
|
|
|
|
#ifdef CONFIG_MEMCG
|
|
extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg,
|
|
unsigned long scanned, unsigned long reclaimed);
|
|
extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio);
|
|
|
|
extern void vmpressure_init(struct vmpressure *vmpr, bool is_root);
|
|
extern struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg);
|
|
extern struct cgroup_subsys_state *vmpressure_to_css(struct vmpressure *vmpr);
|
|
extern struct vmpressure *css_to_vmpressure(struct cgroup_subsys_state *css);
|
|
extern void vmpressure_update_mem_limit(struct mem_cgroup *memcg,
|
|
unsigned long new_limit);
|
|
extern int vmpressure_register_event(struct cgroup *cg, struct cftype *cft,
|
|
struct eventfd_ctx *eventfd,
|
|
const char *args);
|
|
extern void vmpressure_unregister_event(struct cgroup *cg, struct cftype *cft,
|
|
struct eventfd_ctx *eventfd);
|
|
#else
|
|
static inline void vmpressure(gfp_t gfp, struct mem_cgroup *memcg,
|
|
unsigned long scanned, unsigned long reclaimed) {}
|
|
static inline void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg,
|
|
int prio) {}
|
|
#endif /* CONFIG_MEMCG */
|
|
#endif /* __LINUX_VMPRESSURE_H */
|