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
10 static atomic_t kswapd_monitor = ATOMIC_INIT(0);
11 static DECLARE_WAIT_QUEUE_HEAD(kswapd_poll_wait);
12
kswapd_monitor_wake_up_queue(void)13 void kswapd_monitor_wake_up_queue(void)
14 {
15 atomic_inc(&kswapd_monitor);
16 wake_up_interruptible(&kswapd_poll_wait);
17 }
18
kswapd_monitor_poll(struct file * file,struct poll_table_struct * wait)19 static __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
kswapd_monitor_show(struct seq_file * m,void * v)33 static 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
kswapd_monitor_open(struct inode * inode,struct file * file)39 static int kswapd_monitor_open(struct inode *inode, struct file *file)
40 {
41 return single_open(file, kswapd_monitor_show, NULL);
42 }
43
44 static 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
memory_monitor_init(void)52 static 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