Commit 8a164fef authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jason Gunthorpe
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent eee3ae41
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -104,11 +104,8 @@ struct nouveau_migrate {

static void nouveau_dmem_page_free(struct page *page)
{
	struct nouveau_dmem_chunk *chunk;
	unsigned long idx;

	chunk = (void *)hmm_devmem_page_get_drvdata(page);
	idx = page_to_pfn(page) - chunk->pfn_first;
	struct nouveau_dmem_chunk *chunk = page->zone_device_data;
	unsigned long idx = page_to_pfn(page) - chunk->pfn_first;

	/*
	 * FIXME:
@@ -200,7 +197,7 @@ nouveau_dmem_fault_alloc_and_copy(struct vm_area_struct *vma,

		dst_addr = fault->dma[fault->npages++];

		chunk = (void *)hmm_devmem_page_get_drvdata(spage);
		chunk = spage->zone_device_data;
		src_addr = page_to_pfn(spage) - chunk->pfn_first;
		src_addr = (src_addr << PAGE_SHIFT) + chunk->bo->bo.offset;

@@ -633,9 +630,8 @@ nouveau_dmem_init(struct nouveau_drm *drm)
		list_add_tail(&chunk->list, &drm->dmem->chunk_empty);

		page = pfn_to_page(chunk->pfn_first);
		for (j = 0; j < DMEM_CHUNK_NPAGES; ++j, ++page) {
			hmm_devmem_page_set_drvdata(page, (long)chunk);
		}
		for (j = 0; j < DMEM_CHUNK_NPAGES; ++j, ++page)
			page->zone_device_data = chunk;
	}

	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,
		if (!dpage || dst_pfns[i] == MIGRATE_PFN_ERROR)
			continue;

		chunk = (void *)hmm_devmem_page_get_drvdata(dpage);
		chunk = dpage->zone_device_data;
		dst_addr = page_to_pfn(dpage) - chunk->pfn_first;
		dst_addr = (dst_addr << PAGE_SHIFT) + chunk->bo->bo.offset;

@@ -862,7 +858,7 @@ nouveau_dmem_convert_pfn(struct nouveau_drm *drm,
			continue;
		}

		chunk = (void *)hmm_devmem_page_get_drvdata(page);
		chunk = page->zone_device_data;
		addr = page_to_pfn(page) - chunk->pfn_first;
		addr = (addr + chunk->bo->bo.mem.start) << PAGE_SHIFT;

+0 −32
Original line number Diff line number Diff line
@@ -584,36 +584,4 @@ static inline void hmm_mm_destroy(struct mm_struct *mm) {}
static inline void hmm_mm_init(struct mm_struct *mm) {}
#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */

#if IS_ENABLED(CONFIG_DEVICE_PRIVATE)
/*
 * hmm_devmem_page_set_drvdata - set per-page driver data field
 *
 * @page: pointer to struct page
 * @data: driver data value to set
 *
 * Because page can not be on lru we have an unsigned long that driver can use
 * to store a per page field. This just a simple helper to do that.
 */
static inline void hmm_devmem_page_set_drvdata(struct page *page,
					       unsigned long data)
{
	page->hmm_data = data;
}

/*
 * hmm_devmem_page_get_drvdata - get per page driver data field
 *
 * @page: pointer to struct page
 * Return: driver data value
 */
static inline unsigned long hmm_devmem_page_get_drvdata(const struct page *page)
{
	return page->hmm_data;
}
#endif /* CONFIG_DEVICE_PRIVATE */
#else /* IS_ENABLED(CONFIG_HMM) */
static inline void hmm_mm_destroy(struct mm_struct *mm) {}
static inline void hmm_mm_init(struct mm_struct *mm) {}
#endif /* IS_ENABLED(CONFIG_HMM) */

#endif /* LINUX_HMM_H */
+1 −1
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ struct page {
		struct {	/* ZONE_DEVICE pages */
			/** @pgmap: Points to the hosting device page map. */
			struct dev_pagemap *pgmap;
			unsigned long hmm_data;
			void *zone_device_data;
			unsigned long _zd_pad_1;	/* uses mapping */
		};

+4 −4
Original line number Diff line number Diff line
@@ -5886,12 +5886,12 @@ void __ref memmap_init_zone_device(struct zone *zone,
		__SetPageReserved(page);

		/*
		 * ZONE_DEVICE pages union ->lru with a ->pgmap back
		 * pointer and hmm_data.  It is a bug if a ZONE_DEVICE
		 * page is ever freed or placed on a driver-private list.
		 * ZONE_DEVICE pages union ->lru with a ->pgmap back pointer
		 * and zone_device_data.  It is a bug if a ZONE_DEVICE page is
		 * ever freed or placed on a driver-private list.
		 */
		page->pgmap = pgmap;
		page->hmm_data = 0;
		page->zone_device_data = NULL;

		/*
		 * Mark the block movable so that blocks are reserved for