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

Showing the changes to include/linux (1 of 2 files). Show all

Unified · Split

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,