xref: /kernel/linux/linux-5.10/mm/memory_monitor.c (revision 8c2ecf20)
1#include <linux/poll.h>
2#include <linux/eventpoll.h>
3#include <linux/wait.h>
4#include <linux/seq_file.h>
5#include <linux/mm.h>
6#include <linux/proc_fs.h>
7
8#include "internal.h"
9
10static atomic_t kswapd_monitor = ATOMIC_INIT(0);
11static DECLARE_WAIT_QUEUE_HEAD(kswapd_poll_wait);
12
13void kswapd_monitor_wake_up_queue(void)
14{
15    atomic_inc(&kswapd_monitor);
16    wake_up_interruptible(&kswapd_poll_wait);
17}
18
19static __poll_t kswapd_monitor_poll(struct file *file, struct poll_table_struct *wait)
20{
21    struct seq_file *seq = file->private_data;
22
23    poll_wait(file, &kswapd_poll_wait, wait);
24
25    if (seq->poll_event != atomic_read(&kswapd_monitor)) {
26        seq->poll_event = atomic_read(&kswapd_monitor);
27        return EPOLLPRI;
28    }
29
30    return EPOLLIN | EPOLLRDNORM;
31}
32
33static int kswapd_monitor_show(struct seq_file *m, void *v)
34{
35    seq_printf(m, "kswapd_monitor_show kswapd_monitor %d\n", atomic_read(&kswapd_monitor));
36    return 0;
37}
38
39static int kswapd_monitor_open(struct inode *inode, struct file *file)
40{
41    return single_open(file, kswapd_monitor_show, NULL);
42}
43
44static const struct proc_ops proc_kswapd_monitor_operations = {
45    .proc_open = kswapd_monitor_open,
46    .proc_poll = kswapd_monitor_poll,
47    .proc_read = seq_read,
48    .proc_lseek = seq_lseek,
49    .proc_release = single_release,
50};
51
52static int __init memory_monitor_init(void)
53{
54	proc_create("kswapd_monitor", 0, NULL, &proc_kswapd_monitor_operations);
55	return 0;
56}
57
58__initcall(memory_monitor_init)
59