aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/memremap.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/memremap.h')
-rw-r--r--include/linux/memremap.h77
1 files changed, 23 insertions, 54 deletions
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 10d23c367048..7b4899c06f49 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -26,18 +26,6 @@ struct vmem_altmap {
26 unsigned long alloc; 26 unsigned long alloc;
27}; 27};
28 28
29unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
30void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
31
32#ifdef CONFIG_ZONE_DEVICE
33struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start);
34#else
35static inline struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start)
36{
37 return NULL;
38}
39#endif
40
41/* 29/*
42 * Specialize ZONE_DEVICE memory into multiple types each having differents 30 * Specialize ZONE_DEVICE memory into multiple types each having differents
43 * usage. 31 * usage.
@@ -125,8 +113,9 @@ typedef void (*dev_page_free_t)(struct page *page, void *data);
125struct dev_pagemap { 113struct dev_pagemap {
126 dev_page_fault_t page_fault; 114 dev_page_fault_t page_fault;
127 dev_page_free_t page_free; 115 dev_page_free_t page_free;
128 struct vmem_altmap *altmap; 116 struct vmem_altmap altmap;
129 const struct resource *res; 117 bool altmap_valid;
118 struct resource res;
130 struct percpu_ref *ref; 119 struct percpu_ref *ref;
131 struct device *dev; 120 struct device *dev;
132 void *data; 121 void *data;
@@ -134,15 +123,17 @@ struct dev_pagemap {
134}; 123};
135 124
136#ifdef CONFIG_ZONE_DEVICE 125#ifdef CONFIG_ZONE_DEVICE
137void *devm_memremap_pages(struct device *dev, struct resource *res, 126void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap);
138 struct percpu_ref *ref, struct vmem_altmap *altmap); 127struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
139struct dev_pagemap *find_dev_pagemap(resource_size_t phys); 128 struct dev_pagemap *pgmap);
129
130unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
131void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
140 132
141static inline bool is_zone_device_page(const struct page *page); 133static inline bool is_zone_device_page(const struct page *page);
142#else 134#else
143static inline void *devm_memremap_pages(struct device *dev, 135static inline void *devm_memremap_pages(struct device *dev,
144 struct resource *res, struct percpu_ref *ref, 136 struct dev_pagemap *pgmap)
145 struct vmem_altmap *altmap)
146{ 137{
147 /* 138 /*
148 * Fail attempts to call devm_memremap_pages() without 139 * Fail attempts to call devm_memremap_pages() without
@@ -153,11 +144,22 @@ static inline void *devm_memremap_pages(struct device *dev,
153 return ERR_PTR(-ENXIO); 144 return ERR_PTR(-ENXIO);
154} 145}
155 146
156static inline struct dev_pagemap *find_dev_pagemap(resource_size_t phys) 147static inline struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
148 struct dev_pagemap *pgmap)
157{ 149{
158 return NULL; 150 return NULL;
159} 151}
160#endif 152
153static inline unsigned long vmem_altmap_offset(struct vmem_altmap *altmap)
154{
155 return 0;
156}
157
158static inline void vmem_altmap_free(struct vmem_altmap *altmap,
159 unsigned long nr_pfns)
160{
161}
162#endif /* CONFIG_ZONE_DEVICE */
161 163
162#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC) 164#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC)
163static inline bool is_device_private_page(const struct page *page) 165static inline bool is_device_private_page(const struct page *page)
@@ -173,39 +175,6 @@ static inline bool is_device_public_page(const struct page *page)
173} 175}
174#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ 176#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */
175 177
176/**
177 * get_dev_pagemap() - take a new live reference on the dev_pagemap for @pfn
178 * @pfn: page frame number to lookup page_map
179 * @pgmap: optional known pgmap that already has a reference
180 *
181 * @pgmap allows the overhead of a lookup to be bypassed when @pfn lands in the
182 * same mapping.
183 */
184static inline struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
185 struct dev_pagemap *pgmap)
186{
187 const struct resource *res = pgmap ? pgmap->res : NULL;
188 resource_size_t phys = PFN_PHYS(pfn);
189
190 /*
191 * In the cached case we're already holding a live reference so
192 * we can simply do a blind increment
193 */
194 if (res && phys >= res->start && phys <= res->end) {
195 percpu_ref_get(pgmap->ref);
196 return pgmap;
197 }
198
199 /* fall back to slow path lookup */
200 rcu_read_lock();
201 pgmap = find_dev_pagemap(phys);
202 if (pgmap && !percpu_ref_tryget_live(pgmap->ref))
203 pgmap = NULL;
204 rcu_read_unlock();
205
206 return pgmap;
207}
208
209static inline void put_dev_pagemap(struct dev_pagemap *pgmap) 178static inline void put_dev_pagemap(struct dev_pagemap *pgmap)
210{ 179{
211 if (pgmap) 180 if (pgmap)