diff options
author | Christoph Hellwig <hch@lst.de> | 2019-06-26 08:27:21 -0400 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2019-07-02 13:32:45 -0400 |
commit | 8a164fef9c4ccf6ff7757170397222860e40d192 (patch) | |
tree | 32f53aa0e39177a6f952761d22c2415b717c5198 | |
parent | eee3ae41b153e55e25d6cf7bd5b5098ba0afe705 (diff) |
mm: simplify ZONE_DEVICE page private data
Remove the clumsy hmm_devmem_page_{get,set}_drvdata helpers, and
instead just access the page directly. Also make the page data
a void pointer, and thus much easier to use.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dmem.c | 18 | ||||
-rw-r--r-- | include/linux/hmm.h | 32 | ||||
-rw-r--r-- | include/linux/mm_types.h | 2 | ||||
-rw-r--r-- | mm/page_alloc.c | 8 |
4 files changed, 12 insertions, 48 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c index 0fb7a44b8bc4..42c026010938 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c | |||
@@ -104,11 +104,8 @@ struct nouveau_migrate { | |||
104 | 104 | ||
105 | static void nouveau_dmem_page_free(struct page *page) | 105 | static void nouveau_dmem_page_free(struct page *page) |
106 | { | 106 | { |
107 | struct nouveau_dmem_chunk *chunk; | 107 | struct nouveau_dmem_chunk *chunk = page->zone_device_data; |
108 | unsigned long idx; | 108 | unsigned long idx = page_to_pfn(page) - chunk->pfn_first; |
109 | |||
110 | chunk = (void *)hmm_devmem_page_get_drvdata(page); | ||
111 | idx = page_to_pfn(page) - chunk->pfn_first; | ||
112 | 109 | ||
113 | /* | 110 | /* |
114 | * FIXME: | 111 | * FIXME: |
@@ -200,7 +197,7 @@ nouveau_dmem_fault_alloc_and_copy(struct vm_area_struct *vma, | |||
200 | 197 | ||
201 | dst_addr = fault->dma[fault->npages++]; | 198 | dst_addr = fault->dma[fault->npages++]; |
202 | 199 | ||
203 | chunk = (void *)hmm_devmem_page_get_drvdata(spage); | 200 | chunk = spage->zone_device_data; |
204 | src_addr = page_to_pfn(spage) - chunk->pfn_first; | 201 | src_addr = page_to_pfn(spage) - chunk->pfn_first; |
205 | src_addr = (src_addr << PAGE_SHIFT) + chunk->bo->bo.offset; | 202 | src_addr = (src_addr << PAGE_SHIFT) + chunk->bo->bo.offset; |
206 | 203 | ||
@@ -633,9 +630,8 @@ nouveau_dmem_init(struct nouveau_drm *drm) | |||
633 | list_add_tail(&chunk->list, &drm->dmem->chunk_empty); | 630 | list_add_tail(&chunk->list, &drm->dmem->chunk_empty); |
634 | 631 | ||
635 | page = pfn_to_page(chunk->pfn_first); | 632 | page = pfn_to_page(chunk->pfn_first); |
636 | for (j = 0; j < DMEM_CHUNK_NPAGES; ++j, ++page) { | 633 | for (j = 0; j < DMEM_CHUNK_NPAGES; ++j, ++page) |
637 | hmm_devmem_page_set_drvdata(page, (long)chunk); | 634 | page->zone_device_data = chunk; |
638 | } | ||
639 | } | 635 | } |
640 | 636 | ||
641 | NV_INFO(drm, "DMEM: registered %ldMB of device memory\n", size >> 20); | 637 | NV_INFO(drm, "DMEM: registered %ldMB of device memory\n", size >> 20); |
@@ -698,7 +694,7 @@ nouveau_dmem_migrate_alloc_and_copy(struct vm_area_struct *vma, | |||
698 | if (!dpage || dst_pfns[i] == MIGRATE_PFN_ERROR) | 694 | if (!dpage || dst_pfns[i] == MIGRATE_PFN_ERROR) |
699 | continue; | 695 | continue; |
700 | 696 | ||
701 | chunk = (void *)hmm_devmem_page_get_drvdata(dpage); | 697 | chunk = dpage->zone_device_data; |
702 | dst_addr = page_to_pfn(dpage) - chunk->pfn_first; | 698 | dst_addr = page_to_pfn(dpage) - chunk->pfn_first; |
703 | dst_addr = (dst_addr << PAGE_SHIFT) + chunk->bo->bo.offset; | 699 | dst_addr = (dst_addr << PAGE_SHIFT) + chunk->bo->bo.offset; |
704 | 700 | ||
@@ -862,7 +858,7 @@ nouveau_dmem_convert_pfn(struct nouveau_drm *drm, | |||
862 | continue; | 858 | continue; |
863 | } | 859 | } |
864 | 860 | ||
865 | chunk = (void *)hmm_devmem_page_get_drvdata(page); | 861 | chunk = page->zone_device_data; |
866 | addr = page_to_pfn(page) - chunk->pfn_first; | 862 | addr = page_to_pfn(page) - chunk->pfn_first; |
867 | addr = (addr + chunk->bo->bo.mem.start) << PAGE_SHIFT; | 863 | addr = (addr + chunk->bo->bo.mem.start) << PAGE_SHIFT; |
868 | 864 | ||
diff --git a/include/linux/hmm.h b/include/linux/hmm.h index 86aa4ec3404c..3d00e9550e77 100644 --- a/include/linux/hmm.h +++ b/include/linux/hmm.h | |||
@@ -584,36 +584,4 @@ static inline void hmm_mm_destroy(struct mm_struct *mm) {} | |||
584 | static inline void hmm_mm_init(struct mm_struct *mm) {} | 584 | static inline void hmm_mm_init(struct mm_struct *mm) {} |
585 | #endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */ | 585 | #endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */ |
586 | 586 | ||
587 | #if IS_ENABLED(CONFIG_DEVICE_PRIVATE) | ||
588 | /* | ||
589 | * hmm_devmem_page_set_drvdata - set per-page driver data field | ||
590 | * | ||
591 | * @page: pointer to struct page | ||
592 | * @data: driver data value to set | ||
593 | * | ||
594 | * Because page can not be on lru we have an unsigned long that driver can use | ||
595 | * to store a per page field. This just a simple helper to do that. | ||
596 | */ | ||
597 | static inline void hmm_devmem_page_set_drvdata(struct page *page, | ||
598 | unsigned long data) | ||
599 | { | ||
600 | page->hmm_data = data; | ||
601 | } | ||
602 | |||
603 | /* | ||
604 | * hmm_devmem_page_get_drvdata - get per page driver data field | ||
605 | * | ||
606 | * @page: pointer to struct page | ||
607 | * Return: driver data value | ||
608 | */ | ||
609 | static inline unsigned long hmm_devmem_page_get_drvdata(const struct page *page) | ||
610 | { | ||
611 | return page->hmm_data; | ||
612 | } | ||
613 | #endif /* CONFIG_DEVICE_PRIVATE */ | ||
614 | #else /* IS_ENABLED(CONFIG_HMM) */ | ||
615 | static inline void hmm_mm_destroy(struct mm_struct *mm) {} | ||
616 | static inline void hmm_mm_init(struct mm_struct *mm) {} | ||
617 | #endif /* IS_ENABLED(CONFIG_HMM) */ | ||
618 | |||
619 | #endif /* LINUX_HMM_H */ | 587 | #endif /* LINUX_HMM_H */ |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 8ec38b11b361..f33a1289c101 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -158,7 +158,7 @@ struct page { | |||
158 | struct { /* ZONE_DEVICE pages */ | 158 | struct { /* ZONE_DEVICE pages */ |
159 | /** @pgmap: Points to the hosting device page map. */ | 159 | /** @pgmap: Points to the hosting device page map. */ |
160 | struct dev_pagemap *pgmap; | 160 | struct dev_pagemap *pgmap; |
161 | unsigned long hmm_data; | 161 | void *zone_device_data; |
162 | unsigned long _zd_pad_1; /* uses mapping */ | 162 | unsigned long _zd_pad_1; /* uses mapping */ |
163 | }; | 163 | }; |
164 | 164 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 17a39d40a556..c0e031c52db5 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -5886,12 +5886,12 @@ void __ref memmap_init_zone_device(struct zone *zone, | |||
5886 | __SetPageReserved(page); | 5886 | __SetPageReserved(page); |
5887 | 5887 | ||
5888 | /* | 5888 | /* |
5889 | * ZONE_DEVICE pages union ->lru with a ->pgmap back | 5889 | * ZONE_DEVICE pages union ->lru with a ->pgmap back pointer |
5890 | * pointer and hmm_data. It is a bug if a ZONE_DEVICE | 5890 | * and zone_device_data. It is a bug if a ZONE_DEVICE page is |
5891 | * page is ever freed or placed on a driver-private list. | 5891 | * ever freed or placed on a driver-private list. |
5892 | */ | 5892 | */ |
5893 | page->pgmap = pgmap; | 5893 | page->pgmap = pgmap; |
5894 | page->hmm_data = 0; | 5894 | page->zone_device_data = NULL; |
5895 | 5895 | ||
5896 | /* | 5896 | /* |
5897 | * Mark the block movable so that blocks are reserved for | 5897 | * Mark the block movable so that blocks are reserved for |