aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory_monitor.c
blob: 88fb97466b247eba470a1125ac74418f0c9d7cb2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <linux/poll.h>
#include <linux/eventpoll.h>
#include <linux/wait.h>
#include <linux/seq_file.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>

#include "internal.h"

static atomic_t kswapd_monitor = ATOMIC_INIT(0);
static DECLARE_WAIT_QUEUE_HEAD(kswapd_poll_wait);

void kswapd_monitor_wake_up_queue(void)
{
    atomic_inc(&kswapd_monitor);
    wake_up_interruptible(&kswapd_poll_wait);
}

static __poll_t kswapd_monitor_poll(struct file *file, struct poll_table_struct *wait)
{
    struct seq_file *seq = file->private_data;

    poll_wait(file, &kswapd_poll_wait, wait);

    if (seq->poll_event != atomic_read(&kswapd_monitor)) {
        seq->poll_event = atomic_read(&kswapd_monitor);
        return EPOLLPRI;
    }

    return EPOLLIN | EPOLLRDNORM;
}

static int kswapd_monitor_show(struct seq_file *m, void *v)
{
    seq_printf(m, "kswapd_monitor_show kswapd_monitor %d\n", atomic_read(&kswapd_monitor));
    return 0;
}

static int kswapd_monitor_open(struct inode *inode, struct file *file)
{
    return single_open(file, kswapd_monitor_show, NULL);
}

static const struct proc_ops proc_kswapd_monitor_operations = {
    .proc_open = kswapd_monitor_open,
    .proc_poll = kswapd_monitor_poll,
    .proc_read = seq_read,
    .proc_lseek = seq_lseek,
    .proc_release = single_release,
};

static int __init memory_monitor_init(void)
{
	proc_create("kswapd_monitor", 0, NULL, &proc_kswapd_monitor_operations);
	return 0;
}

__initcall(memory_monitor_init)