All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Shiyang Ruan <ruansy.fnst@fujitsu.com>
Cc: linux-kernel@vger.kernel.org, linux-xfs@vger.kernel.org,
	nvdimm@lists.linux.dev, linux-mm@kvack.org,
	linux-fsdevel@vger.kernel.org, dan.j.williams@intel.com,
	david@fromorbit.com, hch@infradead.org, jane.chu@oracle.com
Subject: Re: [PATCH v13 7/7] fsdax: set a CoW flag when associate reflink mappings
Date: Wed, 20 Apr 2022 10:35:44 -0700	[thread overview]
Message-ID: <20220420173544.GU17025@magnolia> (raw)
In-Reply-To: <20220419045045.1664996-8-ruansy.fnst@fujitsu.com>

On Tue, Apr 19, 2022 at 12:50:45PM +0800, Shiyang Ruan wrote:
> Introduce a PAGE_MAPPING_DAX_COW flag to support association with CoW file
> mappings.  In this case, since the dax-rmap has already took the
> responsibility to look up for shared files by given dax page,
> the page->mapping is no longer to used for rmap but for marking that
> this dax page is shared.  And to make sure disassociation works fine, we
> use page->index as refcount, and clear page->mapping to the initial
> state when page->index is decreased to 0.
> 
> With the help of this new flag, it is able to distinguish normal case
> and CoW case, and keep the warning in normal case.
> 
> ==
> PS: The @cow added for dax_associate_entry(), is used to let it know
> whether the entry is to be shared during iomap operation.  It is decided
> by iomap,srcmap's flag, and will be used in another patchset(
> fsdax,xfs: Add reflink&dedupe support for fsdax[1]).
> 
> In this patch, we set @cow always false for now.
> 
> [1] https://lore.kernel.org/linux-xfs/20210928062311.4012070-1-ruansy.fnst@fujitsu.com/
> ==
> 
> Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com>
> ---
>  fs/dax.c                   | 50 +++++++++++++++++++++++++++++++-------
>  include/linux/page-flags.h |  6 +++++
>  2 files changed, 47 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/dax.c b/fs/dax.c
> index 57efd3f73655..4d3dfc8bee33 100644
> --- a/fs/dax.c
> +++ b/fs/dax.c
> @@ -334,13 +334,35 @@ static unsigned long dax_end_pfn(void *entry)
>  	for (pfn = dax_to_pfn(entry); \
>  			pfn < dax_end_pfn(entry); pfn++)
>  
> +static inline bool dax_mapping_is_cow(struct address_space *mapping)
> +{
> +	return (unsigned long)mapping == PAGE_MAPPING_DAX_COW;
> +}
> +
>  /*
> - * TODO: for reflink+dax we need a way to associate a single page with
> - * multiple address_space instances at different linear_page_index()
> - * offsets.
> + * Set the page->mapping with FS_DAX_MAPPING_COW flag, increase the refcount.
> + */
> +static inline void dax_mapping_set_cow(struct page *page)
> +{
> +	if ((uintptr_t)page->mapping != PAGE_MAPPING_DAX_COW) {
> +		/*
> +		 * Reset the index if the page was already mapped
> +		 * regularly before.
> +		 */
> +		if (page->mapping)
> +			page->index = 1;
> +		page->mapping = (void *)PAGE_MAPPING_DAX_COW;
> +	}
> +	page->index++;
> +}
> +
> +/*
> + * When it is called in dax_insert_entry(), the cow flag will indicate that
> + * whether this entry is shared by multiple files.  If so, set the page->mapping
> + * FS_DAX_MAPPING_COW, and use page->index as refcount.
>   */
>  static void dax_associate_entry(void *entry, struct address_space *mapping,
> -		struct vm_area_struct *vma, unsigned long address)
> +		struct vm_area_struct *vma, unsigned long address, bool cow)
>  {
>  	unsigned long size = dax_entry_size(entry), pfn, index;
>  	int i = 0;
> @@ -352,9 +374,13 @@ static void dax_associate_entry(void *entry, struct address_space *mapping,
>  	for_each_mapped_pfn(entry, pfn) {
>  		struct page *page = pfn_to_page(pfn);
>  
> -		WARN_ON_ONCE(page->mapping);
> -		page->mapping = mapping;
> -		page->index = index + i++;
> +		if (cow) {
> +			dax_mapping_set_cow(page);
> +		} else {
> +			WARN_ON_ONCE(page->mapping);
> +			page->mapping = mapping;
> +			page->index = index + i++;
> +		}
>  	}
>  }
>  
> @@ -370,7 +396,12 @@ static void dax_disassociate_entry(void *entry, struct address_space *mapping,
>  		struct page *page = pfn_to_page(pfn);
>  
>  		WARN_ON_ONCE(trunc && page_ref_count(page) > 1);
> -		WARN_ON_ONCE(page->mapping && page->mapping != mapping);
> +		if (dax_mapping_is_cow(page->mapping)) {
> +			/* keep the CoW flag if this page is still shared */
> +			if (page->index-- > 0)
> +				continue;
> +		} else
> +			WARN_ON_ONCE(page->mapping && page->mapping != mapping);
>  		page->mapping = NULL;
>  		page->index = 0;
>  	}
> @@ -829,7 +860,8 @@ static void *dax_insert_entry(struct xa_state *xas,
>  		void *old;
>  
>  		dax_disassociate_entry(entry, mapping, false);
> -		dax_associate_entry(new_entry, mapping, vmf->vma, vmf->address);
> +		dax_associate_entry(new_entry, mapping, vmf->vma, vmf->address,
> +				false);
>  		/*
>  		 * Only swap our new entry into the page cache if the current
>  		 * entry is a zero page or an empty entry.  If a normal PTE or
> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
> index d725a2d17806..5b601e375773 100644
> --- a/include/linux/page-flags.h
> +++ b/include/linux/page-flags.h
> @@ -650,6 +650,12 @@ __PAGEFLAG(Reported, reported, PF_NO_COMPOUND)
>  #define PAGE_MAPPING_KSM	(PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
>  #define PAGE_MAPPING_FLAGS	(PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
>  
> +/*
> + * Different with flags above, this flag is used only for fsdax mode.  It
> + * indicates that this page->mapping is now under reflink case.
> + */
> +#define PAGE_MAPPING_DAX_COW	0x1

The logic looks sound enough, I guess.

Though I do wonder -- if this were defined like this:

#define PAGE_MAPPING_DAX_COW	((struct address_space *)0x1)

Could you then avoid all uintptr_t/unsigned long casts above?

It's probably not worth holding up the whole patchset though, so
Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> +
>  static __always_inline int PageMappingFlags(struct page *page)
>  {
>  	return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) != 0;
> -- 
> 2.35.1
> 
> 
> 

  parent reply	other threads:[~2022-04-20 17:35 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-19  4:50 [PATCH v13 0/7] fsdax: introduce fs query to support reflink Shiyang Ruan
2022-04-19  4:50 ` [PATCH v13 1/7] dax: Introduce holder for dax_device Shiyang Ruan
2022-04-20 17:42   ` Darrick J. Wong
2022-04-19  4:50 ` [PATCH v13 2/7] mm: factor helpers for memory_failure_dev_pagemap Shiyang Ruan
2022-04-21  6:13   ` HORIGUCHI NAOYA(堀口 直也)
2022-04-21  8:10     ` Shiyang Ruan
2022-04-21  8:12     ` Miaohe Lin
2022-04-19  4:50 ` [PATCH v13 3/7] pagemap,pmem: Introduce ->memory_failure() Shiyang Ruan
2022-04-20 17:45   ` Darrick J. Wong
2022-04-21  6:54   ` HORIGUCHI NAOYA(堀口 直也)
2022-04-21  8:24   ` Miaohe Lin
2022-04-22  7:06     ` Shiyang Ruan
2022-04-24  2:00       ` Miaohe Lin
2022-04-19  4:50 ` [PATCH v13 4/7] fsdax: Introduce dax_lock_mapping_entry() Shiyang Ruan
2022-04-20 17:53   ` Darrick J. Wong
2022-04-19  4:50 ` [PATCH v13 5/7] mm: Introduce mf_dax_kill_procs() for fsdax case Shiyang Ruan
2022-04-20 17:58   ` Darrick J. Wong
2022-04-21  8:47   ` Miaohe Lin
2022-04-21 12:50   ` HORIGUCHI NAOYA(堀口 直也)
2022-04-19  4:50 ` [PATCH v13 6/7] xfs: Implement ->notify_failure() for XFS Shiyang Ruan
2022-04-19 15:38   ` Darrick J. Wong
2022-04-20  7:33     ` [PATCH v13.1 " Shiyang Ruan
2022-04-20 17:30       ` Darrick J. Wong
2022-04-19  4:50 ` [PATCH v13 7/7] fsdax: set a CoW flag when associate reflink mappings Shiyang Ruan
2022-04-19  7:27   ` Christoph Hellwig
2022-04-20 17:35   ` Darrick J. Wong [this message]
2022-04-21  1:20 ` [PATCH v13 0/7] fsdax: introduce fs query to support reflink Dave Chinner
2022-04-21  1:48   ` Shiyang Ruan
2022-04-21  2:20     ` Dan Williams
2022-04-21  4:35       ` Dave Chinner
2022-04-21  5:47         ` HORIGUCHI NAOYA(堀口 直也)
2022-04-21  5:54         ` Christoph Hellwig
2022-04-21  7:46           ` Dave Chinner
2022-04-22 21:27             ` Dan Williams
2022-04-23  0:01               ` Dave Chinner
2022-04-23 17:32                 ` Dan Williams

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=20220420173544.GU17025@magnolia \
    --to=djwong@kernel.org \
    --cc=dan.j.williams@intel.com \
    --cc=david@fromorbit.com \
    --cc=hch@infradead.org \
    --cc=jane.chu@oracle.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=nvdimm@lists.linux.dev \
    --cc=ruansy.fnst@fujitsu.com \
    /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.