Skip to content

Commit c7510ab

Browse files
committed
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 <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 2e85abf commit c7510ab

File tree

2 files changed

+41
-31
lines changed

2 files changed

+41
-31
lines changed

include/linux/pagemap.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,43 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma,
496496
return pgoff;
497497
}
498498

499+
/* This has the same layout as wait_bit_key - see fs/cachefiles/rdwr.c */
500+
struct wait_page_key {
501+
struct page *page;
502+
int bit_nr;
503+
int page_match;
504+
};
505+
506+
struct wait_page_queue {
507+
struct page *page;
508+
int bit_nr;
509+
wait_queue_entry_t wait;
510+
};
511+
512+
static inline int wake_page_match(struct wait_page_queue *wait_page,
513+
struct wait_page_key *key)
514+
{
515+
if (wait_page->page != key->page)
516+
return 0;
517+
key->page_match = 1;
518+
519+
if (wait_page->bit_nr != key->bit_nr)
520+
return 0;
521+
522+
/*
523+
* Stop walking if it's locked.
524+
* Is this safe if put_and_wait_on_page_locked() is in use?
525+
* Yes: the waker must hold a reference to this page, and if PG_locked
526+
* has now already been set by another task, that task must also hold
527+
* a reference to the *same usage* of this page; so there is no need
528+
* to walk on to wake even the put_and_wait_on_page_locked() callers.
529+
*/
530+
if (test_bit(key->bit_nr, &key->page->flags))
531+
return -1;
532+
533+
return 1;
534+
}
535+
499536
extern void __lock_page(struct page *page);
500537
extern int __lock_page_killable(struct page *page);
501538
extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm,

mm/filemap.c

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -987,43 +987,16 @@ void __init pagecache_init(void)
987987
page_writeback_init();
988988
}
989989

990-
/* This has the same layout as wait_bit_key - see fs/cachefiles/rdwr.c */
991-
struct wait_page_key {
992-
struct page *page;
993-
int bit_nr;
994-
int page_match;
995-
};
996-
997-
struct wait_page_queue {
998-
struct page *page;
999-
int bit_nr;
1000-
wait_queue_entry_t wait;
1001-
};
1002-
1003990
static int wake_page_function(wait_queue_entry_t *wait, unsigned mode, int sync, void *arg)
1004991
{
1005992
struct wait_page_key *key = arg;
1006993
struct wait_page_queue *wait_page
1007994
= container_of(wait, struct wait_page_queue, wait);
995+
int ret;
1008996

1009-
if (wait_page->page != key->page)
1010-
return 0;
1011-
key->page_match = 1;
1012-
1013-
if (wait_page->bit_nr != key->bit_nr)
1014-
return 0;
1015-
1016-
/*
1017-
* Stop walking if it's locked.
1018-
* Is this safe if put_and_wait_on_page_locked() is in use?
1019-
* Yes: the waker must hold a reference to this page, and if PG_locked
1020-
* has now already been set by another task, that task must also hold
1021-
* a reference to the *same usage* of this page; so there is no need
1022-
* to walk on to wake even the put_and_wait_on_page_locked() callers.
1023-
*/
1024-
if (test_bit(key->bit_nr, &key->page->flags))
1025-
return -1;
1026-
997+
ret = wake_page_match(wait_page, key);
998+
if (ret != 1)
999+
return ret;
10271000
return autoremove_wake_function(wait, mode, sync, key);
10281001
}
10291002

0 commit comments

Comments
 (0)