diff options
Diffstat (limited to 'include/linux/memremap.h')
| -rw-r--r-- | include/linux/memremap.h | 56 | 
1 files changed, 38 insertions, 18 deletions
diff --git a/include/linux/memremap.h b/include/linux/memremap.h index c0e9d35889e8..8af304f6b504 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h @@ -1,6 +1,8 @@  /* SPDX-License-Identifier: GPL-2.0 */  #ifndef _LINUX_MEMREMAP_H_  #define _LINUX_MEMREMAP_H_ + +#include <linux/mm.h>  #include <linux/range.h>  #include <linux/ioport.h>  #include <linux/percpu-refcount.h> @@ -66,23 +68,13 @@ 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 will be +	 * reset to one by the core code after the method is called to prepare +	 * for handing out the page again.  	 */  	void (*page_free)(struct page *page);  	/* -	 * Transition the refcount in struct dev_pagemap to the dead state. -	 */ -	void (*kill)(struct dev_pagemap *pgmap); - -	/* -	 * Wait for refcount in struct dev_pagemap to be idle and reap it. -	 */ -	void (*cleanup)(struct dev_pagemap *pgmap); - -	/*  	 * Used for private (un-addressable) device memory only.  Must migrate  	 * the page back to a CPU accessible page.  	 */ @@ -95,10 +87,14 @@ struct dev_pagemap_ops {   * struct dev_pagemap - metadata for ZONE_DEVICE mappings   * @altmap: pre-allocated/reserved memory for vmemmap allocations   * @ref: reference count that pins the devm_memremap_pages() mapping - * @internal_ref: internal reference if @ref is not provided by the caller - * @done: completion for @internal_ref + * @done: completion for @ref   * @type: memory type: see MEMORY_* in memory_hotplug.h   * @flags: PGMAP_* flags to specify defailed behavior + * @vmemmap_shift: structural definition of how the vmemmap page metadata + *      is populated, specifically the metadata page order. + *	A zero value (default) uses base pages as the vmemmap metadata + *	representation. A bigger value will set up compound struct pages + *	of the requested order value.   * @ops: method table   * @owner: an opaque pointer identifying the entity that manages this   *	instance.  Used by various helpers to make sure that no @@ -109,11 +105,11 @@ struct dev_pagemap_ops {   */  struct dev_pagemap {  	struct vmem_altmap altmap; -	struct percpu_ref *ref; -	struct percpu_ref internal_ref; +	struct percpu_ref ref;  	struct completion done;  	enum memory_type type;  	unsigned int flags; +	unsigned long vmemmap_shift;  	const struct dev_pagemap_ops *ops;  	void *owner;  	int nr_range; @@ -130,6 +126,30 @@ static inline struct vmem_altmap *pgmap_altmap(struct dev_pagemap *pgmap)  	return NULL;  } +static inline unsigned long pgmap_vmemmap_nr(struct dev_pagemap *pgmap) +{ +	return 1 << pgmap->vmemmap_shift; +} + +static inline bool is_device_private_page(const struct page *page) +{ +	return IS_ENABLED(CONFIG_DEVICE_PRIVATE) && +		is_zone_device_page(page) && +		page->pgmap->type == MEMORY_DEVICE_PRIVATE; +} + +static inline bool folio_is_device_private(const struct folio *folio) +{ +	return is_device_private_page(&folio->page); +} + +static inline bool is_pci_p2pdma_page(const struct page *page) +{ +	return IS_ENABLED(CONFIG_PCI_P2PDMA) && +		is_zone_device_page(page) && +		page->pgmap->type == MEMORY_DEVICE_PCI_P2PDMA; +} +  #ifdef CONFIG_ZONE_DEVICE  void *memremap_pages(struct dev_pagemap *pgmap, int nid);  void memunmap_pages(struct dev_pagemap *pgmap); @@ -191,7 +211,7 @@ static inline unsigned long memremap_compat_align(void)  static inline void put_dev_pagemap(struct dev_pagemap *pgmap)  {  	if (pgmap) -		percpu_ref_put(pgmap->ref); +		percpu_ref_put(&pgmap->ref);  }  #endif /* _LINUX_MEMREMAP_H_ */  |