From: Rusty Russell Date: Thu, 20 Jun 2002 05:41:53 +0000 (-0700) Subject: [PATCH] Futex bugfixes. X-Git-Tag: v2.5.24~76 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=74f58650cc458fd2cd3fd5058ba345e2e74612bd;p=history.git [PATCH] Futex bugfixes. This uses page_cache_release() instead of put_page(), as it might be a pagecache page. --- diff --git a/kernel/futex.c b/kernel/futex.c index bdff307969ef..332acaa2d6c5 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -70,6 +70,14 @@ static inline void tell_waiter(struct futex_q *q) wake_up_all(&q->waiters); } +static inline void unpin_page(struct page *page) +{ + /* Avoid releasing the page which is on the LRU list. I don't + know if this is correct, but it stops the BUG() in + __free_pages_ok(). */ + page_cache_release(page); +} + static int futex_wake(struct list_head *head, struct page *page, unsigned int offset, @@ -130,9 +138,9 @@ static struct page *pin_page(unsigned long page_start) int err; down_read(&mm->mmap_sem); - err = get_user_pages(current, current->mm, page_start, + err = get_user_pages(current, mm, page_start, 1 /* one page */, - 1 /* writable */, + 0 /* writable not important */, 0 /* don't force */, &page, NULL /* don't return vmas */); @@ -223,7 +231,7 @@ asmlinkage int sys_futex(void *uaddr, int op, int val, struct timespec *utime) default: ret = -EINVAL; } - page_cache_release(page); + unpin_page(page); return ret; }