Skip to content

Commit f8477ce

Browse files
Ralph Campbelljgunthorpe
authored andcommitted
nouveau/svm: use the new migration invalidation
Use the new MMU_NOTIFY_MIGRATE event to skip GPU MMU invalidations of device private memory and handle the invalidation in the driver as part of migrating device private memory. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ralph Campbell <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 998427b commit f8477ce

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

drivers/gpu/drm/nouveau/nouveau_dmem.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ static vm_fault_t nouveau_dmem_fault_copy_one(struct nouveau_drm *drm,
140140
{
141141
struct device *dev = drm->dev->dev;
142142
struct page *dpage, *spage;
143+
struct nouveau_svmm *svmm;
143144

144145
spage = migrate_pfn_to_page(args->src[0]);
145146
if (!spage || !(args->src[0] & MIGRATE_PFN_MIGRATE))
@@ -154,14 +155,19 @@ static vm_fault_t nouveau_dmem_fault_copy_one(struct nouveau_drm *drm,
154155
if (dma_mapping_error(dev, *dma_addr))
155156
goto error_free_page;
156157

158+
svmm = spage->zone_device_data;
159+
mutex_lock(&svmm->mutex);
160+
nouveau_svmm_invalidate(svmm, args->start, args->end);
157161
if (drm->dmem->migrate.copy_func(drm, 1, NOUVEAU_APER_HOST, *dma_addr,
158162
NOUVEAU_APER_VRAM, nouveau_dmem_page_addr(spage)))
159163
goto error_dma_unmap;
164+
mutex_unlock(&svmm->mutex);
160165

161166
args->dst[0] = migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED;
162167
return 0;
163168

164169
error_dma_unmap:
170+
mutex_unlock(&svmm->mutex);
165171
dma_unmap_page(dev, *dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
166172
error_free_page:
167173
__free_page(dpage);
@@ -531,7 +537,8 @@ nouveau_dmem_init(struct nouveau_drm *drm)
531537
}
532538

533539
static unsigned long nouveau_dmem_migrate_copy_one(struct nouveau_drm *drm,
534-
unsigned long src, dma_addr_t *dma_addr, u64 *pfn)
540+
struct nouveau_svmm *svmm, unsigned long src,
541+
dma_addr_t *dma_addr, u64 *pfn)
535542
{
536543
struct device *dev = drm->dev->dev;
537544
struct page *dpage, *spage;
@@ -561,6 +568,7 @@ static unsigned long nouveau_dmem_migrate_copy_one(struct nouveau_drm *drm,
561568
goto out_free_page;
562569
}
563570

571+
dpage->zone_device_data = svmm;
564572
*pfn = NVIF_VMM_PFNMAP_V0_V | NVIF_VMM_PFNMAP_V0_VRAM |
565573
((paddr >> PAGE_SHIFT) << NVIF_VMM_PFNMAP_V0_ADDR_SHIFT);
566574
if (src & MIGRATE_PFN_WRITE)
@@ -584,8 +592,8 @@ static void nouveau_dmem_migrate_chunk(struct nouveau_drm *drm,
584592
unsigned long addr = args->start, nr_dma = 0, i;
585593

586594
for (i = 0; addr < args->end; i++) {
587-
args->dst[i] = nouveau_dmem_migrate_copy_one(drm, args->src[i],
588-
dma_addrs + nr_dma, pfns + i);
595+
args->dst[i] = nouveau_dmem_migrate_copy_one(drm, svmm,
596+
args->src[i], dma_addrs + nr_dma, pfns + i);
589597
if (!dma_mapping_error(drm->dev->dev, dma_addrs[nr_dma]))
590598
nr_dma++;
591599
addr += PAGE_SIZE;
@@ -616,6 +624,7 @@ nouveau_dmem_migrate_vma(struct nouveau_drm *drm,
616624
struct migrate_vma args = {
617625
.vma = vma,
618626
.start = start,
627+
.pgmap_owner = drm->dev,
619628
.flags = MIGRATE_VMA_SELECT_SYSTEM,
620629
};
621630
unsigned long i;

drivers/gpu/drm/nouveau/nouveau_svm.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,6 @@ nouveau_ivmm_find(struct nouveau_svm *svm, u64 inst)
9393
return NULL;
9494
}
9595

96-
struct nouveau_svmm {
97-
struct mmu_notifier notifier;
98-
struct nouveau_vmm *vmm;
99-
struct {
100-
unsigned long start;
101-
unsigned long limit;
102-
} unmanaged;
103-
104-
struct mutex mutex;
105-
};
106-
10796
#define SVMM_DBG(s,f,a...) \
10897
NV_DEBUG((s)->vmm->cli->drm, "svm-%p: "f"\n", (s), ##a)
10998
#define SVMM_ERR(s,f,a...) \
@@ -246,7 +235,7 @@ nouveau_svmm_join(struct nouveau_svmm *svmm, u64 inst)
246235
}
247236

248237
/* Invalidate SVMM address-range on GPU. */
249-
static void
238+
void
250239
nouveau_svmm_invalidate(struct nouveau_svmm *svmm, u64 start, u64 limit)
251240
{
252241
if (limit > start) {
@@ -279,6 +268,14 @@ nouveau_svmm_invalidate_range_start(struct mmu_notifier *mn,
279268
if (unlikely(!svmm->vmm))
280269
goto out;
281270

271+
/*
272+
* Ignore invalidation callbacks for device private pages since
273+
* the invalidation is handled as part of the migration process.
274+
*/
275+
if (update->event == MMU_NOTIFY_MIGRATE &&
276+
update->migrate_pgmap_owner == svmm->vmm->cli->drm->dev)
277+
goto out;
278+
282279
if (limit > svmm->unmanaged.start && start < svmm->unmanaged.limit) {
283280
if (start < svmm->unmanaged.start) {
284281
nouveau_svmm_invalidate(svmm, start,

drivers/gpu/drm/nouveau/nouveau_svm.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
#ifndef __NOUVEAU_SVM_H__
22
#define __NOUVEAU_SVM_H__
33
#include <nvif/os.h>
4+
#include <linux/mmu_notifier.h>
45
struct drm_device;
56
struct drm_file;
67
struct nouveau_drm;
78

8-
struct nouveau_svmm;
9+
struct nouveau_svmm {
10+
struct mmu_notifier notifier;
11+
struct nouveau_vmm *vmm;
12+
struct {
13+
unsigned long start;
14+
unsigned long limit;
15+
} unmanaged;
16+
17+
struct mutex mutex;
18+
};
919

1020
#if IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM)
1121
void nouveau_svm_init(struct nouveau_drm *);
@@ -19,6 +29,7 @@ int nouveau_svmm_join(struct nouveau_svmm *, u64 inst);
1929
void nouveau_svmm_part(struct nouveau_svmm *, u64 inst);
2030
int nouveau_svmm_bind(struct drm_device *, void *, struct drm_file *);
2131

32+
void nouveau_svmm_invalidate(struct nouveau_svmm *svmm, u64 start, u64 limit);
2233
u64 *nouveau_pfns_alloc(unsigned long npages);
2334
void nouveau_pfns_free(u64 *pfns);
2435
void nouveau_pfns_map(struct nouveau_svmm *svmm, struct mm_struct *mm,

0 commit comments

Comments
 (0)