From a47ca28818f9d439dbe3553c4dfc6337140d93f1 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sun, 15 Jan 2012 20:17:40 +0100 Subject: [PATCH] Fix poll, thanks to the simple test program. Signed-off-by: Pierre Habouzit --- kernel/pwqr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/kernel/pwqr.c b/kernel/pwqr.c index 8248482..233bd7a 100644 --- a/kernel/pwqr.c +++ b/kernel/pwqr.c @@ -115,6 +115,7 @@ struct pwqr_sb { unsigned overcommit_wakes; int state; + unsigned has_pollin; }; struct pwqr_task { @@ -194,6 +195,7 @@ static void pwqr_sb_timer_cb(unsigned long arg) if (sb->running > sb->concurrency) { printk(KERN_DEBUG "wake up poll"); wake_up_poll(&sb->wqh_poll, POLLIN); + sb->has_pollin = 1; } pwqr_sb_unlock_irqrestore(sb, flags); } @@ -208,6 +210,7 @@ static struct pwqr_sb *pwqr_sb_create(void) kref_init(&sb->kref); init_waitqueue_head(&sb->wqh); + init_waitqueue_head(&sb->wqh_poll); sb->concurrency = num_online_cpus(); init_timer(&sb->timer); sb->timer.function = pwqr_sb_timer_cb; @@ -466,7 +469,7 @@ static unsigned int pwqr_poll(struct file *filp, poll_table *wait) poll_wait(filp, &sb->wqh_poll, wait); pwqr_sb_lock_irqsave(sb, flags); - if (sb->running > sb->concurrency) + if (sb->has_pollin) events |= POLLIN; if (sb->state < 0) events |= POLLHUP; @@ -502,8 +505,10 @@ static inline ssize_t pwqr_sb_read(struct pwqr_sb *sb, int no_wait, u32 *cnt) remove_wait_queue(&sb->wqh_poll, &wait); __set_current_state(TASK_RUNNING); } - if (likely(rc == 0)) + if (likely(rc == 0)) { *cnt = sb->running - sb->concurrency; + sb->has_pollin = 0; + } spin_unlock_irq(&sb->wqh.lock); return rc; -- 2.20.1