swaps_poll() sleeps the poller on a queue of its own. procfs owns the queue poll() uses now, so leave the poll_wait() to it and wake its pollers when a swap area comes or goes.
Signed-off-by: Christian Brauner (Amutable) <[email protected]> --- mm/swapfile.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index ee4868ecc3a7..1d063a1cef43 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -111,7 +111,7 @@ static struct kmem_cache *swap_table_cachep; /* Protects si->swap_file for /proc/swaps usage */ static DEFINE_MUTEX(swapon_mutex); -static DECLARE_WAIT_QUEUE_HEAD(proc_poll_wait); +static struct proc_dir_entry *proc_swaps; /* Activity counter to indicate that a swapon or swapoff has occurred */ static atomic_t proc_poll_event = ATOMIC_INIT(0); @@ -3307,7 +3307,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) err = 0; atomic_inc(&proc_poll_event); - wake_up_interruptible(&proc_poll_wait); + proc_poll_notify(proc_swaps); out_dput: filp_close(victim, NULL); @@ -3319,8 +3319,6 @@ static __poll_t swaps_poll(struct file *file, poll_table *wait) { struct seq_file *seq = file->private_data; - poll_wait(file, &proc_poll_wait, wait); - if (seq->poll_event != atomic_read(&proc_poll_event)) { seq->poll_event = atomic_read(&proc_poll_event); return EPOLLIN | EPOLLRDNORM | EPOLLERR | EPOLLPRI; @@ -3428,7 +3426,7 @@ static const struct proc_ops swaps_proc_ops = { static int __init procswaps_init(void) { - proc_create("swaps", 0, NULL, &swaps_proc_ops); + proc_swaps = proc_create("swaps", 0, NULL, &swaps_proc_ops); return 0; } __initcall(procswaps_init); @@ -3907,7 +3905,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) mutex_unlock(&swapon_mutex); atomic_inc(&proc_poll_event); - wake_up_interruptible(&proc_poll_wait); + proc_poll_notify(proc_swaps); error = 0; goto out; -- 2.53.0
