Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=18963c01b8abf381f102752ce024c3582a716125
Commit:     18963c01b8abf381f102752ce024c3582a716125
Parent:     d48eb2331595224ffe89665e79721d44b40bb047
Author:     Davide Libenzi <[EMAIL PROTECTED]>
AuthorDate: Fri May 18 12:02:33 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Fri May 18 13:09:34 2007 -0700

    timerfd use waitqueue lock ...
    
    The timerfd was using the unlocked waitqueue operations, but it was
    using a different lock, so poll_wait() would race with it.
    
    This makes timerfd directly use the waitqueue lock.
    
    Signed-off-by: Davide Libenzi <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/timerfd.c |   24 +++++++++++-------------
 1 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/fs/timerfd.c b/fs/timerfd.c
index e329e37..af9eca5 100644
--- a/fs/timerfd.c
+++ b/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_tmrproc(struct hrtimer 
*htmr)
        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 file *file, 
poll_table *wait)
 
        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 *file, char __user 
*buf, size_t count,
 
        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 *file, char __user 
*buf, size_t count,
                                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 *file, char __user 
*buf, size_t count,
                } 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 clockid, int flags,
                        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 clockid, int 
flags,
                 * 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 clockid, int flags,
                 */
                timerfd_setup(ctx, clockid, flags, &ktmr);
 
-               spin_unlock_irq(&ctx->lock);
+               spin_unlock_irq(&ctx->wqh.lock);
                fput(file);
        }
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to