aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2018-06-08 18:16:40 -0400
committerDan Williams <dan.j.williams@intel.com>2018-06-08 18:16:40 -0400
commitb56845794e1e93121acb74ca325db965035d5545 (patch)
tree3435f4e8de92d5a63fdc15953391cf057ee46642 /include/linux
parent808c340be17dc77131fcdf9ad1eb34452d650da1 (diff)
parentcc4a90ac816e00775fbc2a9c018bf2af606abd06 (diff)
Merge branch 'for-4.18/dax' into libnvdimm-for-next
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/dax.h7
-rw-r--r--include/linux/memremap.h36
-rw-r--r--include/linux/mm.h71
3 files changed, 70 insertions, 44 deletions
diff --git a/include/linux/dax.h b/include/linux/dax.h
index f9eb22ad341e..25bab6abb695 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -83,6 +83,8 @@ static inline void fs_put_dax(struct dax_device *dax_dev)
83struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev); 83struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev);
84int dax_writeback_mapping_range(struct address_space *mapping, 84int dax_writeback_mapping_range(struct address_space *mapping,
85 struct block_device *bdev, struct writeback_control *wbc); 85 struct block_device *bdev, struct writeback_control *wbc);
86
87struct page *dax_layout_busy_page(struct address_space *mapping);
86#else 88#else
87static inline int bdev_dax_supported(struct super_block *sb, int blocksize) 89static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
88{ 90{
@@ -103,6 +105,11 @@ static inline struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
103 return NULL; 105 return NULL;
104} 106}
105 107
108static inline struct page *dax_layout_busy_page(struct address_space *mapping)
109{
110 return NULL;
111}
112
106static inline int dax_writeback_mapping_range(struct address_space *mapping, 113static inline int dax_writeback_mapping_range(struct address_space *mapping,
107 struct block_device *bdev, struct writeback_control *wbc) 114 struct block_device *bdev, struct writeback_control *wbc)
108{ 115{
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 7b4899c06f49..5ebfff65da4d 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -1,7 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _LINUX_MEMREMAP_H_ 2#ifndef _LINUX_MEMREMAP_H_
3#define _LINUX_MEMREMAP_H_ 3#define _LINUX_MEMREMAP_H_
4#include <linux/mm.h>
5#include <linux/ioport.h> 4#include <linux/ioport.h>
6#include <linux/percpu-refcount.h> 5#include <linux/percpu-refcount.h>
7 6
@@ -30,13 +29,6 @@ struct vmem_altmap {
30 * Specialize ZONE_DEVICE memory into multiple types each having differents 29 * Specialize ZONE_DEVICE memory into multiple types each having differents
31 * usage. 30 * usage.
32 * 31 *
33 * MEMORY_DEVICE_HOST:
34 * Persistent device memory (pmem): struct page might be allocated in different
35 * memory and architecture might want to perform special actions. It is similar
36 * to regular memory, in that the CPU can access it transparently. However,
37 * it is likely to have different bandwidth and latency than regular memory.
38 * See Documentation/nvdimm/nvdimm.txt for more information.
39 *
40 * MEMORY_DEVICE_PRIVATE: 32 * MEMORY_DEVICE_PRIVATE:
41 * Device memory that is not directly addressable by the CPU: CPU can neither 33 * Device memory that is not directly addressable by the CPU: CPU can neither
42 * read nor write private memory. In this case, we do still have struct pages 34 * read nor write private memory. In this case, we do still have struct pages
@@ -53,11 +45,19 @@ struct vmem_altmap {
53 * driver can hotplug the device memory using ZONE_DEVICE and with that memory 45 * driver can hotplug the device memory using ZONE_DEVICE and with that memory
54 * type. Any page of a process can be migrated to such memory. However no one 46 * type. Any page of a process can be migrated to such memory. However no one
55 * should be allow to pin such memory so that it can always be evicted. 47 * should be allow to pin such memory so that it can always be evicted.
48 *
49 * MEMORY_DEVICE_FS_DAX:
50 * Host memory that has similar access semantics as System RAM i.e. DMA
51 * coherent and supports page pinning. In support of coordinating page
52 * pinning vs other operations MEMORY_DEVICE_FS_DAX arranges for a
53 * wakeup event whenever a page is unpinned and becomes idle. This
54 * wakeup is used to coordinate physical address space management (ex:
55 * fs truncate/hole punch) vs pinned pages (ex: device dma).
56 */ 56 */
57enum memory_type { 57enum memory_type {
58 MEMORY_DEVICE_HOST = 0, 58 MEMORY_DEVICE_PRIVATE = 1,
59 MEMORY_DEVICE_PRIVATE,
60 MEMORY_DEVICE_PUBLIC, 59 MEMORY_DEVICE_PUBLIC,
60 MEMORY_DEVICE_FS_DAX,
61}; 61};
62 62
63/* 63/*
@@ -129,8 +129,6 @@ struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
129 129
130unsigned long vmem_altmap_offset(struct vmem_altmap *altmap); 130unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
131void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns); 131void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
132
133static inline bool is_zone_device_page(const struct page *page);
134#else 132#else
135static inline void *devm_memremap_pages(struct device *dev, 133static inline void *devm_memremap_pages(struct device *dev,
136 struct dev_pagemap *pgmap) 134 struct dev_pagemap *pgmap)
@@ -161,20 +159,6 @@ static inline void vmem_altmap_free(struct vmem_altmap *altmap,
161} 159}
162#endif /* CONFIG_ZONE_DEVICE */ 160#endif /* CONFIG_ZONE_DEVICE */
163 161
164#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC)
165static inline bool is_device_private_page(const struct page *page)
166{
167 return is_zone_device_page(page) &&
168 page->pgmap->type == MEMORY_DEVICE_PRIVATE;
169}
170
171static inline bool is_device_public_page(const struct page *page)
172{
173 return is_zone_device_page(page) &&
174 page->pgmap->type == MEMORY_DEVICE_PUBLIC;
175}
176#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */
177
178static inline void put_dev_pagemap(struct dev_pagemap *pgmap) 162static inline void put_dev_pagemap(struct dev_pagemap *pgmap)
179{ 163{
180 if (pgmap) 164 if (pgmap)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 02a616e2f17d..274d5242bd0d 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -821,27 +821,65 @@ static inline bool is_zone_device_page(const struct page *page)
821} 821}
822#endif 822#endif
823 823
824#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC) 824#ifdef CONFIG_DEV_PAGEMAP_OPS
825void put_zone_device_private_or_public_page(struct page *page); 825void dev_pagemap_get_ops(void);
826DECLARE_STATIC_KEY_FALSE(device_private_key); 826void dev_pagemap_put_ops(void);
827#define IS_HMM_ENABLED static_branch_unlikely(&device_private_key) 827void __put_devmap_managed_page(struct page *page);
828static inline bool is_device_private_page(const struct page *page); 828DECLARE_STATIC_KEY_FALSE(devmap_managed_key);
829static inline bool is_device_public_page(const struct page *page); 829static inline bool put_devmap_managed_page(struct page *page)
830#else /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ 830{
831static inline void put_zone_device_private_or_public_page(struct page *page) 831 if (!static_branch_unlikely(&devmap_managed_key))
832 return false;
833 if (!is_zone_device_page(page))
834 return false;
835 switch (page->pgmap->type) {
836 case MEMORY_DEVICE_PRIVATE:
837 case MEMORY_DEVICE_PUBLIC:
838 case MEMORY_DEVICE_FS_DAX:
839 __put_devmap_managed_page(page);
840 return true;
841 default:
842 break;
843 }
844 return false;
845}
846
847static inline bool is_device_private_page(const struct page *page)
832{ 848{
849 return is_zone_device_page(page) &&
850 page->pgmap->type == MEMORY_DEVICE_PRIVATE;
833} 851}
834#define IS_HMM_ENABLED 0 852
853static inline bool is_device_public_page(const struct page *page)
854{
855 return is_zone_device_page(page) &&
856 page->pgmap->type == MEMORY_DEVICE_PUBLIC;
857}
858
859#else /* CONFIG_DEV_PAGEMAP_OPS */
860static inline void dev_pagemap_get_ops(void)
861{
862}
863
864static inline void dev_pagemap_put_ops(void)
865{
866}
867
868static inline bool put_devmap_managed_page(struct page *page)
869{
870 return false;
871}
872
835static inline bool is_device_private_page(const struct page *page) 873static inline bool is_device_private_page(const struct page *page)
836{ 874{
837 return false; 875 return false;
838} 876}
877
839static inline bool is_device_public_page(const struct page *page) 878static inline bool is_device_public_page(const struct page *page)
840{ 879{
841 return false; 880 return false;
842} 881}
843#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ 882#endif /* CONFIG_DEV_PAGEMAP_OPS */
844
845 883
846static inline void get_page(struct page *page) 884static inline void get_page(struct page *page)
847{ 885{
@@ -859,16 +897,13 @@ static inline void put_page(struct page *page)
859 page = compound_head(page); 897 page = compound_head(page);
860 898
861 /* 899 /*
862 * For private device pages we need to catch refcount transition from 900 * For devmap managed pages we need to catch refcount transition from
863 * 2 to 1, when refcount reach one it means the private device page is 901 * 2 to 1, when refcount reach one it means the page is free and we
864 * free and we need to inform the device driver through callback. See 902 * need to inform the device driver through callback. See
865 * include/linux/memremap.h and HMM for details. 903 * include/linux/memremap.h and HMM for details.
866 */ 904 */
867 if (IS_HMM_ENABLED && unlikely(is_device_private_page(page) || 905 if (put_devmap_managed_page(page))
868 unlikely(is_device_public_page(page)))) {
869 put_zone_device_private_or_public_page(page);
870 return; 906 return;
871 }
872 907
873 if (put_page_testzero(page)) 908 if (put_page_testzero(page))
874 __put_page(page); 909 __put_page(page);