Messages in this thread Patch in this message | | | Date | Sun, 21 Mar 2021 10:53:09 +0000 | From | Matthew Wilcox <> | Subject | Re: [PATCH v4 02/28] mm: Add an unlock function for PG_private_2/PG_fscache |
| |
On Wed, Mar 10, 2021 at 04:54:49PM +0000, David Howells wrote: > Add a function, unlock_page_private_2(), to unlock PG_private_2 analogous > to that of PG_lock. Add a kerneldoc banner to that indicating the example > usage case.
One of the things which confused me about this was ... where's the other side? Where's lock_page_private_2()? Then I found this:
#ifdef CONFIG_AFS_FSCACHE if (PageFsCache(page) && wait_on_page_bit_killable(page, PG_fscache) < 0) return VM_FAULT_RETRY; #endif
Please respect the comment!
/* * This is exported only for wait_on_page_locked/wait_on_page_writeback, etc., * and should not be used directly. */ extern void wait_on_page_bit(struct page *page, int bit_nr); extern int wait_on_page_bit_killable(struct page *page, int bit_nr);
I think we need the exported API to be wait_on_page_private_2(), and AFS needs to not tinker in the guts of filemap. Otherwise you miss out on bugfixes like c2407cf7d22d0c0d94cf20342b3b8f06f1d904e7 (see also https://lore.kernel.org/linux-fsdevel/20210320054104.1300774-4-willy@infradead.org/T/#u ).
That also brings up that there is no set_page_private_2(). I think that's OK -- you only set PageFsCache() immediately after reading the page from the server. But I feel this "unlock_page_private_2" is actually "clear_page_private_2" -- ie it's equivalent to writeback, not to lock.
> +++ b/mm/filemap.c > @@ -1432,6 +1432,26 @@ void unlock_page(struct page *page) > } > EXPORT_SYMBOL(unlock_page); > > +/** > + * unlock_page_private_2 - Unlock a page that's locked with PG_private_2 > + * @page: The page > + * > + * Unlocks a page that's locked with PG_private_2 and wakes up sleepers in > + * wait_on_page_private_2(). > + * > + * This is, for example, used when a netfs page is being written to a local > + * disk cache, thereby allowing writes to the cache for the same page to be > + * serialised. > + */ > +void unlock_page_private_2(struct page *page) > +{ > + page = compound_head(page); > + VM_BUG_ON_PAGE(!PagePrivate2(page), page); > + clear_bit_unlock(PG_private_2, &page->flags); > + wake_up_page_bit(page, PG_private_2); > +} > +EXPORT_SYMBOL(unlock_page_private_2); > + > /**
| |