The patch titled timerfd: use waitqueue lock has been added to the -mm tree. Its filename is timerfd-use-waitqueue-lock.patch *** Remember to use Documentation/SubmitChecklist when testing your code *** See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: timerfd: use waitqueue lock From: Davide Libenzi <davidel@xxxxxxxxxxxxxxx> The timerfd was using the unlocked waitqueue operations, but it was using a different lock, so poll_wait() would race with it. This patch makes timerfd directly use the waitqueue lock. Signed-off-by: Davide Libenzi <davidel@xxxxxxxxxxxxxxx> Cc: Davi Arnaut <davi@xxxxxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/timerfd.c | 24 +++++++++++------------- 1 files changed, 11 insertions(+), 13 deletions(-) diff -puN fs/timerfd.c~timerfd-use-waitqueue-lock fs/timerfd.c --- a/fs/timerfd.c~timerfd-use-waitqueue-lock +++ a/fs/timerfd.c @@ -24,7 +24,6 @@ struct timerfd_ctx { struct hrtimer tmr; ktime_t tintv; - spinlock_t lock; wait_queue_head_t wqh; int expired; }; @@ -39,10 +38,10 @@ static enum hrtimer_restart timerfd_tmrp struct timerfd_ctx *ctx = container_of(htmr, struct timerfd_ctx, tmr); unsigned long flags; - spin_lock_irqsave(&ctx->lock, flags); + spin_lock_irqsave(&ctx->wqh.lock, flags); ctx->expired = 1; wake_up_locked(&ctx->wqh); - spin_unlock_irqrestore(&ctx->lock, flags); + spin_unlock_irqrestore(&ctx->wqh.lock, flags); return HRTIMER_NORESTART; } @@ -83,10 +82,10 @@ static unsigned int timerfd_poll(struct poll_wait(file, &ctx->wqh, wait); - spin_lock_irqsave(&ctx->lock, flags); + spin_lock_irqsave(&ctx->wqh.lock, flags); if (ctx->expired) events |= POLLIN; - spin_unlock_irqrestore(&ctx->lock, flags); + spin_unlock_irqrestore(&ctx->wqh.lock, flags); return events; } @@ -101,7 +100,7 @@ static ssize_t timerfd_read(struct file if (count < sizeof(ticks)) return -EINVAL; - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); res = -EAGAIN; if (!ctx->expired && !(file->f_flags & O_NONBLOCK)) { __add_wait_queue(&ctx->wqh, &wait); @@ -115,9 +114,9 @@ static ssize_t timerfd_read(struct file res = -ERESTARTSYS; break; } - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); schedule(); - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); } __remove_wait_queue(&ctx->wqh, &wait); __set_current_state(TASK_RUNNING); @@ -139,7 +138,7 @@ static ssize_t timerfd_read(struct file } else ticks = 1; } - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); if (ticks) res = put_user(ticks, buf) ? -EFAULT: sizeof(ticks); return res; @@ -176,7 +175,6 @@ asmlinkage long sys_timerfd(int ufd, int return -ENOMEM; init_waitqueue_head(&ctx->wqh); - spin_lock_init(&ctx->lock); timerfd_setup(ctx, clockid, flags, &ktmr); @@ -202,10 +200,10 @@ asmlinkage long sys_timerfd(int ufd, int * it to the new values. */ for (;;) { - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); if (hrtimer_try_to_cancel(&ctx->tmr) >= 0) break; - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); cpu_relax(); } /* @@ -213,7 +211,7 @@ asmlinkage long sys_timerfd(int ufd, int */ timerfd_setup(ctx, clockid, flags, &ktmr); - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); fput(file); } _ Patches currently in -mm which might be from davidel@xxxxxxxxxxxxxxx are origin.patch x86_64-fix-oprofile-smp.patch eventfd-use-waitqueue-lock.patch timerfd-use-waitqueue-lock.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html