All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ralph Campbell <rcampbell@nvidia.com>
To: Christoph Hellwig <hch@lst.de>
Cc: <linux-mm@kvack.org>, <kvm-ppc@vger.kernel.org>,
	<nouveau@lists.freedesktop.org>, <linux-kernel@vger.kernel.org>,
	Dan Williams <dan.j.williams@intel.com>,
	Ira Weiny <ira.weiny@intel.com>,
	Matthew Wilcox <willy@infradead.org>,
	Jerome Glisse <jglisse@redhat.com>,
	John Hubbard <jhubbard@nvidia.com>,
	Alistair Popple <apopple@nvidia.com>,
	Jason Gunthorpe <jgg@nvidia.com>,
	Bharata B Rao <bharata@linux.ibm.com>, Zi Yan <ziy@nvidia.com>,
	"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>,
	Yang Shi <yang.shi@linux.alibaba.com>,
	Paul Mackerras <paulus@ozlabs.org>,
	Ben Skeggs <bskeggs@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH 2/2] mm: remove extra ZONE_DEVICE struct page refcount
Date: Mon, 28 Sep 2020 15:29:24 -0700	[thread overview]
Message-ID: <78746c2f-4bbb-886f-6eb6-0daffab8be3f@nvidia.com> (raw)
In-Reply-To: <20200926064116.GB3540@lst.de>


On 9/25/20 11:41 PM, Christoph Hellwig wrote:
> On Fri, Sep 25, 2020 at 01:44:42PM -0700, Ralph Campbell wrote:
>> ZONE_DEVICE struct pages have an extra reference count that complicates the
>> code for put_page() and several places in the kernel that need to check the
>> reference count to see that a page is not being used (gup, compaction,
>> migration, etc.). Clean up the code so the reference count doesn't need to
>> be treated specially for ZONE_DEVICE.
>>
>> Signed-off-by: Ralph Campbell <rcampbell@nvidia.com>
>> ---
>>   arch/powerpc/kvm/book3s_hv_uvmem.c     |  2 +-
>>   drivers/gpu/drm/nouveau/nouveau_dmem.c |  2 +-
>>   include/linux/dax.h                    |  2 +-
>>   include/linux/memremap.h               |  7 ++-
>>   include/linux/mm.h                     | 44 --------------
>>   lib/test_hmm.c                         |  2 +-
>>   mm/gup.c                               | 44 --------------
>>   mm/internal.h                          |  8 +++
>>   mm/memremap.c                          | 82 ++++++--------------------
>>   mm/migrate.c                           |  5 --
>>   mm/page_alloc.c                        |  3 +
>>   mm/swap.c                              | 46 +++------------
>>   12 files changed, 44 insertions(+), 203 deletions(-)
>>
>> diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c
>> index 7705d5557239..e6ec98325fab 100644
>> --- a/arch/powerpc/kvm/book3s_hv_uvmem.c
>> +++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
>> @@ -711,7 +711,7 @@ static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm)
>>   
>>   	dpage = pfn_to_page(uvmem_pfn);
>>   	dpage->zone_device_data = pvt;
>> -	get_page(dpage);
>> +	init_page_count(dpage);
>>   	lock_page(dpage);
>>   	return dpage;
>>   out_clear:
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c
>> index 4e8112fde3e6..ca2e3c3edc36 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
>> @@ -323,7 +323,7 @@ nouveau_dmem_page_alloc_locked(struct nouveau_drm *drm)
>>   			return NULL;
>>   	}
>>   
>> -	get_page(page);
>> +	init_page_count(page);
>>   	lock_page(page);
>>   	return page;
>>   }
>> diff --git a/include/linux/dax.h b/include/linux/dax.h
>> index 3f78ed78d1d6..8d29f38645aa 100644
>> --- a/include/linux/dax.h
>> +++ b/include/linux/dax.h
>> @@ -240,7 +240,7 @@ static inline bool dax_mapping(struct address_space *mapping)
>>   
>>   static inline bool dax_layout_is_idle_page(struct page *page)
>>   {
>> -	return page_ref_count(page) <= 1;
>> +	return page_ref_count(page) == 0;
>>   }
>>   
>>   #endif
>> diff --git a/include/linux/memremap.h b/include/linux/memremap.h
>> index e5862746751b..f9224f88e4cd 100644
>> --- a/include/linux/memremap.h
>> +++ b/include/linux/memremap.h
>> @@ -65,9 +65,10 @@ enum memory_type {
>>   
>>   struct dev_pagemap_ops {
>>   	/*
>> -	 * Called once the page refcount reaches 1.  (ZONE_DEVICE pages never
>> -	 * reach 0 refcount unless there is a refcount bug. This allows the
>> -	 * device driver to implement its own memory management.)
>> +	 * Called once the page refcount reaches 0. The reference count
>> +	 * should be reset to one with init_page_count(page) before reusing
>> +	 * the page. This allows the device driver to implement its own
>> +	 * memory management.
>>   	 */
>>   	void (*page_free)(struct page *page);
>>   
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index b2f370f0b420..2159c2477aa3 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -1092,39 +1092,6 @@ static inline bool is_zone_device_page(const struct page *page)
>>   }
>>   #endif
>>   
>> -#ifdef CONFIG_DEV_PAGEMAP_OPS
>> -void free_devmap_managed_page(struct page *page);
>> -DECLARE_STATIC_KEY_FALSE(devmap_managed_key);
>> -
>> -static inline bool page_is_devmap_managed(struct page *page)
>> -{
>> -	if (!static_branch_unlikely(&devmap_managed_key))
>> -		return false;
>> -	if (!is_zone_device_page(page))
>> -		return false;
>> -	switch (page->pgmap->type) {
>> -	case MEMORY_DEVICE_PRIVATE:
>> -	case MEMORY_DEVICE_FS_DAX:
>> -		return true;
>> -	default:
>> -		break;
>> -	}
>> -	return false;
>> -}
>> -
>> -void put_devmap_managed_page(struct page *page);
>> -
>> -#else /* CONFIG_DEV_PAGEMAP_OPS */
>> -static inline bool page_is_devmap_managed(struct page *page)
>> -{
>> -	return false;
>> -}
>> -
>> -static inline void put_devmap_managed_page(struct page *page)
>> -{
>> -}
>> -#endif /* CONFIG_DEV_PAGEMAP_OPS */
>> -
>>   static inline bool is_device_private_page(const struct page *page)
>>   {
>>   	return IS_ENABLED(CONFIG_DEV_PAGEMAP_OPS) &&
>> @@ -1171,17 +1138,6 @@ static inline void put_page(struct page *page)
>>   {
>>   	page = compound_head(page);
>>   
>> -	/*
>> -	 * For devmap managed pages we need to catch refcount transition from
>> -	 * 2 to 1, when refcount reach one it means the page is free and we
>> -	 * need to inform the device driver through callback. See
>> -	 * include/linux/memremap.h and HMM for details.
>> -	 */
>> -	if (page_is_devmap_managed(page)) {
>> -		put_devmap_managed_page(page);
>> -		return;
>> -	}
>> -
>>   	if (put_page_testzero(page))
>>   		__put_page(page);
>>   }
>> diff --git a/lib/test_hmm.c b/lib/test_hmm.c
>> index e7dc3de355b7..1033b19c9c52 100644
>> --- a/lib/test_hmm.c
>> +++ b/lib/test_hmm.c
>> @@ -561,7 +561,7 @@ static struct page *dmirror_devmem_alloc_page(struct dmirror_device *mdevice)
>>   	}
>>   
>>   	dpage->zone_device_data = rpage;
>> -	get_page(dpage);
>> +	init_page_count(dpage);
>>   	lock_page(dpage);
>>   	return dpage;
>>   
> 
> Doesn't test_hmm also need to reinitialize the refcount before freeing
> the page in hmm_dmirror_exit?

The dmirror_zero_page is dead code, it isn't used. There is a patch queued in
linux-mm which removes it. Besides, it was allocated with alloc_page() so it
isn't a device private struct page.

>>   	int error, is_ram;
>> -	bool need_devmap_managed = true;
>>   
>>   	switch (pgmap->type) {
>>   	case MEMORY_DEVICE_PRIVATE:
>> @@ -217,11 +171,9 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid)
>>   		}
>>   		break;
>>   	case MEMORY_DEVICE_GENERIC:
> 
> The MEMORY_DEVICE_PRIVATE cases loses the sanity check that the
> page_free method is set.

I'll add that back into memremap_pages() with other sanity checks in v3.

> Otherwise this looks good.

Thanks!

WARNING: multiple messages have this Message-ID (diff)
From: Ralph Campbell <rcampbell-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
To: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
Cc: Yang Shi
	<yang.shi-KPsoFbNs7GizrGE5bRqYAgC/G2K4zDHf@public.gmane.org>,
	Zi Yan <ziy-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
	nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	Alistair Popple <apopple-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Bharata B Rao <bharata-tEXmvtCZX7AybS5Ee8rs3A@public.gmane.org>,
	Paul Mackerras <paulus-mnsaURCQ41sdnm+yROfE0A@public.gmane.org>,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org,
	Matthew Wilcox <willy-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
	Jason Gunthorpe <jgg-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
	Dan Williams
	<dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	Ira Weiny <ira.weiny-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	Andrew Morton
	<akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>,
	"Kirill A . Shutemov"
	<kirill.shutemov-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>,
	Ben Skeggs <bskeggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Subject: Re: [PATCH 2/2] mm: remove extra ZONE_DEVICE struct page refcount
Date: Mon, 28 Sep 2020 15:29:24 -0700	[thread overview]
Message-ID: <78746c2f-4bbb-886f-6eb6-0daffab8be3f@nvidia.com> (raw)
In-Reply-To: <20200926064116.GB3540-jcswGhMUV9g@public.gmane.org>


On 9/25/20 11:41 PM, Christoph Hellwig wrote:
> On Fri, Sep 25, 2020 at 01:44:42PM -0700, Ralph Campbell wrote:
>> ZONE_DEVICE struct pages have an extra reference count that complicates the
>> code for put_page() and several places in the kernel that need to check the
>> reference count to see that a page is not being used (gup, compaction,
>> migration, etc.). Clean up the code so the reference count doesn't need to
>> be treated specially for ZONE_DEVICE.
>>
>> Signed-off-by: Ralph Campbell <rcampbell-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>> ---
>>   arch/powerpc/kvm/book3s_hv_uvmem.c     |  2 +-
>>   drivers/gpu/drm/nouveau/nouveau_dmem.c |  2 +-
>>   include/linux/dax.h                    |  2 +-
>>   include/linux/memremap.h               |  7 ++-
>>   include/linux/mm.h                     | 44 --------------
>>   lib/test_hmm.c                         |  2 +-
>>   mm/gup.c                               | 44 --------------
>>   mm/internal.h                          |  8 +++
>>   mm/memremap.c                          | 82 ++++++--------------------
>>   mm/migrate.c                           |  5 --
>>   mm/page_alloc.c                        |  3 +
>>   mm/swap.c                              | 46 +++------------
>>   12 files changed, 44 insertions(+), 203 deletions(-)
>>
>> diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c
>> index 7705d5557239..e6ec98325fab 100644
>> --- a/arch/powerpc/kvm/book3s_hv_uvmem.c
>> +++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
>> @@ -711,7 +711,7 @@ static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm)
>>   
>>   	dpage = pfn_to_page(uvmem_pfn);
>>   	dpage->zone_device_data = pvt;
>> -	get_page(dpage);
>> +	init_page_count(dpage);
>>   	lock_page(dpage);
>>   	return dpage;
>>   out_clear:
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c
>> index 4e8112fde3e6..ca2e3c3edc36 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
>> @@ -323,7 +323,7 @@ nouveau_dmem_page_alloc_locked(struct nouveau_drm *drm)
>>   			return NULL;
>>   	}
>>   
>> -	get_page(page);
>> +	init_page_count(page);
>>   	lock_page(page);
>>   	return page;
>>   }
>> diff --git a/include/linux/dax.h b/include/linux/dax.h
>> index 3f78ed78d1d6..8d29f38645aa 100644
>> --- a/include/linux/dax.h
>> +++ b/include/linux/dax.h
>> @@ -240,7 +240,7 @@ static inline bool dax_mapping(struct address_space *mapping)
>>   
>>   static inline bool dax_layout_is_idle_page(struct page *page)
>>   {
>> -	return page_ref_count(page) <= 1;
>> +	return page_ref_count(page) == 0;
>>   }
>>   
>>   #endif
>> diff --git a/include/linux/memremap.h b/include/linux/memremap.h
>> index e5862746751b..f9224f88e4cd 100644
>> --- a/include/linux/memremap.h
>> +++ b/include/linux/memremap.h
>> @@ -65,9 +65,10 @@ enum memory_type {
>>   
>>   struct dev_pagemap_ops {
>>   	/*
>> -	 * Called once the page refcount reaches 1.  (ZONE_DEVICE pages never
>> -	 * reach 0 refcount unless there is a refcount bug. This allows the
>> -	 * device driver to implement its own memory management.)
>> +	 * Called once the page refcount reaches 0. The reference count
>> +	 * should be reset to one with init_page_count(page) before reusing
>> +	 * the page. This allows the device driver to implement its own
>> +	 * memory management.
>>   	 */
>>   	void (*page_free)(struct page *page);
>>   
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index b2f370f0b420..2159c2477aa3 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -1092,39 +1092,6 @@ static inline bool is_zone_device_page(const struct page *page)
>>   }
>>   #endif
>>   
>> -#ifdef CONFIG_DEV_PAGEMAP_OPS
>> -void free_devmap_managed_page(struct page *page);
>> -DECLARE_STATIC_KEY_FALSE(devmap_managed_key);
>> -
>> -static inline bool page_is_devmap_managed(struct page *page)
>> -{
>> -	if (!static_branch_unlikely(&devmap_managed_key))
>> -		return false;
>> -	if (!is_zone_device_page(page))
>> -		return false;
>> -	switch (page->pgmap->type) {
>> -	case MEMORY_DEVICE_PRIVATE:
>> -	case MEMORY_DEVICE_FS_DAX:
>> -		return true;
>> -	default:
>> -		break;
>> -	}
>> -	return false;
>> -}
>> -
>> -void put_devmap_managed_page(struct page *page);
>> -
>> -#else /* CONFIG_DEV_PAGEMAP_OPS */
>> -static inline bool page_is_devmap_managed(struct page *page)
>> -{
>> -	return false;
>> -}
>> -
>> -static inline void put_devmap_managed_page(struct page *page)
>> -{
>> -}
>> -#endif /* CONFIG_DEV_PAGEMAP_OPS */
>> -
>>   static inline bool is_device_private_page(const struct page *page)
>>   {
>>   	return IS_ENABLED(CONFIG_DEV_PAGEMAP_OPS) &&
>> @@ -1171,17 +1138,6 @@ static inline void put_page(struct page *page)
>>   {
>>   	page = compound_head(page);
>>   
>> -	/*
>> -	 * For devmap managed pages we need to catch refcount transition from
>> -	 * 2 to 1, when refcount reach one it means the page is free and we
>> -	 * need to inform the device driver through callback. See
>> -	 * include/linux/memremap.h and HMM for details.
>> -	 */
>> -	if (page_is_devmap_managed(page)) {
>> -		put_devmap_managed_page(page);
>> -		return;
>> -	}
>> -
>>   	if (put_page_testzero(page))
>>   		__put_page(page);
>>   }
>> diff --git a/lib/test_hmm.c b/lib/test_hmm.c
>> index e7dc3de355b7..1033b19c9c52 100644
>> --- a/lib/test_hmm.c
>> +++ b/lib/test_hmm.c
>> @@ -561,7 +561,7 @@ static struct page *dmirror_devmem_alloc_page(struct dmirror_device *mdevice)
>>   	}
>>   
>>   	dpage->zone_device_data = rpage;
>> -	get_page(dpage);
>> +	init_page_count(dpage);
>>   	lock_page(dpage);
>>   	return dpage;
>>   
> 
> Doesn't test_hmm also need to reinitialize the refcount before freeing
> the page in hmm_dmirror_exit?

The dmirror_zero_page is dead code, it isn't used. There is a patch queued in
linux-mm which removes it. Besides, it was allocated with alloc_page() so it
isn't a device private struct page.

>>   	int error, is_ram;
>> -	bool need_devmap_managed = true;
>>   
>>   	switch (pgmap->type) {
>>   	case MEMORY_DEVICE_PRIVATE:
>> @@ -217,11 +171,9 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid)
>>   		}
>>   		break;
>>   	case MEMORY_DEVICE_GENERIC:
> 
> The MEMORY_DEVICE_PRIVATE cases loses the sanity check that the
> page_free method is set.

I'll add that back into memremap_pages() with other sanity checks in v3.

> Otherwise this looks good.

Thanks!

WARNING: multiple messages have this Message-ID (diff)
From: Ralph Campbell <rcampbell@nvidia.com>
To: Christoph Hellwig <hch@lst.de>
Cc: linux-mm@kvack.org, kvm-ppc@vger.kernel.org,
	nouveau@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	Dan Williams <dan.j.williams@intel.com>,
	Ira Weiny <ira.weiny@intel.com>,
	Matthew Wilcox <willy@infradead.org>,
	Jerome Glisse <jglisse@redhat.com>,
	John Hubbard <jhubbard@nvidia.com>,
	Alistair Popple <apopple@nvidia.com>,
	Jason Gunthorpe <jgg@nvidia.com>,
	Bharata B Rao <bharata@linux.ibm.com>, Zi Yan <ziy@nvidia.com>,
	"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>,
	Yang Shi <yang.shi@linux.alibaba.com>,
	Paul Mackerras <paulus@ozlabs.org>,
	Ben Skeggs <bskeggs@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH 2/2] mm: remove extra ZONE_DEVICE struct page refcount
Date: Mon, 28 Sep 2020 22:29:24 +0000	[thread overview]
Message-ID: <78746c2f-4bbb-886f-6eb6-0daffab8be3f@nvidia.com> (raw)
In-Reply-To: <20200926064116.GB3540@lst.de>


On 9/25/20 11:41 PM, Christoph Hellwig wrote:
> On Fri, Sep 25, 2020 at 01:44:42PM -0700, Ralph Campbell wrote:
>> ZONE_DEVICE struct pages have an extra reference count that complicates the
>> code for put_page() and several places in the kernel that need to check the
>> reference count to see that a page is not being used (gup, compaction,
>> migration, etc.). Clean up the code so the reference count doesn't need to
>> be treated specially for ZONE_DEVICE.
>>
>> Signed-off-by: Ralph Campbell <rcampbell@nvidia.com>
>> ---
>>   arch/powerpc/kvm/book3s_hv_uvmem.c     |  2 +-
>>   drivers/gpu/drm/nouveau/nouveau_dmem.c |  2 +-
>>   include/linux/dax.h                    |  2 +-
>>   include/linux/memremap.h               |  7 ++-
>>   include/linux/mm.h                     | 44 --------------
>>   lib/test_hmm.c                         |  2 +-
>>   mm/gup.c                               | 44 --------------
>>   mm/internal.h                          |  8 +++
>>   mm/memremap.c                          | 82 ++++++--------------------
>>   mm/migrate.c                           |  5 --
>>   mm/page_alloc.c                        |  3 +
>>   mm/swap.c                              | 46 +++------------
>>   12 files changed, 44 insertions(+), 203 deletions(-)
>>
>> diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c
>> index 7705d5557239..e6ec98325fab 100644
>> --- a/arch/powerpc/kvm/book3s_hv_uvmem.c
>> +++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
>> @@ -711,7 +711,7 @@ static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm)
>>   
>>   	dpage = pfn_to_page(uvmem_pfn);
>>   	dpage->zone_device_data = pvt;
>> -	get_page(dpage);
>> +	init_page_count(dpage);
>>   	lock_page(dpage);
>>   	return dpage;
>>   out_clear:
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c
>> index 4e8112fde3e6..ca2e3c3edc36 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
>> @@ -323,7 +323,7 @@ nouveau_dmem_page_alloc_locked(struct nouveau_drm *drm)
>>   			return NULL;
>>   	}
>>   
>> -	get_page(page);
>> +	init_page_count(page);
>>   	lock_page(page);
>>   	return page;
>>   }
>> diff --git a/include/linux/dax.h b/include/linux/dax.h
>> index 3f78ed78d1d6..8d29f38645aa 100644
>> --- a/include/linux/dax.h
>> +++ b/include/linux/dax.h
>> @@ -240,7 +240,7 @@ static inline bool dax_mapping(struct address_space *mapping)
>>   
>>   static inline bool dax_layout_is_idle_page(struct page *page)
>>   {
>> -	return page_ref_count(page) <= 1;
>> +	return page_ref_count(page) = 0;
>>   }
>>   
>>   #endif
>> diff --git a/include/linux/memremap.h b/include/linux/memremap.h
>> index e5862746751b..f9224f88e4cd 100644
>> --- a/include/linux/memremap.h
>> +++ b/include/linux/memremap.h
>> @@ -65,9 +65,10 @@ enum memory_type {
>>   
>>   struct dev_pagemap_ops {
>>   	/*
>> -	 * Called once the page refcount reaches 1.  (ZONE_DEVICE pages never
>> -	 * reach 0 refcount unless there is a refcount bug. This allows the
>> -	 * device driver to implement its own memory management.)
>> +	 * Called once the page refcount reaches 0. The reference count
>> +	 * should be reset to one with init_page_count(page) before reusing
>> +	 * the page. This allows the device driver to implement its own
>> +	 * memory management.
>>   	 */
>>   	void (*page_free)(struct page *page);
>>   
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index b2f370f0b420..2159c2477aa3 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -1092,39 +1092,6 @@ static inline bool is_zone_device_page(const struct page *page)
>>   }
>>   #endif
>>   
>> -#ifdef CONFIG_DEV_PAGEMAP_OPS
>> -void free_devmap_managed_page(struct page *page);
>> -DECLARE_STATIC_KEY_FALSE(devmap_managed_key);
>> -
>> -static inline bool page_is_devmap_managed(struct page *page)
>> -{
>> -	if (!static_branch_unlikely(&devmap_managed_key))
>> -		return false;
>> -	if (!is_zone_device_page(page))
>> -		return false;
>> -	switch (page->pgmap->type) {
>> -	case MEMORY_DEVICE_PRIVATE:
>> -	case MEMORY_DEVICE_FS_DAX:
>> -		return true;
>> -	default:
>> -		break;
>> -	}
>> -	return false;
>> -}
>> -
>> -void put_devmap_managed_page(struct page *page);
>> -
>> -#else /* CONFIG_DEV_PAGEMAP_OPS */
>> -static inline bool page_is_devmap_managed(struct page *page)
>> -{
>> -	return false;
>> -}
>> -
>> -static inline void put_devmap_managed_page(struct page *page)
>> -{
>> -}
>> -#endif /* CONFIG_DEV_PAGEMAP_OPS */
>> -
>>   static inline bool is_device_private_page(const struct page *page)
>>   {
>>   	return IS_ENABLED(CONFIG_DEV_PAGEMAP_OPS) &&
>> @@ -1171,17 +1138,6 @@ static inline void put_page(struct page *page)
>>   {
>>   	page = compound_head(page);
>>   
>> -	/*
>> -	 * For devmap managed pages we need to catch refcount transition from
>> -	 * 2 to 1, when refcount reach one it means the page is free and we
>> -	 * need to inform the device driver through callback. See
>> -	 * include/linux/memremap.h and HMM for details.
>> -	 */
>> -	if (page_is_devmap_managed(page)) {
>> -		put_devmap_managed_page(page);
>> -		return;
>> -	}
>> -
>>   	if (put_page_testzero(page))
>>   		__put_page(page);
>>   }
>> diff --git a/lib/test_hmm.c b/lib/test_hmm.c
>> index e7dc3de355b7..1033b19c9c52 100644
>> --- a/lib/test_hmm.c
>> +++ b/lib/test_hmm.c
>> @@ -561,7 +561,7 @@ static struct page *dmirror_devmem_alloc_page(struct dmirror_device *mdevice)
>>   	}
>>   
>>   	dpage->zone_device_data = rpage;
>> -	get_page(dpage);
>> +	init_page_count(dpage);
>>   	lock_page(dpage);
>>   	return dpage;
>>   
> 
> Doesn't test_hmm also need to reinitialize the refcount before freeing
> the page in hmm_dmirror_exit?

The dmirror_zero_page is dead code, it isn't used. There is a patch queued in
linux-mm which removes it. Besides, it was allocated with alloc_page() so it
isn't a device private struct page.

>>   	int error, is_ram;
>> -	bool need_devmap_managed = true;
>>   
>>   	switch (pgmap->type) {
>>   	case MEMORY_DEVICE_PRIVATE:
>> @@ -217,11 +171,9 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid)
>>   		}
>>   		break;
>>   	case MEMORY_DEVICE_GENERIC:
> 
> The MEMORY_DEVICE_PRIVATE cases loses the sanity check that the
> page_free method is set.

I'll add that back into memremap_pages() with other sanity checks in v3.

> Otherwise this looks good.

Thanks!

  reply	other threads:[~2020-09-28 23:40 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-25 20:44 [RFC PATCH v2 0/2] mm: remove extra ZONE_DEVICE struct page refcount Ralph Campbell
2020-09-25 20:44 ` Ralph Campbell
2020-09-25 20:44 ` Ralph Campbell
2020-09-25 20:44 ` [PATCH 1/2] ext4/xfs: add page refcount helper Ralph Campbell
2020-09-25 20:44   ` Ralph Campbell
2020-09-25 20:44   ` Ralph Campbell
2020-09-25 20:51   ` Dan Williams
2020-09-25 20:51     ` Dan Williams
2020-09-25 20:51     ` Dan Williams
2020-09-25 21:17     ` Ralph Campbell
2020-09-25 21:17       ` Ralph Campbell
2020-09-25 21:17       ` Ralph Campbell
2020-09-26  6:35   ` Christoph Hellwig
2020-09-26  6:35     ` Christoph Hellwig
2020-09-28 22:20     ` Ralph Campbell
2020-09-28 22:20       ` Ralph Campbell
2020-09-28 22:20       ` Ralph Campbell
2020-09-25 20:44 ` [PATCH 2/2] mm: remove extra ZONE_DEVICE struct page refcount Ralph Campbell
2020-09-25 20:44   ` Ralph Campbell
2020-09-25 20:44   ` Ralph Campbell
2020-09-26  6:41   ` Christoph Hellwig
2020-09-26  6:41     ` Christoph Hellwig
2020-09-28 22:29     ` Ralph Campbell [this message]
2020-09-28 22:29       ` Ralph Campbell
2020-09-28 22:29       ` Ralph Campbell
2020-09-29  2:59   ` Bharata B Rao
2020-09-29  3:11     ` Bharata B Rao
2020-09-29  2:59     ` Bharata B Rao

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=78746c2f-4bbb-886f-6eb6-0daffab8be3f@nvidia.com \
    --to=rcampbell@nvidia.com \
    --cc=akpm@linux-foundation.org \
    --cc=apopple@nvidia.com \
    --cc=bharata@linux.ibm.com \
    --cc=bskeggs@redhat.com \
    --cc=dan.j.williams@intel.com \
    --cc=hch@lst.de \
    --cc=ira.weiny@intel.com \
    --cc=jgg@nvidia.com \
    --cc=jglisse@redhat.com \
    --cc=jhubbard@nvidia.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=kvm-ppc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=nouveau@lists.freedesktop.org \
    --cc=paulus@ozlabs.org \
    --cc=willy@infradead.org \
    --cc=yang.shi@linux.alibaba.com \
    --cc=ziy@nvidia.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.