History

mm: abstract out wake_page_match() from wake_page_function()

No functional changes in this patch, just in preparation for allowing more callers.

Jens Axboe committed 6 years ago

Commit c7510ab1 parent 2e85abf2 files · +41 −31Browse files

Unified · Split

2 files
  1. include/linux/pagemap.h +37 −0
  2. mm/filemap.c +4 −31
include/linux/pagemap.h+37−0
@@ -496,6 +496,43 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma, · 495 unmodified lines
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+4−31
@@ -987,43 +987,16 @@ void __init pagecache_init(void) · 986 unmodified lines
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