aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2019-06-26 08:27:21 -0400
committerJason Gunthorpe <jgg@mellanox.com>2019-07-02 13:32:45 -0400
commit8a164fef9c4ccf6ff7757170397222860e40d192 (patch)
tree32f53aa0e39177a6f952761d22c2415b717c5198
parenteee3ae41b153e55e25d6cf7bd5b5098ba0afe705 (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.c18
-rw-r--r--include/linux/hmm.h32
-rw-r--r--include/linux/mm_types.h2
-rw-r--r--mm/page_alloc.c8
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
105static void nouveau_dmem_page_free(struct page *page) 105static 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) {}
584static inline void hmm_mm_init(struct mm_struct *mm) {} 584static 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 */
597static 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 */
609static 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) */
615static inline void hmm_mm_destroy(struct mm_struct *mm) {}
616static 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