~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/linux/memremap.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 #ifndef _LINUX_MEMREMAP_H_
  3 #define _LINUX_MEMREMAP_H_
  4 
  5 #include <linux/mmzone.h>
  6 #include <linux/range.h>
  7 #include <linux/ioport.h>
  8 #include <linux/percpu-refcount.h>
  9 
 10 struct resource;
 11 struct device;
 12 
 13 /**
 14  * struct vmem_altmap - pre-allocated storage for vmemmap_populate
 15  * @base_pfn: base of the entire dev_pagemap mapping
 16  * @reserve: pages mapped, but reserved for driver use (relative to @base)
 17  * @free: free pages set aside in the mapping for memmap storage
 18  * @align: pages reserved to meet allocation alignments
 19  * @alloc: track pages consumed, private to vmemmap_populate()
 20  */
 21 struct vmem_altmap {
 22         unsigned long base_pfn;
 23         const unsigned long end_pfn;
 24         const unsigned long reserve;
 25         unsigned long free;
 26         unsigned long align;
 27         unsigned long alloc;
 28         bool inaccessible;
 29 };
 30 
 31 /*
 32  * Specialize ZONE_DEVICE memory into multiple types each has a different
 33  * usage.
 34  *
 35  * MEMORY_DEVICE_PRIVATE:
 36  * Device memory that is not directly addressable by the CPU: CPU can neither
 37  * read nor write private memory. In this case, we do still have struct pages
 38  * backing the device memory. Doing so simplifies the implementation, but it is
 39  * important to remember that there are certain points at which the struct page
 40  * must be treated as an opaque object, rather than a "normal" struct page.
 41  *
 42  * A more complete discussion of unaddressable memory may be found in
 43  * include/linux/hmm.h and Documentation/mm/hmm.rst.
 44  *
 45  * MEMORY_DEVICE_COHERENT:
 46  * Device memory that is cache coherent from device and CPU point of view. This
 47  * is used on platforms that have an advanced system bus (like CAPI or CXL). A
 48  * driver can hotplug the device memory using ZONE_DEVICE and with that memory
 49  * type. Any page of a process can be migrated to such memory. However no one
 50  * should be allowed to pin such memory so that it can always be evicted.
 51  *
 52  * MEMORY_DEVICE_FS_DAX:
 53  * Host memory that has similar access semantics as System RAM i.e. DMA
 54  * coherent and supports page pinning. In support of coordinating page
 55  * pinning vs other operations MEMORY_DEVICE_FS_DAX arranges for a
 56  * wakeup event whenever a page is unpinned and becomes idle. This
 57  * wakeup is used to coordinate physical address space management (ex:
 58  * fs truncate/hole punch) vs pinned pages (ex: device dma).
 59  *
 60  * MEMORY_DEVICE_GENERIC:
 61  * Host memory that has similar access semantics as System RAM i.e. DMA
 62  * coherent and supports page pinning. This is for example used by DAX devices
 63  * that expose memory using a character device.
 64  *
 65  * MEMORY_DEVICE_PCI_P2PDMA:
 66  * Device memory residing in a PCI BAR intended for use with Peer-to-Peer
 67  * transactions.
 68  */
 69 enum memory_type {
 70         /* 0 is reserved to catch uninitialized type fields */
 71         MEMORY_DEVICE_PRIVATE = 1,
 72         MEMORY_DEVICE_COHERENT,
 73         MEMORY_DEVICE_FS_DAX,
 74         MEMORY_DEVICE_GENERIC,
 75         MEMORY_DEVICE_PCI_P2PDMA,
 76 };
 77 
 78 struct dev_pagemap_ops {
 79         /*
 80          * Called once the page refcount reaches 0.  The reference count will be
 81          * reset to one by the core code after the method is called to prepare
 82          * for handing out the page again.
 83          */
 84         void (*page_free)(struct page *page);
 85 
 86         /*
 87          * Used for private (un-addressable) device memory only.  Must migrate
 88          * the page back to a CPU accessible page.
 89          */
 90         vm_fault_t (*migrate_to_ram)(struct vm_fault *vmf);
 91 
 92         /*
 93          * Handle the memory failure happens on a range of pfns.  Notify the
 94          * processes who are using these pfns, and try to recover the data on
 95          * them if necessary.  The mf_flags is finally passed to the recover
 96          * function through the whole notify routine.
 97          *
 98          * When this is not implemented, or it returns -EOPNOTSUPP, the caller
 99          * will fall back to a common handler called mf_generic_kill_procs().
100          */
101         int (*memory_failure)(struct dev_pagemap *pgmap, unsigned long pfn,
102                               unsigned long nr_pages, int mf_flags);
103 };
104 
105 #define PGMAP_ALTMAP_VALID      (1 << 0)
106 
107 /**
108  * struct dev_pagemap - metadata for ZONE_DEVICE mappings
109  * @altmap: pre-allocated/reserved memory for vmemmap allocations
110  * @ref: reference count that pins the devm_memremap_pages() mapping
111  * @done: completion for @ref
112  * @type: memory type: see MEMORY_* above in memremap.h
113  * @flags: PGMAP_* flags to specify defailed behavior
114  * @vmemmap_shift: structural definition of how the vmemmap page metadata
115  *      is populated, specifically the metadata page order.
116  *      A zero value (default) uses base pages as the vmemmap metadata
117  *      representation. A bigger value will set up compound struct pages
118  *      of the requested order value.
119  * @ops: method table
120  * @owner: an opaque pointer identifying the entity that manages this
121  *      instance.  Used by various helpers to make sure that no
122  *      foreign ZONE_DEVICE memory is accessed.
123  * @nr_range: number of ranges to be mapped
124  * @range: range to be mapped when nr_range == 1
125  * @ranges: array of ranges to be mapped when nr_range > 1
126  */
127 struct dev_pagemap {
128         struct vmem_altmap altmap;
129         struct percpu_ref ref;
130         struct completion done;
131         enum memory_type type;
132         unsigned int flags;
133         unsigned long vmemmap_shift;
134         const struct dev_pagemap_ops *ops;
135         void *owner;
136         int nr_range;
137         union {
138                 struct range range;
139                 DECLARE_FLEX_ARRAY(struct range, ranges);
140         };
141 };
142 
143 static inline bool pgmap_has_memory_failure(struct dev_pagemap *pgmap)
144 {
145         return pgmap->ops && pgmap->ops->memory_failure;
146 }
147 
148 static inline struct vmem_altmap *pgmap_altmap(struct dev_pagemap *pgmap)
149 {
150         if (pgmap->flags & PGMAP_ALTMAP_VALID)
151                 return &pgmap->altmap;
152         return NULL;
153 }
154 
155 static inline unsigned long pgmap_vmemmap_nr(struct dev_pagemap *pgmap)
156 {
157         return 1 << pgmap->vmemmap_shift;
158 }
159 
160 static inline bool is_device_private_page(const struct page *page)
161 {
162         return IS_ENABLED(CONFIG_DEVICE_PRIVATE) &&
163                 is_zone_device_page(page) &&
164                 page->pgmap->type == MEMORY_DEVICE_PRIVATE;
165 }
166 
167 static inline bool folio_is_device_private(const struct folio *folio)
168 {
169         return is_device_private_page(&folio->page);
170 }
171 
172 static inline bool is_pci_p2pdma_page(const struct page *page)
173 {
174         return IS_ENABLED(CONFIG_PCI_P2PDMA) &&
175                 is_zone_device_page(page) &&
176                 page->pgmap->type == MEMORY_DEVICE_PCI_P2PDMA;
177 }
178 
179 static inline bool is_device_coherent_page(const struct page *page)
180 {
181         return is_zone_device_page(page) &&
182                 page->pgmap->type == MEMORY_DEVICE_COHERENT;
183 }
184 
185 static inline bool folio_is_device_coherent(const struct folio *folio)
186 {
187         return is_device_coherent_page(&folio->page);
188 }
189 
190 #ifdef CONFIG_ZONE_DEVICE
191 void zone_device_page_init(struct page *page);
192 void *memremap_pages(struct dev_pagemap *pgmap, int nid);
193 void memunmap_pages(struct dev_pagemap *pgmap);
194 void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap);
195 void devm_memunmap_pages(struct device *dev, struct dev_pagemap *pgmap);
196 struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
197                 struct dev_pagemap *pgmap);
198 bool pgmap_pfn_valid(struct dev_pagemap *pgmap, unsigned long pfn);
199 
200 unsigned long memremap_compat_align(void);
201 #else
202 static inline void *devm_memremap_pages(struct device *dev,
203                 struct dev_pagemap *pgmap)
204 {
205         /*
206          * Fail attempts to call devm_memremap_pages() without
207          * ZONE_DEVICE support enabled, this requires callers to fall
208          * back to plain devm_memremap() based on config
209          */
210         WARN_ON_ONCE(1);
211         return ERR_PTR(-ENXIO);
212 }
213 
214 static inline void devm_memunmap_pages(struct device *dev,
215                 struct dev_pagemap *pgmap)
216 {
217 }
218 
219 static inline struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
220                 struct dev_pagemap *pgmap)
221 {
222         return NULL;
223 }
224 
225 static inline bool pgmap_pfn_valid(struct dev_pagemap *pgmap, unsigned long pfn)
226 {
227         return false;
228 }
229 
230 /* when memremap_pages() is disabled all archs can remap a single page */
231 static inline unsigned long memremap_compat_align(void)
232 {
233         return PAGE_SIZE;
234 }
235 #endif /* CONFIG_ZONE_DEVICE */
236 
237 static inline void put_dev_pagemap(struct dev_pagemap *pgmap)
238 {
239         if (pgmap)
240                 percpu_ref_put(&pgmap->ref);
241 }
242 
243 #endif /* _LINUX_MEMREMAP_H_ */
244 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php