mm: remove MEMORY_DEVICE_PUBLIC support
The code hasn't been used since it was added to the tree, and doesn't appear to actually be usable. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jason Gunthorpe <jgg@mellanox.com> Acked-by: Michal Hocko <mhocko@suse.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Tested-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
07ec38917e
commit
25b2995a35
@ -1279,7 +1279,7 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm,
|
|||||||
if (pm->show_pfn)
|
if (pm->show_pfn)
|
||||||
frame = pte_pfn(pte);
|
frame = pte_pfn(pte);
|
||||||
flags |= PM_PRESENT;
|
flags |= PM_PRESENT;
|
||||||
page = _vm_normal_page(vma, addr, pte, true);
|
page = vm_normal_page(vma, addr, pte);
|
||||||
if (pte_soft_dirty(pte))
|
if (pte_soft_dirty(pte))
|
||||||
flags |= PM_SOFT_DIRTY;
|
flags |= PM_SOFT_DIRTY;
|
||||||
} else if (is_swap_pte(pte)) {
|
} else if (is_swap_pte(pte)) {
|
||||||
|
@ -584,7 +584,7 @@ static inline void hmm_mm_destroy(struct mm_struct *mm) {}
|
|||||||
static inline void hmm_mm_init(struct mm_struct *mm) {}
|
static inline void hmm_mm_init(struct mm_struct *mm) {}
|
||||||
#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */
|
#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_DEVICE_PRIVATE) || IS_ENABLED(CONFIG_DEVICE_PUBLIC)
|
#if IS_ENABLED(CONFIG_DEVICE_PRIVATE)
|
||||||
struct hmm_devmem;
|
struct hmm_devmem;
|
||||||
|
|
||||||
struct page *hmm_vma_alloc_locked_page(struct vm_area_struct *vma,
|
struct page *hmm_vma_alloc_locked_page(struct vm_area_struct *vma,
|
||||||
@ -722,9 +722,6 @@ struct hmm_devmem {
|
|||||||
struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops,
|
struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops,
|
||||||
struct device *device,
|
struct device *device,
|
||||||
unsigned long size);
|
unsigned long size);
|
||||||
struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops,
|
|
||||||
struct device *device,
|
|
||||||
struct resource *res);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hmm_devmem_page_set_drvdata - set per-page driver data field
|
* hmm_devmem_page_set_drvdata - set per-page driver data field
|
||||||
@ -751,7 +748,7 @@ static inline unsigned long hmm_devmem_page_get_drvdata(const struct page *page)
|
|||||||
{
|
{
|
||||||
return page->hmm_data;
|
return page->hmm_data;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */
|
#endif /* CONFIG_DEVICE_PRIVATE */
|
||||||
#else /* IS_ENABLED(CONFIG_HMM) */
|
#else /* IS_ENABLED(CONFIG_HMM) */
|
||||||
static inline void hmm_mm_destroy(struct mm_struct *mm) {}
|
static inline void hmm_mm_destroy(struct mm_struct *mm) {}
|
||||||
static inline void hmm_mm_init(struct mm_struct *mm) {}
|
static inline void hmm_mm_init(struct mm_struct *mm) {}
|
||||||
|
@ -132,7 +132,6 @@ enum {
|
|||||||
IORES_DESC_PERSISTENT_MEMORY = 4,
|
IORES_DESC_PERSISTENT_MEMORY = 4,
|
||||||
IORES_DESC_PERSISTENT_MEMORY_LEGACY = 5,
|
IORES_DESC_PERSISTENT_MEMORY_LEGACY = 5,
|
||||||
IORES_DESC_DEVICE_PRIVATE_MEMORY = 6,
|
IORES_DESC_DEVICE_PRIVATE_MEMORY = 6,
|
||||||
IORES_DESC_DEVICE_PUBLIC_MEMORY = 7,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* helpers to define resources */
|
/* helpers to define resources */
|
||||||
|
@ -37,13 +37,6 @@ struct vmem_altmap {
|
|||||||
* A more complete discussion of unaddressable memory may be found in
|
* A more complete discussion of unaddressable memory may be found in
|
||||||
* include/linux/hmm.h and Documentation/vm/hmm.rst.
|
* include/linux/hmm.h and Documentation/vm/hmm.rst.
|
||||||
*
|
*
|
||||||
* MEMORY_DEVICE_PUBLIC:
|
|
||||||
* Device memory that is cache coherent from device and CPU point of view. This
|
|
||||||
* is use on platform that have an advance system bus (like CAPI or CCIX). A
|
|
||||||
* driver can hotplug the device memory using ZONE_DEVICE and with that memory
|
|
||||||
* type. Any page of a process can be migrated to such memory. However no one
|
|
||||||
* should be allow to pin such memory so that it can always be evicted.
|
|
||||||
*
|
|
||||||
* MEMORY_DEVICE_FS_DAX:
|
* MEMORY_DEVICE_FS_DAX:
|
||||||
* Host memory that has similar access semantics as System RAM i.e. DMA
|
* Host memory that has similar access semantics as System RAM i.e. DMA
|
||||||
* coherent and supports page pinning. In support of coordinating page
|
* coherent and supports page pinning. In support of coordinating page
|
||||||
@ -58,7 +51,6 @@ struct vmem_altmap {
|
|||||||
*/
|
*/
|
||||||
enum memory_type {
|
enum memory_type {
|
||||||
MEMORY_DEVICE_PRIVATE = 1,
|
MEMORY_DEVICE_PRIVATE = 1,
|
||||||
MEMORY_DEVICE_PUBLIC,
|
|
||||||
MEMORY_DEVICE_FS_DAX,
|
MEMORY_DEVICE_FS_DAX,
|
||||||
MEMORY_DEVICE_PCI_P2PDMA,
|
MEMORY_DEVICE_PCI_P2PDMA,
|
||||||
};
|
};
|
||||||
|
@ -944,7 +944,6 @@ static inline bool put_devmap_managed_page(struct page *page)
|
|||||||
return false;
|
return false;
|
||||||
switch (page->pgmap->type) {
|
switch (page->pgmap->type) {
|
||||||
case MEMORY_DEVICE_PRIVATE:
|
case MEMORY_DEVICE_PRIVATE:
|
||||||
case MEMORY_DEVICE_PUBLIC:
|
|
||||||
case MEMORY_DEVICE_FS_DAX:
|
case MEMORY_DEVICE_FS_DAX:
|
||||||
__put_devmap_managed_page(page);
|
__put_devmap_managed_page(page);
|
||||||
return true;
|
return true;
|
||||||
@ -960,12 +959,6 @@ static inline bool is_device_private_page(const struct page *page)
|
|||||||
page->pgmap->type == MEMORY_DEVICE_PRIVATE;
|
page->pgmap->type == MEMORY_DEVICE_PRIVATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_device_public_page(const struct page *page)
|
|
||||||
{
|
|
||||||
return is_zone_device_page(page) &&
|
|
||||||
page->pgmap->type == MEMORY_DEVICE_PUBLIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_P2PDMA
|
#ifdef CONFIG_PCI_P2PDMA
|
||||||
static inline bool is_pci_p2pdma_page(const struct page *page)
|
static inline bool is_pci_p2pdma_page(const struct page *page)
|
||||||
{
|
{
|
||||||
@ -998,11 +991,6 @@ static inline bool is_device_private_page(const struct page *page)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_device_public_page(const struct page *page)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool is_pci_p2pdma_page(const struct page *page)
|
static inline bool is_pci_p2pdma_page(const struct page *page)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -1431,10 +1419,8 @@ struct zap_details {
|
|||||||
pgoff_t last_index; /* Highest page->index to unmap */
|
pgoff_t last_index; /* Highest page->index to unmap */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct page *_vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
|
struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
|
||||||
pte_t pte, bool with_public_device);
|
pte_t pte);
|
||||||
#define vm_normal_page(vma, addr, pte) _vm_normal_page(vma, addr, pte, false)
|
|
||||||
|
|
||||||
struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
|
struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
|
||||||
pmd_t pmd);
|
pmd_t pmd);
|
||||||
|
|
||||||
|
11
mm/Kconfig
11
mm/Kconfig
@ -718,17 +718,6 @@ config DEVICE_PRIVATE
|
|||||||
memory; i.e., memory that is only accessible from the device (or
|
memory; i.e., memory that is only accessible from the device (or
|
||||||
group of devices). You likely also want to select HMM_MIRROR.
|
group of devices). You likely also want to select HMM_MIRROR.
|
||||||
|
|
||||||
config DEVICE_PUBLIC
|
|
||||||
bool "Addressable device memory (like GPU memory)"
|
|
||||||
depends on ARCH_HAS_HMM
|
|
||||||
select HMM
|
|
||||||
select DEV_PAGEMAP_OPS
|
|
||||||
|
|
||||||
help
|
|
||||||
Allows creation of struct pages to represent addressable device
|
|
||||||
memory; i.e., memory that is accessible from both the device and
|
|
||||||
the CPU
|
|
||||||
|
|
||||||
config FRAME_VECTOR
|
config FRAME_VECTOR
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
7
mm/gup.c
7
mm/gup.c
@ -605,13 +605,6 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
|
|||||||
if ((gup_flags & FOLL_DUMP) || !is_zero_pfn(pte_pfn(*pte)))
|
if ((gup_flags & FOLL_DUMP) || !is_zero_pfn(pte_pfn(*pte)))
|
||||||
goto unmap;
|
goto unmap;
|
||||||
*page = pte_page(*pte);
|
*page = pte_page(*pte);
|
||||||
|
|
||||||
/*
|
|
||||||
* This should never happen (a device public page in the gate
|
|
||||||
* area).
|
|
||||||
*/
|
|
||||||
if (is_device_public_page(*page))
|
|
||||||
goto unmap;
|
|
||||||
}
|
}
|
||||||
if (unlikely(!try_get_page(*page))) {
|
if (unlikely(!try_get_page(*page))) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
54
mm/hmm.c
54
mm/hmm.c
@ -1331,7 +1331,7 @@ EXPORT_SYMBOL(hmm_range_dma_unmap);
|
|||||||
#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */
|
#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */
|
||||||
|
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_DEVICE_PRIVATE) || IS_ENABLED(CONFIG_DEVICE_PUBLIC)
|
#if IS_ENABLED(CONFIG_DEVICE_PRIVATE)
|
||||||
struct page *hmm_vma_alloc_locked_page(struct vm_area_struct *vma,
|
struct page *hmm_vma_alloc_locked_page(struct vm_area_struct *vma,
|
||||||
unsigned long addr)
|
unsigned long addr)
|
||||||
{
|
{
|
||||||
@ -1478,54 +1478,4 @@ struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops,
|
|||||||
return devmem;
|
return devmem;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hmm_devmem_add);
|
EXPORT_SYMBOL_GPL(hmm_devmem_add);
|
||||||
|
#endif /* CONFIG_DEVICE_PRIVATE */
|
||||||
struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops,
|
|
||||||
struct device *device,
|
|
||||||
struct resource *res)
|
|
||||||
{
|
|
||||||
struct hmm_devmem *devmem;
|
|
||||||
void *result;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (res->desc != IORES_DESC_DEVICE_PUBLIC_MEMORY)
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
|
|
||||||
dev_pagemap_get_ops();
|
|
||||||
|
|
||||||
devmem = devm_kzalloc(device, sizeof(*devmem), GFP_KERNEL);
|
|
||||||
if (!devmem)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
init_completion(&devmem->completion);
|
|
||||||
devmem->pfn_first = -1UL;
|
|
||||||
devmem->pfn_last = -1UL;
|
|
||||||
devmem->resource = res;
|
|
||||||
devmem->device = device;
|
|
||||||
devmem->ops = ops;
|
|
||||||
|
|
||||||
ret = percpu_ref_init(&devmem->ref, &hmm_devmem_ref_release,
|
|
||||||
0, GFP_KERNEL);
|
|
||||||
if (ret)
|
|
||||||
return ERR_PTR(ret);
|
|
||||||
|
|
||||||
devmem->pfn_first = devmem->resource->start >> PAGE_SHIFT;
|
|
||||||
devmem->pfn_last = devmem->pfn_first +
|
|
||||||
(resource_size(devmem->resource) >> PAGE_SHIFT);
|
|
||||||
devmem->page_fault = hmm_devmem_fault;
|
|
||||||
|
|
||||||
devmem->pagemap.type = MEMORY_DEVICE_PUBLIC;
|
|
||||||
devmem->pagemap.res = *devmem->resource;
|
|
||||||
devmem->pagemap.page_free = hmm_devmem_free;
|
|
||||||
devmem->pagemap.altmap_valid = false;
|
|
||||||
devmem->pagemap.ref = &devmem->ref;
|
|
||||||
devmem->pagemap.data = devmem;
|
|
||||||
devmem->pagemap.kill = hmm_devmem_ref_kill;
|
|
||||||
devmem->pagemap.cleanup = hmm_devmem_ref_exit;
|
|
||||||
|
|
||||||
result = devm_memremap_pages(devmem->device, &devmem->pagemap);
|
|
||||||
if (IS_ERR(result))
|
|
||||||
return result;
|
|
||||||
return devmem;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(hmm_devmem_add_resource);
|
|
||||||
#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */
|
|
||||||
|
@ -354,7 +354,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
page = _vm_normal_page(vma, addr, ptent, true);
|
page = vm_normal_page(vma, addr, ptent);
|
||||||
if (!page)
|
if (!page)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -4793,7 +4793,7 @@ enum mc_target_type {
|
|||||||
static struct page *mc_handle_present_pte(struct vm_area_struct *vma,
|
static struct page *mc_handle_present_pte(struct vm_area_struct *vma,
|
||||||
unsigned long addr, pte_t ptent)
|
unsigned long addr, pte_t ptent)
|
||||||
{
|
{
|
||||||
struct page *page = _vm_normal_page(vma, addr, ptent, true);
|
struct page *page = vm_normal_page(vma, addr, ptent);
|
||||||
|
|
||||||
if (!page || !page_mapped(page))
|
if (!page || !page_mapped(page))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -4994,8 +4994,8 @@ out:
|
|||||||
* 2(MC_TARGET_SWAP): if the swap entry corresponding to this pte is a
|
* 2(MC_TARGET_SWAP): if the swap entry corresponding to this pte is a
|
||||||
* target for charge migration. if @target is not NULL, the entry is stored
|
* target for charge migration. if @target is not NULL, the entry is stored
|
||||||
* in target->ent.
|
* in target->ent.
|
||||||
* 3(MC_TARGET_DEVICE): like MC_TARGET_PAGE but page is MEMORY_DEVICE_PUBLIC
|
* 3(MC_TARGET_DEVICE): like MC_TARGET_PAGE but page is MEMORY_DEVICE_PRIVATE
|
||||||
* or MEMORY_DEVICE_PRIVATE (so ZONE_DEVICE page and thus not on the lru).
|
* (so ZONE_DEVICE page and thus not on the lru).
|
||||||
* For now we such page is charge like a regular page would be as for all
|
* For now we such page is charge like a regular page would be as for all
|
||||||
* intent and purposes it is just special memory taking the place of a
|
* intent and purposes it is just special memory taking the place of a
|
||||||
* regular page.
|
* regular page.
|
||||||
@ -5029,8 +5029,7 @@ static enum mc_target_type get_mctgt_type(struct vm_area_struct *vma,
|
|||||||
*/
|
*/
|
||||||
if (page->mem_cgroup == mc.from) {
|
if (page->mem_cgroup == mc.from) {
|
||||||
ret = MC_TARGET_PAGE;
|
ret = MC_TARGET_PAGE;
|
||||||
if (is_device_private_page(page) ||
|
if (is_device_private_page(page))
|
||||||
is_device_public_page(page))
|
|
||||||
ret = MC_TARGET_DEVICE;
|
ret = MC_TARGET_DEVICE;
|
||||||
if (target)
|
if (target)
|
||||||
target->page = page;
|
target->page = page;
|
||||||
@ -5101,8 +5100,8 @@ static int mem_cgroup_count_precharge_pte_range(pmd_t *pmd,
|
|||||||
if (ptl) {
|
if (ptl) {
|
||||||
/*
|
/*
|
||||||
* Note their can not be MC_TARGET_DEVICE for now as we do not
|
* Note their can not be MC_TARGET_DEVICE for now as we do not
|
||||||
* support transparent huge page with MEMORY_DEVICE_PUBLIC or
|
* support transparent huge page with MEMORY_DEVICE_PRIVATE but
|
||||||
* MEMORY_DEVICE_PRIVATE but this might change.
|
* this might change.
|
||||||
*/
|
*/
|
||||||
if (get_mctgt_type_thp(vma, addr, *pmd, NULL) == MC_TARGET_PAGE)
|
if (get_mctgt_type_thp(vma, addr, *pmd, NULL) == MC_TARGET_PAGE)
|
||||||
mc.precharge += HPAGE_PMD_NR;
|
mc.precharge += HPAGE_PMD_NR;
|
||||||
|
@ -1177,16 +1177,12 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags,
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (pgmap->type) {
|
if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
|
||||||
case MEMORY_DEVICE_PRIVATE:
|
|
||||||
case MEMORY_DEVICE_PUBLIC:
|
|
||||||
/*
|
/*
|
||||||
* TODO: Handle HMM pages which may need coordination
|
* TODO: Handle HMM pages which may need coordination
|
||||||
* with device-side memory.
|
* with device-side memory.
|
||||||
*/
|
*/
|
||||||
goto unlock;
|
goto unlock;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
40
mm/memory.c
40
mm/memory.c
@ -571,8 +571,8 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
|
|||||||
* PFNMAP mappings in order to support COWable mappings.
|
* PFNMAP mappings in order to support COWable mappings.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct page *_vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
|
struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
|
||||||
pte_t pte, bool with_public_device)
|
pte_t pte)
|
||||||
{
|
{
|
||||||
unsigned long pfn = pte_pfn(pte);
|
unsigned long pfn = pte_pfn(pte);
|
||||||
|
|
||||||
@ -585,29 +585,6 @@ struct page *_vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
|
|||||||
return NULL;
|
return NULL;
|
||||||
if (is_zero_pfn(pfn))
|
if (is_zero_pfn(pfn))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
|
||||||
* Device public pages are special pages (they are ZONE_DEVICE
|
|
||||||
* pages but different from persistent memory). They behave
|
|
||||||
* allmost like normal pages. The difference is that they are
|
|
||||||
* not on the lru and thus should never be involve with any-
|
|
||||||
* thing that involve lru manipulation (mlock, numa balancing,
|
|
||||||
* ...).
|
|
||||||
*
|
|
||||||
* This is why we still want to return NULL for such page from
|
|
||||||
* vm_normal_page() so that we do not have to special case all
|
|
||||||
* call site of vm_normal_page().
|
|
||||||
*/
|
|
||||||
if (likely(pfn <= highest_memmap_pfn)) {
|
|
||||||
struct page *page = pfn_to_page(pfn);
|
|
||||||
|
|
||||||
if (is_device_public_page(page)) {
|
|
||||||
if (with_public_device)
|
|
||||||
return page;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pte_devmap(pte))
|
if (pte_devmap(pte))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -797,17 +774,6 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
|
|||||||
rss[mm_counter(page)]++;
|
rss[mm_counter(page)]++;
|
||||||
} else if (pte_devmap(pte)) {
|
} else if (pte_devmap(pte)) {
|
||||||
page = pte_page(pte);
|
page = pte_page(pte);
|
||||||
|
|
||||||
/*
|
|
||||||
* Cache coherent device memory behave like regular page and
|
|
||||||
* not like persistent memory page. For more informations see
|
|
||||||
* MEMORY_DEVICE_CACHE_COHERENT in memory_hotplug.h
|
|
||||||
*/
|
|
||||||
if (is_device_public_page(page)) {
|
|
||||||
get_page(page);
|
|
||||||
page_dup_rmap(page, false);
|
|
||||||
rss[mm_counter(page)]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out_set_pte:
|
out_set_pte:
|
||||||
@ -1063,7 +1029,7 @@ again:
|
|||||||
if (pte_present(ptent)) {
|
if (pte_present(ptent)) {
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
||||||
page = _vm_normal_page(vma, addr, ptent, true);
|
page = vm_normal_page(vma, addr, ptent);
|
||||||
if (unlikely(details) && page) {
|
if (unlikely(details) && page) {
|
||||||
/*
|
/*
|
||||||
* unmap_shared_mapping_pages() wants to
|
* unmap_shared_mapping_pages() wants to
|
||||||
|
28
mm/migrate.c
28
mm/migrate.c
@ -246,8 +246,6 @@ static bool remove_migration_pte(struct page *page, struct vm_area_struct *vma,
|
|||||||
if (is_device_private_page(new)) {
|
if (is_device_private_page(new)) {
|
||||||
entry = make_device_private_entry(new, pte_write(pte));
|
entry = make_device_private_entry(new, pte_write(pte));
|
||||||
pte = swp_entry_to_pte(entry);
|
pte = swp_entry_to_pte(entry);
|
||||||
} else if (is_device_public_page(new)) {
|
|
||||||
pte = pte_mkdevmap(pte);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +379,6 @@ static int expected_page_refs(struct address_space *mapping, struct page *page)
|
|||||||
* ZONE_DEVICE pages.
|
* ZONE_DEVICE pages.
|
||||||
*/
|
*/
|
||||||
expected_count += is_device_private_page(page);
|
expected_count += is_device_private_page(page);
|
||||||
expected_count += is_device_public_page(page);
|
|
||||||
if (mapping)
|
if (mapping)
|
||||||
expected_count += hpage_nr_pages(page) + page_has_private(page);
|
expected_count += hpage_nr_pages(page) + page_has_private(page);
|
||||||
|
|
||||||
@ -994,10 +991,7 @@ static int move_to_new_page(struct page *newpage, struct page *page,
|
|||||||
if (!PageMappingFlags(page))
|
if (!PageMappingFlags(page))
|
||||||
page->mapping = NULL;
|
page->mapping = NULL;
|
||||||
|
|
||||||
if (unlikely(is_zone_device_page(newpage))) {
|
if (likely(!is_zone_device_page(newpage)))
|
||||||
if (is_device_public_page(newpage))
|
|
||||||
flush_dcache_page(newpage);
|
|
||||||
} else
|
|
||||||
flush_dcache_page(newpage);
|
flush_dcache_page(newpage);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2265,7 +2259,7 @@ again:
|
|||||||
pfn = 0;
|
pfn = 0;
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
page = _vm_normal_page(migrate->vma, addr, pte, true);
|
page = vm_normal_page(migrate->vma, addr, pte);
|
||||||
mpfn = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
|
mpfn = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
|
||||||
mpfn |= pte_write(pte) ? MIGRATE_PFN_WRITE : 0;
|
mpfn |= pte_write(pte) ? MIGRATE_PFN_WRITE : 0;
|
||||||
}
|
}
|
||||||
@ -2406,16 +2400,7 @@ static bool migrate_vma_check_page(struct page *page)
|
|||||||
* FIXME proper solution is to rework migration_entry_wait() so
|
* FIXME proper solution is to rework migration_entry_wait() so
|
||||||
* it does not need to take a reference on page.
|
* it does not need to take a reference on page.
|
||||||
*/
|
*/
|
||||||
if (is_device_private_page(page))
|
return is_device_private_page(page);
|
||||||
return true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only allow device public page to be migrated and account for
|
|
||||||
* the extra reference count imply by ZONE_DEVICE pages.
|
|
||||||
*/
|
|
||||||
if (!is_device_public_page(page))
|
|
||||||
return false;
|
|
||||||
extra++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For file back page */
|
/* For file back page */
|
||||||
@ -2665,11 +2650,6 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
|
|||||||
|
|
||||||
swp_entry = make_device_private_entry(page, vma->vm_flags & VM_WRITE);
|
swp_entry = make_device_private_entry(page, vma->vm_flags & VM_WRITE);
|
||||||
entry = swp_entry_to_pte(swp_entry);
|
entry = swp_entry_to_pte(swp_entry);
|
||||||
} else if (is_device_public_page(page)) {
|
|
||||||
entry = pte_mkold(mk_pte(page, READ_ONCE(vma->vm_page_prot)));
|
|
||||||
if (vma->vm_flags & VM_WRITE)
|
|
||||||
entry = pte_mkwrite(pte_mkdirty(entry));
|
|
||||||
entry = pte_mkdevmap(entry);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
entry = mk_pte(page, vma->vm_page_prot);
|
entry = mk_pte(page, vma->vm_page_prot);
|
||||||
@ -2789,7 +2769,7 @@ static void migrate_vma_pages(struct migrate_vma *migrate)
|
|||||||
migrate->src[i] &= ~MIGRATE_PFN_MIGRATE;
|
migrate->src[i] &= ~MIGRATE_PFN_MIGRATE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (!is_device_public_page(newpage)) {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Other types of ZONE_DEVICE page are not
|
* Other types of ZONE_DEVICE page are not
|
||||||
* supported.
|
* supported.
|
||||||
|
11
mm/swap.c
11
mm/swap.c
@ -740,17 +740,6 @@ void release_pages(struct page **pages, int nr)
|
|||||||
if (is_huge_zero_page(page))
|
if (is_huge_zero_page(page))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Device public page can not be huge page */
|
|
||||||
if (is_device_public_page(page)) {
|
|
||||||
if (locked_pgdat) {
|
|
||||||
spin_unlock_irqrestore(&locked_pgdat->lru_lock,
|
|
||||||
flags);
|
|
||||||
locked_pgdat = NULL;
|
|
||||||
}
|
|
||||||
put_devmap_managed_page(page);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
page = compound_head(page);
|
page = compound_head(page);
|
||||||
if (!put_page_testzero(page))
|
if (!put_page_testzero(page))
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user