diff options
| author | Rusty Russell <rusty@rustcorp.com.au> | 2002-06-19 22:41:53 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-06-19 22:41:53 -0700 |
| commit | 74f58650cc458fd2cd3fd5058ba345e2e74612bd (patch) | |
| tree | 509e5d1fbdbea01e0e638b2f82159a451e3b856e /kernel | |
| parent | 0e042f3a9e3607e5f93f42831ef01dbe835fa2b1 (diff) | |
[PATCH] Futex bugfixes.
This uses page_cache_release() instead of put_page(), as it might
be a pagecache page.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/futex.c | 14 |
1 files changed, 11 insertions, 3 deletions
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; } |
