No functional changes in this patch, just in preparation for allowing more callers.
Unified · Split
| @@ -496,6 +496,43 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma, · 495 unmodified lines | ||
| 496 | 496 | return pgoff; |
| 497 | 497 | } |
| 498 | 498 | |
| 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 | + | |
| 499 | 536 | extern void __lock_page(struct page *page); |
| 500 | 537 | extern int __lock_page_killable(struct page *page); |
| 501 | 538 | extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm, |
| @@ -987,43 +987,16 @@ void __init pagecache_init(void) · 986 unmodified lines | ||
| 987 | 987 | page_writeback_init(); |
| 988 | 988 | } |
| 989 | 989 | |
| 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 | − | |
| 1003 | 990 | static int wake_page_function(wait_queue_entry_t *wait, unsigned mode, int sync, void *arg) |
| 1004 | 991 | { |
| 1005 | 992 | struct wait_page_key *key = arg; |
| 1006 | 993 | struct wait_page_queue *wait_page |
| 1007 | 994 | = container_of(wait, struct wait_page_queue, wait); |
| 995 | + int ret; | |
| 1008 | 996 | |
| 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; | |
| 1027 | 1000 | return autoremove_wake_function(wait, mode, sync, key); |
| 1028 | 1001 | } |
| 1029 | 1002 | |