41
41
#include <linux/hugetlb.h>
42
42
#include <linux/interval_tree.h>
43
43
#include <linux/hmm.h>
44
+ #include <linux/hmm-dma.h>
44
45
#include <linux/pagemap.h>
45
46
46
47
#include <rdma/ib_umem_odp.h>
50
51
static inline int ib_init_umem_odp (struct ib_umem_odp * umem_odp ,
51
52
const struct mmu_interval_notifier_ops * ops )
52
53
{
54
+ struct ib_device * dev = umem_odp -> umem .ibdev ;
53
55
int ret ;
54
56
55
57
umem_odp -> umem .is_odp = 1 ;
@@ -59,7 +61,6 @@ static inline int ib_init_umem_odp(struct ib_umem_odp *umem_odp,
59
61
size_t page_size = 1UL << umem_odp -> page_shift ;
60
62
unsigned long start ;
61
63
unsigned long end ;
62
- size_t ndmas , npfns ;
63
64
64
65
start = ALIGN_DOWN (umem_odp -> umem .address , page_size );
65
66
if (check_add_overflow (umem_odp -> umem .address ,
@@ -70,36 +71,23 @@ static inline int ib_init_umem_odp(struct ib_umem_odp *umem_odp,
70
71
if (unlikely (end < page_size ))
71
72
return - EOVERFLOW ;
72
73
73
- ndmas = (end - start ) >> umem_odp -> page_shift ;
74
- if (!ndmas )
75
- return - EINVAL ;
76
-
77
- npfns = (end - start ) >> PAGE_SHIFT ;
78
- umem_odp -> pfn_list = kvcalloc (
79
- npfns , sizeof (* umem_odp -> pfn_list ), GFP_KERNEL );
80
- if (!umem_odp -> pfn_list )
81
- return - ENOMEM ;
82
-
83
- umem_odp -> dma_list = kvcalloc (
84
- ndmas , sizeof (* umem_odp -> dma_list ), GFP_KERNEL );
85
- if (!umem_odp -> dma_list ) {
86
- ret = - ENOMEM ;
87
- goto out_pfn_list ;
88
- }
74
+ ret = hmm_dma_map_alloc (dev -> dma_device , & umem_odp -> map ,
75
+ (end - start ) >> PAGE_SHIFT ,
76
+ 1 << umem_odp -> page_shift );
77
+ if (ret )
78
+ return ret ;
89
79
90
80
ret = mmu_interval_notifier_insert (& umem_odp -> notifier ,
91
81
umem_odp -> umem .owning_mm ,
92
82
start , end - start , ops );
93
83
if (ret )
94
- goto out_dma_list ;
84
+ goto out_free_map ;
95
85
}
96
86
97
87
return 0 ;
98
88
99
- out_dma_list :
100
- kvfree (umem_odp -> dma_list );
101
- out_pfn_list :
102
- kvfree (umem_odp -> pfn_list );
89
+ out_free_map :
90
+ hmm_dma_map_free (dev -> dma_device , & umem_odp -> map );
103
91
return ret ;
104
92
}
105
93
@@ -262,6 +250,8 @@ EXPORT_SYMBOL(ib_umem_odp_get);
262
250
263
251
void ib_umem_odp_release (struct ib_umem_odp * umem_odp )
264
252
{
253
+ struct ib_device * dev = umem_odp -> umem .ibdev ;
254
+
265
255
/*
266
256
* Ensure that no more pages are mapped in the umem.
267
257
*
@@ -274,48 +264,17 @@ void ib_umem_odp_release(struct ib_umem_odp *umem_odp)
274
264
ib_umem_end (umem_odp ));
275
265
mutex_unlock (& umem_odp -> umem_mutex );
276
266
mmu_interval_notifier_remove (& umem_odp -> notifier );
277
- kvfree (umem_odp -> dma_list );
278
- kvfree (umem_odp -> pfn_list );
267
+ hmm_dma_map_free (dev -> dma_device , & umem_odp -> map );
279
268
}
280
269
put_pid (umem_odp -> tgid );
281
270
kfree (umem_odp );
282
271
}
283
272
EXPORT_SYMBOL (ib_umem_odp_release );
284
273
285
- /*
286
- * Map for DMA and insert a single page into the on-demand paging page tables.
287
- *
288
- * @umem: the umem to insert the page to.
289
- * @dma_index: index in the umem to add the dma to.
290
- * @page: the page struct to map and add.
291
- * @access_mask: access permissions needed for this page.
292
- *
293
- * The function returns -EFAULT if the DMA mapping operation fails.
294
- *
295
- */
296
- static int ib_umem_odp_map_dma_single_page (
297
- struct ib_umem_odp * umem_odp ,
298
- unsigned int dma_index ,
299
- struct page * page )
300
- {
301
- struct ib_device * dev = umem_odp -> umem .ibdev ;
302
- dma_addr_t * dma_addr = & umem_odp -> dma_list [dma_index ];
303
-
304
- * dma_addr = ib_dma_map_page (dev , page , 0 , 1 << umem_odp -> page_shift ,
305
- DMA_BIDIRECTIONAL );
306
- if (ib_dma_mapping_error (dev , * dma_addr )) {
307
- * dma_addr = 0 ;
308
- return - EFAULT ;
309
- }
310
- umem_odp -> npages ++ ;
311
- return 0 ;
312
- }
313
-
314
274
/**
315
275
* ib_umem_odp_map_dma_and_lock - DMA map userspace memory in an ODP MR and lock it.
316
276
*
317
277
* Maps the range passed in the argument to DMA addresses.
318
- * The DMA addresses of the mapped pages is updated in umem_odp->dma_list.
319
278
* Upon success the ODP MR will be locked to let caller complete its device
320
279
* page table update.
321
280
*
@@ -372,7 +331,7 @@ int ib_umem_odp_map_dma_and_lock(struct ib_umem_odp *umem_odp, u64 user_virt,
372
331
range .default_flags |= HMM_PFN_REQ_WRITE ;
373
332
}
374
333
375
- range .hmm_pfns = & (umem_odp -> pfn_list [pfn_start_idx ]);
334
+ range .hmm_pfns = & (umem_odp -> map . pfn_list [pfn_start_idx ]);
376
335
timeout = jiffies + msecs_to_jiffies (HMM_RANGE_DEFAULT_TIMEOUT );
377
336
378
337
retry :
@@ -423,16 +382,6 @@ int ib_umem_odp_map_dma_and_lock(struct ib_umem_odp *umem_odp, u64 user_virt,
423
382
__func__ , hmm_order , page_shift );
424
383
break ;
425
384
}
426
-
427
- ret = ib_umem_odp_map_dma_single_page (
428
- umem_odp , dma_index ,
429
- hmm_pfn_to_page (range .hmm_pfns [pfn_index ]));
430
- if (ret < 0 ) {
431
- ibdev_dbg (umem_odp -> umem .ibdev ,
432
- "ib_umem_odp_map_dma_single_page failed with error %d\n" , ret );
433
- break ;
434
- }
435
- range .hmm_pfns [pfn_index ] |= HMM_PFN_DMA_MAPPED ;
436
385
}
437
386
/* upon success lock should stay on hold for the callee */
438
387
if (!ret )
@@ -452,32 +401,23 @@ EXPORT_SYMBOL(ib_umem_odp_map_dma_and_lock);
452
401
void ib_umem_odp_unmap_dma_pages (struct ib_umem_odp * umem_odp , u64 virt ,
453
402
u64 bound )
454
403
{
455
- dma_addr_t dma ;
456
- int idx ;
457
- u64 addr ;
458
404
struct ib_device * dev = umem_odp -> umem .ibdev ;
405
+ u64 addr ;
459
406
460
407
lockdep_assert_held (& umem_odp -> umem_mutex );
461
408
462
409
virt = max_t (u64 , virt , ib_umem_start (umem_odp ));
463
410
bound = min_t (u64 , bound , ib_umem_end (umem_odp ));
464
411
for (addr = virt ; addr < bound ; addr += BIT (umem_odp -> page_shift )) {
465
- unsigned long pfn_idx = (addr - ib_umem_start (umem_odp )) >>
466
- PAGE_SHIFT ;
467
- struct page * page =
468
- hmm_pfn_to_page (umem_odp -> pfn_list [pfn_idx ]);
469
-
470
- idx = (addr - ib_umem_start (umem_odp )) >> umem_odp -> page_shift ;
471
- dma = umem_odp -> dma_list [idx ];
412
+ u64 offset = addr - ib_umem_start (umem_odp );
413
+ size_t idx = offset >> umem_odp -> page_shift ;
414
+ unsigned long pfn = umem_odp -> map .pfn_list [idx ];
472
415
473
- if (!(umem_odp -> pfn_list [pfn_idx ] & HMM_PFN_VALID ))
474
- goto clear ;
475
- if (!(umem_odp -> pfn_list [pfn_idx ] & HMM_PFN_DMA_MAPPED ))
416
+ if (!hmm_dma_unmap_pfn (dev -> dma_device , & umem_odp -> map , idx ))
476
417
goto clear ;
477
418
478
- ib_dma_unmap_page (dev , dma , BIT (umem_odp -> page_shift ),
479
- DMA_BIDIRECTIONAL );
480
- if (umem_odp -> pfn_list [pfn_idx ] & HMM_PFN_WRITE ) {
419
+ if (pfn & HMM_PFN_WRITE ) {
420
+ struct page * page = hmm_pfn_to_page (pfn );
481
421
struct page * head_page = compound_head (page );
482
422
/*
483
423
* set_page_dirty prefers being called with
@@ -492,7 +432,7 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 virt,
492
432
}
493
433
umem_odp -> npages -- ;
494
434
clear :
495
- umem_odp -> pfn_list [pfn_idx ] &= ~HMM_PFN_FLAGS ;
435
+ umem_odp -> map . pfn_list [idx ] &= ~HMM_PFN_FLAGS ;
496
436
}
497
437
}
498
438
EXPORT_SYMBOL (ib_umem_odp_unmap_dma_pages );
0 commit comments