diff options
author | Jens Axboe <axboe@kernel.dk> | 2020-05-23 08:22:14 -0600 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-06-21 20:44:25 -0600 |
commit | c7510ab2cf5ccd997fe7f194edfe09cc511abf99 (patch) | |
tree | 4f0311803f9bc434de9fabfe9c89c3195d1f00d1 /include/linux | |
parent | 2e85abf053b99a6488f1b529d7aa3b8d7478adae (diff) | |
download | linux-c7510ab2cf5ccd997fe7f194edfe09cc511abf99.tar.gz linux-c7510ab2cf5ccd997fe7f194edfe09cc511abf99.tar.bz2 linux-c7510ab2cf5ccd997fe7f194edfe09cc511abf99.zip |
mm: abstract out wake_page_match() from wake_page_function()
No functional changes in this patch, just in preparation for allowing
more callers.
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/pagemap.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index cf2468da68e9..2f18221bb5c8 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -496,6 +496,43 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma, return pgoff; } +/* This has the same layout as wait_bit_key - see fs/cachefiles/rdwr.c */ +struct wait_page_key { + struct page *page; + int bit_nr; + int page_match; +}; + +struct wait_page_queue { + struct page *page; + int bit_nr; + wait_queue_entry_t wait; +}; + +static inline int wake_page_match(struct wait_page_queue *wait_page, + struct wait_page_key *key) +{ + if (wait_page->page != key->page) + return 0; + key->page_match = 1; + + if (wait_page->bit_nr != key->bit_nr) + return 0; + + /* + * Stop walking if it's locked. + * Is this safe if put_and_wait_on_page_locked() is in use? + * Yes: the waker must hold a reference to this page, and if PG_locked + * has now already been set by another task, that task must also hold + * a reference to the *same usage* of this page; so there is no need + * to walk on to wake even the put_and_wait_on_page_locked() callers. + */ + if (test_bit(key->bit_nr, &key->page->flags)) + return -1; + + return 1; +} + extern void __lock_page(struct page *page); extern int __lock_page_killable(struct page *page); extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm, |