Skip to content

Commit 8bfafde

Browse files
yishaihjgunthorpe
authored andcommitted
IB/core: Enable ODP sync without faulting
Enable ODP sync without faulting, this improves performance by reducing the number of page faults in the system. The gain from this option is that the device page table can be aligned with the presented pages in the CPU page table without causing page faults. As of that, the overhead on data path from hardware point of view to trigger a fault which end-up by calling the driver to bring the pages will be dropped. Link: https://lore.kernel.org/r/20200930163828.1336747-3-leon@kernel.org Signed-off-by: Yishai Hadas <yishaih@nvidia.com> Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent 36f30e4 commit 8bfafde

3 files changed

Lines changed: 27 additions & 12 deletions

File tree

drivers/infiniband/core/umem_odp.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,10 @@ static int ib_umem_odp_map_dma_single_page(
347347
* the return value.
348348
* @access_mask: bit mask of the requested access permissions for the given
349349
* range.
350+
* @fault: is faulting required for the given range
350351
*/
351352
int ib_umem_odp_map_dma_and_lock(struct ib_umem_odp *umem_odp, u64 user_virt,
352-
u64 bcnt, u64 access_mask)
353+
u64 bcnt, u64 access_mask, bool fault)
353354
__acquires(&umem_odp->umem_mutex)
354355
{
355356
struct task_struct *owning_process = NULL;
@@ -385,10 +386,12 @@ int ib_umem_odp_map_dma_and_lock(struct ib_umem_odp *umem_odp, u64 user_virt,
385386
range.end = ALIGN(user_virt + bcnt, 1UL << page_shift);
386387
pfn_start_idx = (range.start - ib_umem_start(umem_odp)) >> PAGE_SHIFT;
387388
num_pfns = (range.end - range.start) >> PAGE_SHIFT;
388-
range.default_flags = HMM_PFN_REQ_FAULT;
389+
if (fault) {
390+
range.default_flags = HMM_PFN_REQ_FAULT;
389391

390-
if (access_mask & ODP_WRITE_ALLOWED_BIT)
391-
range.default_flags |= HMM_PFN_REQ_WRITE;
392+
if (access_mask & ODP_WRITE_ALLOWED_BIT)
393+
range.default_flags |= HMM_PFN_REQ_WRITE;
394+
}
392395

393396
range.hmm_pfns = &(umem_odp->pfn_list[pfn_start_idx]);
394397
timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
@@ -417,12 +420,24 @@ int ib_umem_odp_map_dma_and_lock(struct ib_umem_odp *umem_odp, u64 user_virt,
417420

418421
for (pfn_index = 0; pfn_index < num_pfns;
419422
pfn_index += 1 << (page_shift - PAGE_SHIFT), dma_index++) {
420-
/*
421-
* Since we asked for hmm_range_fault() to populate pages,
422-
* it shouldn't return an error entry on success.
423-
*/
424-
WARN_ON(range.hmm_pfns[pfn_index] & HMM_PFN_ERROR);
425-
WARN_ON(!(range.hmm_pfns[pfn_index] & HMM_PFN_VALID));
423+
424+
if (fault) {
425+
/*
426+
* Since we asked for hmm_range_fault() to populate
427+
* pages it shouldn't return an error entry on success.
428+
*/
429+
WARN_ON(range.hmm_pfns[pfn_index] & HMM_PFN_ERROR);
430+
WARN_ON(!(range.hmm_pfns[pfn_index] & HMM_PFN_VALID));
431+
} else {
432+
if (!(range.hmm_pfns[pfn_index] & HMM_PFN_VALID)) {
433+
WARN_ON(umem_odp->dma_list[dma_index]);
434+
continue;
435+
}
436+
access_mask = ODP_READ_ALLOWED_BIT;
437+
if (range.hmm_pfns[pfn_index] & HMM_PFN_WRITE)
438+
access_mask |= ODP_WRITE_ALLOWED_BIT;
439+
}
440+
426441
hmm_order = hmm_pfn_to_map_order(range.hmm_pfns[pfn_index]);
427442
/* If a hugepage was detected and ODP wasn't set for, the umem
428443
* page_shift will be used, the opposite case is an error.

drivers/infiniband/hw/mlx5/odp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ static int pagefault_real_mr(struct mlx5_ib_mr *mr, struct ib_umem_odp *odp,
681681
if (odp->umem.writable && !downgrade)
682682
access_mask |= ODP_WRITE_ALLOWED_BIT;
683683

684-
np = ib_umem_odp_map_dma_and_lock(odp, user_va, bcnt, access_mask);
684+
np = ib_umem_odp_map_dma_and_lock(odp, user_va, bcnt, access_mask, true);
685685
if (np < 0)
686686
return np;
687687

include/rdma/ib_umem_odp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ ib_umem_odp_alloc_child(struct ib_umem_odp *root_umem, unsigned long addr,
9494
void ib_umem_odp_release(struct ib_umem_odp *umem_odp);
9595

9696
int ib_umem_odp_map_dma_and_lock(struct ib_umem_odp *umem_odp, u64 start_offset,
97-
u64 bcnt, u64 access_mask);
97+
u64 bcnt, u64 access_mask, bool fault);
9898

9999
void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 start_offset,
100100
u64 bound);

0 commit comments

Comments
 (0)