All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v3 16/22] btrfs: extent_io: implement try_release_extent_buffer() for subpage metadata support
Date: Wed, 6 Jan 2021 16:43:19 +0800	[thread overview]
Message-ID: <8b1e1a60-3ad1-54b0-b6c2-59c9eafc9440@suse.com> (raw)
In-Reply-To: <2c06bcbb-2aba-838f-e185-d2ce139fd170@suse.com>



On 2021/1/6 下午4:24, Qu Wenruo wrote:
> 
> 
> On 2021/1/6 上午9:01, Qu Wenruo wrote:
>> Unlike the original try_release_extent_buffer,
>> try_release_subpage_extent_buffer() will iterate through
>> btrfs_subpage::tree_block_bitmap, and try to release each extent buffer.
>>
>> Signed-off-by: Qu Wenruo <wqu@suse.com>
>> ---
>>   fs/btrfs/extent_io.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 76 insertions(+)
>>
>> diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
>> index 194cb8b63216..792264f5c3c2 100644
>> --- a/fs/btrfs/extent_io.c
>> +++ b/fs/btrfs/extent_io.c
>> @@ -6258,10 +6258,86 @@ void memmove_extent_buffer(const struct 
>> extent_buffer *dst,
>>       }
>>   }
>> +static int try_release_subpage_extent_buffer(struct page *page)
>> +{
>> +    struct btrfs_fs_info *fs_info = btrfs_sb(page->mapping->host->i_sb);
>> +    u64 page_start = page_offset(page);
>> +    int bitmap_size = BTRFS_SUBPAGE_BITMAP_SIZE;
>> +    int bit_start = 0;
>> +    int ret;
>> +
>> +    while (bit_start < bitmap_size) {
>> +        struct btrfs_subpage *subpage;
>> +        struct extent_buffer *eb;
>> +        unsigned long flags;
>> +        u16 tmp = 1 << bit_start;
>> +        u64 start;
>> +
>> +        /*
>> +         * Make sure the page still has private, as previous iteration
>> +         * can detach page private.
>> +         */
>> +        spin_lock(&page->mapping->private_lock);
>> +        if (!PagePrivate(page)) {
>> +            spin_unlock(&page->mapping->private_lock);
>> +            break;
>> +        }
>> +
>> +        subpage = (struct btrfs_subpage *)page->private;
>> +
>> +        spin_lock_irqsave(&subpage->lock, flags);
>> +        spin_unlock(&page->mapping->private_lock);
>> +
>> +        if (!(tmp & subpage->tree_block_bitmap))  {
>> +            spin_unlock_irqrestore(&subpage->lock, flags);
>> +            bit_start++;
>> +            continue;
>> +        }
>> +
>> +        start = bit_start * fs_info->sectorsize + page_start;
>> +        bit_start += fs_info->nodesize >> fs_info->sectorsize_bits;
>> +        /*
>> +         * Here we can't call find_extent_buffer() which will increase
>> +         * eb->refs.
>> +         */
>> +        rcu_read_lock();
>> +        eb = radix_tree_lookup(&fs_info->buffer_radix,
>> +                start >> fs_info->sectorsize_bits);
>> +        ASSERT(eb);
> 
> Another ASSERT() hit here. Surprised that I have never hit such case 
> before.
> 
> Since in releasse_extent_buffer(), radix tree is removed first, then 
> subpage tree_block_bitmap update, we could have cases where subpage 
> tree_block_bitmap is set but no eb in radix tree.
> 
> In that case, we can safely go next bit and re-check.
> 
> The function return value is only bounded to if the page has private bit 
> or not, so here we can safely continue.
> 
> Nik is right on this, we need better eb refs handling refactor, I'll 
> investigate more time to make the eb refs handling better.

The root problem here is, we have too many things to be synchronized for 
extent buffer.

We have eb::refs, eb::bflags (IN_TREE), buffer_radix, and the new 
subpage::tree_block_bitmap, they all need to be in sync with each other.

I'm wondering if we could find a good and clear enough way to handle 
extent buffers.

IMHO, we need to sacrifice some metadata performance (which is already 
poor enough), or there is really no better way to solve the mess...

Thanks,
Qu

> 
> Thanks,
> Qu
>> +        spin_lock(&eb->refs_lock);
>> +        if (atomic_read(&eb->refs) != 1 || extent_buffer_under_io(eb) ||
>> +            !test_and_clear_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) {
>> +            spin_unlock(&eb->refs_lock);
>> +            rcu_read_unlock();
>> +            continue;
>> +        }
>> +        rcu_read_unlock();
>> +        spin_unlock_irqrestore(&subpage->lock, flags);
>> +        /*
>> +         * Here we don't care the return value, we will always check
>> +         * the page private at the end.
>> +         * And release_extent_buffer() will release the refs_lock.
>> +         */
>> +        release_extent_buffer(eb);
>> +    }
>> +    /* Finally to check if we have cleared page private */
>> +    spin_lock(&page->mapping->private_lock);
>> +    if (!PagePrivate(page))
>> +        ret = 1;
>> +    else
>> +        ret = 0;
>> +    spin_unlock(&page->mapping->private_lock);
>> +    return ret;
>> +
>> +}
>> +
>>   int try_release_extent_buffer(struct page *page)
>>   {
>>       struct extent_buffer *eb;
>> +    if (btrfs_sb(page->mapping->host->i_sb)->sectorsize < PAGE_SIZE)
>> +        return try_release_subpage_extent_buffer(page);
>> +
>>       /*
>>        * We need to make sure nobody is attaching this page to an eb 
>> right
>>        * now.
>>
> 


  reply	other threads:[~2021-01-06  8:45 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-06  1:01 [PATCH v3 00/22] btrfs: add read-only support for subpage sector size Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 01/22] btrfs: extent_io: rename @offset parameter to @disk_bytenr for submit_extent_page() Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 02/22] btrfs: extent_io: refactor __extent_writepage_io() to improve readability Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 03/22] btrfs: file: update comment for btrfs_dirty_pages() Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 04/22] btrfs: extent_io: update locked page dirty/writeback/error bits in __process_pages_contig() Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 05/22] btrfs: extent_io: merge PAGE_CLEAR_DIRTY and PAGE_SET_WRITEBACK into PAGE_START_WRITEBACK Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 06/22] btrfs: extent_io: introduce a helper to grab an existing extent buffer from a page Qu Wenruo
2021-01-12 15:08   ` David Sterba
2021-01-06  1:01 ` [PATCH v3 07/22] btrfs: extent_io: introduce the skeleton of btrfs_subpage structure Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 08/22] btrfs: extent_io: make attach_extent_buffer_page() to handle subpage case Qu Wenruo
2021-01-06  6:54   ` Qu Wenruo
2021-01-07  1:35   ` Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 09/22] btrfs: extent_io: make grab_extent_buffer_from_page() " Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 10/22] btrfs: extent_io: support subpage for extent buffer page release Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 11/22] btrfs: extent_io: attach private to dummy extent buffer pages Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 12/22] btrfs: subpage: introduce helper for subpage uptodate status Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 13/22] btrfs: subpage: introduce helper for subpage error status Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 14/22] btrfs: extent_io: make set/clear_extent_buffer_uptodate() to support subpage size Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 15/22] btrfs: extent_io: make btrfs_clone_extent_buffer() to be subpage compatible Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 16/22] btrfs: extent_io: implement try_release_extent_buffer() for subpage metadata support Qu Wenruo
2021-01-06  8:24   ` Qu Wenruo
2021-01-06  8:43     ` Qu Wenruo [this message]
2021-01-06  1:01 ` [PATCH v3 17/22] btrfs: extent_io: introduce read_extent_buffer_subpage() Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 18/22] btrfs: extent_io: make endio_readpage_update_page_status() to handle subpage case Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 19/22] btrfs: disk-io: introduce subpage metadata validation check Qu Wenruo
2021-01-06  1:01 ` [PATCH v3 20/22] btrfs: introduce btrfs_subpage for data inodes Qu Wenruo
2021-01-06  5:04   ` kernel test robot
2021-01-06  5:04     ` kernel test robot
2021-01-06  5:32     ` Qu Wenruo
2021-01-06  6:48       ` Rong Chen
2021-01-06  6:48         ` Rong Chen
2021-01-09  9:53   ` kernel test robot
2021-01-09  9:53     ` kernel test robot
2021-01-06  1:02 ` [PATCH v3 21/22] btrfs: integrate page status update for read path into begin/end_page_read() Qu Wenruo
2021-01-06  1:02 ` [PATCH v3 22/22] btrfs: allow RO mount of 4K sector size fs on 64K page system Qu Wenruo
2021-01-12 15:14 ` [PATCH v3 00/22] btrfs: add read-only support for subpage sector size David Sterba
2021-01-13  5:06   ` Qu Wenruo
2021-01-06  3:59 [PATCH v3 16/22] btrfs: extent_io: implement try_release_extent_buffer() for subpage metadata support kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8b1e1a60-3ad1-54b0-b6c2-59c9eafc9440@suse.com \
    --to=wqu@suse.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.