/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_VMPRESSURE_H #define __LINUX_VMPRESSURE_H #include #include #include #include #include #include #include struct vmpressure { unsigned long scanned; unsigned long reclaimed; /* The lock is used to keep the scanned/reclaimed in sync. */ spinlock_t sr_lock; #ifdef CONFIG_MEMCG_V1 /* * tree=true accumulators feed the v1 userspace eventfd interface * (memory.pressure_level). Drained by @work. v2 has no equivalent * interface, so this state is omitted on CONFIG_MEMCG_V1=n builds. */ unsigned long tree_scanned; unsigned long tree_reclaimed; /* 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; #endif }; enum vmpressure_levels { VMPRESSURE_LOW = 0, VMPRESSURE_MEDIUM, VMPRESSURE_CRITICAL, VMPRESSURE_NUM_LEVELS, }; struct mem_cgroup; #ifdef CONFIG_MEMCG void vmpressure(gfp_t gfp, int order, struct mem_cgroup *memcg, bool tree, unsigned long scanned, unsigned long reclaimed); extern void vmpressure_init(struct vmpressure *vmpr); extern void vmpressure_cleanup(struct vmpressure *vmpr); extern struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg); extern struct mem_cgroup *vmpressure_to_memcg(struct vmpressure *vmpr); /* Shared with the v1 vmpressure block in mm/memcontrol-v1.c. */ extern const unsigned long vmpressure_win; extern enum vmpressure_levels vmpressure_calc_level(unsigned long scanned, unsigned long reclaimed); #ifdef CONFIG_MEMCG_V1 extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio); extern int vmpressure_register_event(struct mem_cgroup *memcg, struct eventfd_ctx *eventfd, const char *args); extern void vmpressure_unregister_event(struct mem_cgroup *memcg, struct eventfd_ctx *eventfd); /* v1 hooks called from mm/vmpressure.c; no-ops below when !MEMCG_V1. */ extern void vmpressure_v1_init(struct vmpressure *vmpr); extern void vmpressure_v1_cleanup(struct vmpressure *vmpr); extern void vmpressure_v1_account_tree(struct vmpressure *vmpr, unsigned long scanned, unsigned long reclaimed); #else static inline void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio) {} static inline void vmpressure_v1_init(struct vmpressure *vmpr) {} static inline void vmpressure_v1_cleanup(struct vmpressure *vmpr) {} static inline void vmpressure_v1_account_tree(struct vmpressure *vmpr, unsigned long scanned, unsigned long reclaimed) {} #endif /* CONFIG_MEMCG_V1 */ #else /* !CONFIG_MEMCG */ static inline void vmpressure(gfp_t gfp, int order, struct mem_cgroup *memcg, bool tree, 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 */