* [RFC PATCH v2 1/3] drm/pagemap: Add helper to access zone_device_data
2026-01-23 21:59 [RFC PATCH v2 0/3] Use new dma-map IOVA alloc, link, and sync API in GPU SVM and DRM pagemap Matthew Brost
@ 2026-01-23 21:59 ` Matthew Brost
2026-01-23 21:59 ` [RFC PATCH v2 2/3] drm/gpusvm: Use new dma-map IOVA alloc, link, and sync API in GPU SVM Matthew Brost
` (2 subsequent siblings)
3 siblings, 0 replies; 10+ messages in thread
From: Matthew Brost @ 2026-01-23 21:59 UTC (permalink / raw)
To: intel-xe, dri-devel
Cc: leonro, francois.dugast, thomas.hellstrom, himal.prasad.ghimiray,
jgg
From: Francois Dugast <francois.dugast@intel.com>
This new helper helps ensure all accesses to zone_device_data use the
correct API whether the page is part of a folio or not.
v2:
- Move to drm_pagemap.h, stick to folio_zone_device_data (Matthew Brost)
- Return struct drm_pagemap_zdd * (Matthew Brost)
Suggested-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Francois Dugast <francois.dugast@intel.com>
---
drivers/gpu/drm/drm_gpusvm.c | 7 +++++--
drivers/gpu/drm/drm_pagemap.c | 21 ++++++++++++---------
include/drm/drm_pagemap.h | 14 ++++++++++++++
3 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c
index aa9a0b60e727..585d913d3d19 100644
--- a/drivers/gpu/drm/drm_gpusvm.c
+++ b/drivers/gpu/drm/drm_gpusvm.c
@@ -1488,12 +1488,15 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
order = drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages);
if (is_device_private_page(page) ||
is_device_coherent_page(page)) {
+ struct drm_pagemap_zdd *__zdd =
+ drm_pagemap_page_zone_device_data(page);
+
if (!ctx->allow_mixed &&
- zdd != page->zone_device_data && i > 0) {
+ zdd != __zdd && i > 0) {
err = -EOPNOTSUPP;
goto err_unmap;
}
- zdd = page->zone_device_data;
+ zdd = __zdd;
if (pagemap != page_pgmap(page)) {
if (i > 0) {
err = -EOPNOTSUPP;
diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
index 03ee39a761a4..2c67aabd8d65 100644
--- a/drivers/gpu/drm/drm_pagemap.c
+++ b/drivers/gpu/drm/drm_pagemap.c
@@ -244,7 +244,7 @@ static int drm_pagemap_migrate_map_pages(struct device *dev,
order = folio_order(folio);
if (is_device_private_page(page)) {
- struct drm_pagemap_zdd *zdd = page->zone_device_data;
+ struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
struct drm_pagemap *dpagemap = zdd->dpagemap;
struct drm_pagemap_addr addr;
@@ -315,7 +315,7 @@ static void drm_pagemap_migrate_unmap_pages(struct device *dev,
goto next;
if (is_zone_device_page(page)) {
- struct drm_pagemap_zdd *zdd = page->zone_device_data;
+ struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
struct drm_pagemap *dpagemap = zdd->dpagemap;
dpagemap->ops->device_unmap(dpagemap, dev, pagemap_addr[i]);
@@ -603,7 +603,8 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation,
pages[i] = NULL;
if (src_page && is_device_private_page(src_page)) {
- struct drm_pagemap_zdd *src_zdd = src_page->zone_device_data;
+ struct drm_pagemap_zdd *src_zdd =
+ drm_pagemap_page_zone_device_data(src_page);
if (page_pgmap(src_page) == pagemap &&
!mdetails->can_migrate_same_pagemap) {
@@ -725,8 +726,8 @@ static int drm_pagemap_migrate_populate_ram_pfn(struct vm_area_struct *vas,
goto next;
if (fault_page) {
- if (src_page->zone_device_data !=
- fault_page->zone_device_data)
+ if (drm_pagemap_page_zone_device_data(src_page) !=
+ drm_pagemap_page_zone_device_data(fault_page))
goto next;
}
@@ -1067,7 +1068,7 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
void *buf;
int i, err = 0;
- zdd = page->zone_device_data;
+ zdd = drm_pagemap_page_zone_device_data(page);
if (time_before64(get_jiffies_64(), zdd->devmem_allocation->timeslice_expiration))
return 0;
@@ -1150,7 +1151,9 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
*/
static void drm_pagemap_folio_free(struct folio *folio)
{
- drm_pagemap_zdd_put(folio->page.zone_device_data);
+ struct page *page = folio_page(folio, 0);
+
+ drm_pagemap_zdd_put(drm_pagemap_page_zone_device_data(page));
}
/**
@@ -1166,7 +1169,7 @@ static void drm_pagemap_folio_free(struct folio *folio)
*/
static vm_fault_t drm_pagemap_migrate_to_ram(struct vm_fault *vmf)
{
- struct drm_pagemap_zdd *zdd = vmf->page->zone_device_data;
+ struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(vmf->page);
int err;
err = __drm_pagemap_migrate_to_ram(vmf->vma,
@@ -1232,7 +1235,7 @@ EXPORT_SYMBOL_GPL(drm_pagemap_devmem_init);
*/
struct drm_pagemap *drm_pagemap_page_to_dpagemap(struct page *page)
{
- struct drm_pagemap_zdd *zdd = page->zone_device_data;
+ struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
return zdd->devmem_allocation->dpagemap;
}
diff --git a/include/drm/drm_pagemap.h b/include/drm/drm_pagemap.h
index 2baf0861f78f..c6459f4bde8b 100644
--- a/include/drm/drm_pagemap.h
+++ b/include/drm/drm_pagemap.h
@@ -4,6 +4,7 @@
#include <linux/dma-direction.h>
#include <linux/hmm.h>
+#include <linux/memremap.h>
#include <linux/types.h>
#define NR_PAGES(order) (1U << (order))
@@ -367,6 +368,19 @@ void drm_pagemap_destroy(struct drm_pagemap *dpagemap, bool is_atomic_or_reclaim
int drm_pagemap_reinit(struct drm_pagemap *dpagemap);
+/**
+ * drm_pagemap_page_zone_device_data() - Page to zone_device_data
+ * @page: Pointer to the page
+ *
+ * Return: Page's zone_device_data
+ */
+static inline struct drm_pagemap_zdd *drm_pagemap_page_zone_device_data(struct page *page)
+{
+ struct folio *folio = page_folio(page);
+
+ return folio_zone_device_data(folio);
+}
+
#endif /* IS_ENABLED(CONFIG_ZONE_DEVICE) */
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC PATCH v2 2/3] drm/gpusvm: Use new dma-map IOVA alloc, link, and sync API in GPU SVM
2026-01-23 21:59 [RFC PATCH v2 0/3] Use new dma-map IOVA alloc, link, and sync API in GPU SVM and DRM pagemap Matthew Brost
2026-01-23 21:59 ` [RFC PATCH v2 1/3] drm/pagemap: Add helper to access zone_device_data Matthew Brost
@ 2026-01-23 21:59 ` Matthew Brost
2026-01-23 21:59 ` [RFC PATCH v2 3/3] drm/pagemap: Use new dma-map IOVA alloc, link, and sync API for DRM pagemap Matthew Brost
2026-01-23 22:41 ` [RFC PATCH v2 0/3] Use new dma-map IOVA alloc, link, and sync API in GPU SVM and " Jason Gunthorpe
3 siblings, 0 replies; 10+ messages in thread
From: Matthew Brost @ 2026-01-23 21:59 UTC (permalink / raw)
To: intel-xe, dri-devel
Cc: leonro, francois.dugast, thomas.hellstrom, himal.prasad.ghimiray,
jgg
The dma-map IOVA alloc, link, and sync APIs perform significantly better
than dma-map / dma-unmap, as they avoid costly IOMMU synchronizations.
This difference is especially noticeable when mapping a 2MB region in
4KB pages.
Use the IOVA alloc, link, and sync APIs for GPU SVM, which create DMA
mappings between the CPU and GPU.
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/drm_gpusvm.c | 63 +++++++++++++++++++++++++-----------
include/drm/drm_gpusvm.h | 3 ++
2 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c
index 585d913d3d19..eff764445108 100644
--- a/drivers/gpu/drm/drm_gpusvm.c
+++ b/drivers/gpu/drm/drm_gpusvm.c
@@ -1139,19 +1139,26 @@ static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm,
struct drm_gpusvm_pages_flags flags = {
.__flags = svm_pages->flags.__flags,
};
+ struct dma_iova_state __state = {};
- for (i = 0, j = 0; i < npages; j++) {
- struct drm_pagemap_addr *addr = &svm_pages->dma_addr[j];
-
- if (addr->proto == DRM_INTERCONNECT_SYSTEM)
- dma_unmap_page(dev,
- addr->addr,
- PAGE_SIZE << addr->order,
- addr->dir);
- else if (dpagemap && dpagemap->ops->device_unmap)
- dpagemap->ops->device_unmap(dpagemap,
- dev, *addr);
- i += 1 << addr->order;
+ if (dma_use_iova(&svm_pages->state)) {
+ dma_iova_destroy(dev, &svm_pages->state,
+ npages * PAGE_SIZE,
+ svm_pages->dma_addr[0].dir, 0);
+ } else {
+ for (i = 0, j = 0; i < npages; j++) {
+ struct drm_pagemap_addr *addr = &svm_pages->dma_addr[j];
+
+ if (addr->proto == DRM_INTERCONNECT_SYSTEM)
+ dma_unmap_page(dev,
+ addr->addr,
+ PAGE_SIZE << addr->order,
+ addr->dir);
+ else if (dpagemap && dpagemap->ops->device_unmap)
+ dpagemap->ops->device_unmap(dpagemap,
+ dev, *addr);
+ i += 1 << addr->order;
+ }
}
/* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */
@@ -1161,6 +1168,7 @@ static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm,
drm_pagemap_put(svm_pages->dpagemap);
svm_pages->dpagemap = NULL;
+ svm_pages->state = __state;
}
}
@@ -1408,6 +1416,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
struct drm_gpusvm_pages_flags flags;
enum dma_data_direction dma_dir = ctx->read_only ? DMA_TO_DEVICE :
DMA_BIDIRECTIONAL;
+ struct dma_iova_state *state = &svm_pages->state;
retry:
if (time_after(jiffies, timeout))
@@ -1539,13 +1548,29 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
goto err_unmap;
}
- addr = dma_map_page(gpusvm->drm->dev,
- page, 0,
- PAGE_SIZE << order,
- dma_dir);
- if (dma_mapping_error(gpusvm->drm->dev, addr)) {
- err = -EFAULT;
- goto err_unmap;
+ if (!i)
+ dma_iova_try_alloc(gpusvm->drm->dev, state, 0,
+ npages * PAGE_SIZE);
+
+ if (dma_use_iova(state)) {
+ err = dma_iova_link(gpusvm->drm->dev, state,
+ page_to_phys(page),
+ i * PAGE_SIZE,
+ PAGE_SIZE << order,
+ dma_dir, 0);
+ if (err)
+ goto err_unmap;
+
+ addr = state->addr + i * PAGE_SIZE;
+ } else {
+ addr = dma_map_page(gpusvm->drm->dev,
+ page, 0,
+ PAGE_SIZE << order,
+ dma_dir);
+ if (dma_mapping_error(gpusvm->drm->dev, addr)) {
+ err = -EFAULT;
+ goto err_unmap;
+ }
}
svm_pages->dma_addr[j] = drm_pagemap_addr_encode
diff --git a/include/drm/drm_gpusvm.h b/include/drm/drm_gpusvm.h
index 2578ac92a8d4..6772d8a92788 100644
--- a/include/drm/drm_gpusvm.h
+++ b/include/drm/drm_gpusvm.h
@@ -6,6 +6,7 @@
#ifndef __DRM_GPUSVM_H__
#define __DRM_GPUSVM_H__
+#include <linux/dma-mapping.h>
#include <linux/kref.h>
#include <linux/interval_tree.h>
#include <linux/mmu_notifier.h>
@@ -136,6 +137,7 @@ struct drm_gpusvm_pages_flags {
* @dma_addr: Device address array
* @dpagemap: The struct drm_pagemap of the device pages we're dma-mapping.
* Note this is assuming only one drm_pagemap per range is allowed.
+ * @state: DMA IOVA state for mapping.
* @notifier_seq: Notifier sequence number of the range's pages
* @flags: Flags for range
* @flags.migrate_devmem: Flag indicating whether the range can be migrated to device memory
@@ -147,6 +149,7 @@ struct drm_gpusvm_pages_flags {
struct drm_gpusvm_pages {
struct drm_pagemap_addr *dma_addr;
struct drm_pagemap *dpagemap;
+ struct dma_iova_state state;
unsigned long notifier_seq;
struct drm_gpusvm_pages_flags flags;
};
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC PATCH v2 3/3] drm/pagemap: Use new dma-map IOVA alloc, link, and sync API for DRM pagemap
2026-01-23 21:59 [RFC PATCH v2 0/3] Use new dma-map IOVA alloc, link, and sync API in GPU SVM and DRM pagemap Matthew Brost
2026-01-23 21:59 ` [RFC PATCH v2 1/3] drm/pagemap: Add helper to access zone_device_data Matthew Brost
2026-01-23 21:59 ` [RFC PATCH v2 2/3] drm/gpusvm: Use new dma-map IOVA alloc, link, and sync API in GPU SVM Matthew Brost
@ 2026-01-23 21:59 ` Matthew Brost
2026-01-23 22:41 ` [RFC PATCH v2 0/3] Use new dma-map IOVA alloc, link, and sync API in GPU SVM and " Jason Gunthorpe
3 siblings, 0 replies; 10+ messages in thread
From: Matthew Brost @ 2026-01-23 21:59 UTC (permalink / raw)
To: intel-xe, dri-devel
Cc: leonro, francois.dugast, thomas.hellstrom, himal.prasad.ghimiray,
jgg
The dma-map IOVA alloc, link, and sync APIs perform significantly better
than dma-map / dma-unmap, as they avoid costly IOMMU synchronizations.
This difference is especially noticeable when mapping a 2MB region in
4KB pages.
Use the IOVA alloc, link, and sync APIs for DRM pagemap, which create DMA
mappings between the CPU and GPU for copying data.
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/drm_pagemap.c | 135 ++++++++++++++++++++++++++--------
1 file changed, 105 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
index 2c67aabd8d65..a4749aa77964 100644
--- a/drivers/gpu/drm/drm_pagemap.c
+++ b/drivers/gpu/drm/drm_pagemap.c
@@ -213,6 +213,7 @@ static void drm_pagemap_get_devmem_page(struct page *page,
* @npages: Number of system pages or peer pages to map.
* @dir: Direction of data transfer (e.g., DMA_BIDIRECTIONAL)
* @mdetails: Details governing the migration behaviour.
+ * @state: DMA IOVA state for mapping.
*
* This function maps pages of memory for migration usage in GPU SVM. It
* iterates over each page frame number provided in @migrate_pfn, maps the
@@ -227,27 +228,46 @@ static int drm_pagemap_migrate_map_pages(struct device *dev,
unsigned long *migrate_pfn,
unsigned long npages,
enum dma_data_direction dir,
- const struct drm_pagemap_migrate_details *mdetails)
+ const struct drm_pagemap_migrate_details *mdetails,
+ struct dma_iova_state *state)
{
- unsigned long num_peer_pages = 0, num_local_pages = 0, i;
+ unsigned long num_peer_pages = 0, num_local_pages = 0, psize, i;
+ struct page *dummy_page = NULL;
+ bool try_alloc = false, device_private = false;
+ int err = 0;
for (i = 0; i < npages;) {
struct page *page = migrate_pfn_to_page(migrate_pfn[i]);
- dma_addr_t dma_addr;
- struct folio *folio;
+ dma_addr_t dma_addr = -1;
unsigned int order = 0;
- if (!page)
+ /*
+ * This loop is a bit goofy, but if IOVA linking is used, the
+ * entire IOVA range must be populated with physical addresses.
+ * The first page we find, dummy_page, is therefore used to
+ * ensure every address in the IOVA range is populated.
+ */
+
+ if (!page && (device_private || !dummy_page))
goto next;
- folio = page_folio(page);
- order = folio_order(folio);
+ if (!page) {
+ page = dummy_page;
+ psize = PAGE_SIZE;
+ } else {
+ struct folio *folio;
+
+ folio = page_folio(page);
+ order = folio_order(folio);
+ psize = page_size(page);
+ }
if (is_device_private_page(page)) {
struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
struct drm_pagemap *dpagemap = zdd->dpagemap;
struct drm_pagemap_addr addr;
+ device_private = true;
if (dpagemap == local_dpagemap) {
if (!mdetails->can_migrate_same_pagemap)
goto next;
@@ -263,28 +283,68 @@ static int drm_pagemap_migrate_map_pages(struct device *dev,
pagemap_addr[i] = addr;
} else {
- dma_addr = dma_map_page(dev, page, 0, page_size(page), dir);
- if (dma_mapping_error(dev, dma_addr))
- return -EFAULT;
+ if (!try_alloc) {
+ dma_iova_try_alloc(dev, state, 0,
+ npages * PAGE_SIZE);
+ try_alloc = true;
+ }
+
+ if (dma_use_iova(state)) {
+ bool found_dummy = page && !dummy_page;
+
+ if (found_dummy) {
+ unsigned long j;
- pagemap_addr[i] =
- drm_pagemap_addr_encode(dma_addr,
- DRM_INTERCONNECT_SYSTEM,
- order, dir);
+ for (j = 0; j < i; ++j) {
+ err = dma_iova_link(dev, state,
+ page_to_phys(page),
+ j * PAGE_SIZE,
+ PAGE_SIZE,
+ dir, 0);
+ if (err)
+ return err;
+ }
+ }
+
+ err = dma_iova_link(dev, state, page_to_phys(page),
+ i * PAGE_SIZE, psize,
+ dir, 0);
+ if (err)
+ return err;
+
+ if (page != dummy_page)
+ dma_addr = state->addr + i * PAGE_SIZE;
+
+ if (found_dummy)
+ dummy_page = page;
+
+ } else {
+ dma_addr = dma_map_page(dev, page, 0, psize, dir);
+ if (dma_mapping_error(dev, dma_addr))
+ return -EFAULT;
+ }
+
+ if (dma_addr != -1)
+ pagemap_addr[i] =
+ drm_pagemap_addr_encode(dma_addr,
+ DRM_INTERCONNECT_SYSTEM,
+ order, dir);
}
next:
i += NR_PAGES(order);
}
- if (num_peer_pages)
+ if (dma_use_iova(state))
+ err = dma_iova_sync(dev, state, 0, npages * PAGE_SIZE);
+ if (!err && num_peer_pages)
drm_dbg(local_dpagemap->drm, "Migrating %lu peer pages over interconnect.\n",
num_peer_pages);
- if (num_local_pages)
+ if (!err && num_local_pages)
drm_dbg(local_dpagemap->drm, "Migrating %lu local pages over interconnect.\n",
num_local_pages);
- return 0;
+ return err;
}
/**
@@ -295,6 +355,7 @@ static int drm_pagemap_migrate_map_pages(struct device *dev,
* @pagemap_addr: Array of DMA information corresponding to mapped pages
* @npages: Number of pages to unmap
* @dir: Direction of data transfer (e.g., DMA_BIDIRECTIONAL)
+ * @state: DMA IOVA state for mapping.
*
* This function unmaps previously mapped pages of memory for GPU Shared Virtual
* Memory (SVM). It iterates over each DMA address provided in @dma_addr, checks
@@ -304,10 +365,16 @@ static void drm_pagemap_migrate_unmap_pages(struct device *dev,
struct drm_pagemap_addr *pagemap_addr,
unsigned long *migrate_pfn,
unsigned long npages,
- enum dma_data_direction dir)
+ enum dma_data_direction dir,
+ struct dma_iova_state *state)
{
unsigned long i;
+ if (dma_use_iova(state)) {
+ dma_iova_destroy(dev, state, npages * PAGE_SIZE, dir, 0);
+ return;
+ }
+
for (i = 0; i < npages;) {
struct page *page = migrate_pfn_to_page(migrate_pfn[i]);
@@ -344,12 +411,14 @@ drm_pagemap_migrate_remote_to_local(struct drm_pagemap_devmem *devmem,
struct drm_pagemap_addr pagemap_addr[],
unsigned long npages,
const struct drm_pagemap_devmem_ops *ops,
- const struct drm_pagemap_migrate_details *mdetails)
+ const struct drm_pagemap_migrate_details *mdetails,
+ struct dma_iova_state *state)
{
int err = drm_pagemap_migrate_map_pages(remote_device, remote_dpagemap,
pagemap_addr, local_pfns,
- npages, DMA_FROM_DEVICE, mdetails);
+ npages, DMA_FROM_DEVICE,
+ mdetails, state);
if (err)
goto out;
@@ -358,7 +427,7 @@ drm_pagemap_migrate_remote_to_local(struct drm_pagemap_devmem *devmem,
devmem->pre_migrate_fence);
out:
drm_pagemap_migrate_unmap_pages(remote_device, pagemap_addr, local_pfns,
- npages, DMA_FROM_DEVICE);
+ npages, DMA_FROM_DEVICE, state);
return err;
}
@@ -369,11 +438,12 @@ drm_pagemap_migrate_sys_to_dev(struct drm_pagemap_devmem *devmem,
struct drm_pagemap_addr pagemap_addr[],
unsigned long npages,
const struct drm_pagemap_devmem_ops *ops,
- const struct drm_pagemap_migrate_details *mdetails)
+ const struct drm_pagemap_migrate_details *mdetails,
+ struct dma_iova_state *state)
{
int err = drm_pagemap_migrate_map_pages(devmem->dev, devmem->dpagemap,
pagemap_addr, sys_pfns, npages,
- DMA_TO_DEVICE, mdetails);
+ DMA_TO_DEVICE, mdetails, state);
if (err)
goto out;
@@ -382,7 +452,7 @@ drm_pagemap_migrate_sys_to_dev(struct drm_pagemap_devmem *devmem,
devmem->pre_migrate_fence);
out:
drm_pagemap_migrate_unmap_pages(devmem->dev, pagemap_addr, sys_pfns, npages,
- DMA_TO_DEVICE);
+ DMA_TO_DEVICE, state);
return err;
}
@@ -410,6 +480,7 @@ static int drm_pagemap_migrate_range(struct drm_pagemap_devmem *devmem,
const struct migrate_range_loc *cur,
const struct drm_pagemap_migrate_details *mdetails)
{
+ struct dma_iova_state state = {};
int ret = 0;
if (cur->start == 0)
@@ -429,7 +500,8 @@ static int drm_pagemap_migrate_range(struct drm_pagemap_devmem *devmem,
&pages[last->start],
&pagemap_addr[last->start],
cur->start - last->start,
- last->ops, mdetails);
+ last->ops, mdetails,
+ &state);
else
ret = drm_pagemap_migrate_sys_to_dev(devmem,
@@ -437,7 +509,7 @@ static int drm_pagemap_migrate_range(struct drm_pagemap_devmem *devmem,
&pages[last->start],
&pagemap_addr[last->start],
cur->start - last->start,
- last->ops, mdetails);
+ last->ops, mdetails, &state);
out:
*last = *cur;
@@ -955,6 +1027,7 @@ int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
{
const struct drm_pagemap_devmem_ops *ops = devmem_allocation->ops;
struct drm_pagemap_migrate_details mdetails = {};
+ struct dma_iova_state state = {};
unsigned long npages, mpages = 0;
struct page **pages;
unsigned long *src, *dst;
@@ -996,7 +1069,7 @@ int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
err = drm_pagemap_migrate_map_pages(devmem_allocation->dev,
devmem_allocation->dpagemap, pagemap_addr,
dst, npages, DMA_FROM_DEVICE,
- &mdetails);
+ &mdetails, &state);
if (err)
goto err_finalize;
@@ -1013,7 +1086,7 @@ int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
migrate_device_pages(src, dst, npages);
migrate_device_finalize(src, dst, npages);
drm_pagemap_migrate_unmap_pages(devmem_allocation->dev, pagemap_addr, dst, npages,
- DMA_FROM_DEVICE);
+ DMA_FROM_DEVICE, &state);
err_free:
kvfree(buf);
@@ -1058,6 +1131,7 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
.fault_page = page,
};
struct drm_pagemap_migrate_details mdetails = {};
+ struct dma_iova_state state = {};
struct drm_pagemap_zdd *zdd;
const struct drm_pagemap_devmem_ops *ops;
struct device *dev = NULL;
@@ -1116,7 +1190,7 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
goto err_finalize;
err = drm_pagemap_migrate_map_pages(dev, zdd->dpagemap, pagemap_addr, migrate.dst, npages,
- DMA_FROM_DEVICE, &mdetails);
+ DMA_FROM_DEVICE, &mdetails, &state);
if (err)
goto err_finalize;
@@ -1134,7 +1208,8 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
migrate_vma_finalize(&migrate);
if (dev)
drm_pagemap_migrate_unmap_pages(dev, pagemap_addr, migrate.dst,
- npages, DMA_FROM_DEVICE);
+ npages, DMA_FROM_DEVICE,
+ &state);
err_free:
kvfree(buf);
err_out:
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread