#ifndef __LINUX_VMPRESSURE_H #define __LINUX_VMPRESSURE_H #include #include #include #include #include #include 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 */