Re: [patch 041/178] mm: provide filemap_range_needs_writeback() helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2/19/24 2:59 PM, Matthew Wilcox wrote:
> On Sun, May 09, 2021 at 08:40:25PM +0100, Matthew Wilcox wrote:
>> On Fri, Apr 30, 2021 at 09:50:29AM -0700, Linus Torvalds wrote:
>>> On Thu, Apr 29, 2021 at 10:55 PM Andrew Morton
>>> <akpm@xxxxxxxxxxxxxxxxxxxx> wrote:
>>>> +       rcu_read_lock();
>>>> +       xas_for_each(&xas, page, max) {
>>>> +               if (xas_retry(&xas, page))
>>>> +                       continue;
>>>> +               if (xa_is_value(page))
>>>> +                       continue;
>>>> +               if (PageDirty(page) || PageLocked(page) || PageWriteback(page))
>>>> +                       break;
>>>> +       }
>>>> +       rcu_read_unlock();
>>>
>>> Whee. This looks very very expensive indeed.
>>>
>>> Why is is going to each page, why does it care about locked when the
>>> simple early cases did not?
>>
>> I was hoping Jens would answer this, but I guess he missed it so far.
>> I don't know why it now cares about whether the page is locked or not.
>> I presume it's not even the slightest bit slow for Jens because the
>> common case is that there are no pages in the range, and so we never
>> check any pages.
> 
> Looking at this again, since the change to operate on folios, we're now
> living dangerously as we don't have a reference on the folio, so it can
> now be freed, turned into a tail page and trigger the VM_BUG_ON_PGFLAGS()
> in folio_flags().
> 
> Rather than take a refcount on the folio to prevent that from happening,
> we can just examine the pagecache flags in the XArray. like this.
> Assuming there really isn't a need to check the locked flag (which for
> obvious reasons we don't mirror into the xarray marks).
> 
> Jens, WDYT?
> 
> diff --git a/mm/filemap.c b/mm/filemap.c
> index 750e779c23db..09f3851157f9 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -640,10 +640,8 @@ bool filemap_range_has_writeback(struct address_space *mapping,
>  	xas_for_each(&xas, folio, max) {
>  		if (xas_retry(&xas, folio))
>  			continue;
> -		if (xa_is_value(folio))
> -			continue;
> -		if (folio_test_dirty(folio) || folio_test_locked(folio) ||
> -				folio_test_writeback(folio))
> +		if (xas_get_mark(&xas, PAGECACHE_TAG_DIRTY) ||
> +		    xas_get_mark(&xas, PAGECACHE_TAG_WRITEBACK))
>  			break;
>  	}
>  	rcu_read_unlock();

Blast from the past, guess I did miss it back then. This looks a lot
more reasonable to me, also in terms of overhead, compared to the
previous one.

Heading out for the rest of the week tomorrow morning, but I can give it
a test spin as well once I'm back.

-- 
Jens Axboe





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux