Skip to content

Commit 680a383

Browse files
eugpermargregkh
authored andcommitted
vduse: take out allocations from vduse_dev_alloc_coherent
[ Upstream commit 489d765 ] The function vduse_dev_alloc_coherent will be called under rwlock in next patches. Make it out of the lock to avoid increasing its fail rate. Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Eugenio Pérez <eperezma@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260119143306.1818855-10-eperezma@redhat.com> Stable-dep-of: 9c15238 ("VDUSE: avoid leaking information to userspace") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 0a0f90a commit 680a383

3 files changed

Lines changed: 19 additions & 24 deletions

File tree

drivers/vdpa/vdpa_user/iova_domain.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -479,17 +479,15 @@ void vduse_domain_unmap_page(struct vduse_iova_domain *domain,
479479
vduse_domain_free_iova(iovad, dma_addr, size);
480480
}
481481

482-
void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain,
483-
size_t size, dma_addr_t *dma_addr,
484-
gfp_t flag, unsigned long attrs)
482+
dma_addr_t vduse_domain_alloc_coherent(struct vduse_iova_domain *domain,
483+
size_t size, void *orig)
485484
{
486485
struct iova_domain *iovad = &domain->consistent_iovad;
487486
unsigned long limit = domain->iova_limit;
488487
dma_addr_t iova = vduse_domain_alloc_iova(iovad, size, limit);
489-
void *orig = alloc_pages_exact(size, flag);
490488

491-
if (!iova || !orig)
492-
goto err;
489+
if (!iova)
490+
return DMA_MAPPING_ERROR;
493491

494492
spin_lock(&domain->iotlb_lock);
495493
if (vduse_iotlb_add_range(domain, (u64)iova, (u64)iova + size - 1,
@@ -500,17 +498,12 @@ void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain,
500498
}
501499
spin_unlock(&domain->iotlb_lock);
502500

503-
*dma_addr = iova;
501+
return iova;
504502

505-
return orig;
506503
err:
507-
*dma_addr = DMA_MAPPING_ERROR;
508-
if (orig)
509-
free_pages_exact(orig, size);
510-
if (iova)
511-
vduse_domain_free_iova(iovad, iova, size);
504+
vduse_domain_free_iova(iovad, iova, size);
512505

513-
return NULL;
506+
return DMA_MAPPING_ERROR;
514507
}
515508

516509
void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size,
@@ -519,7 +512,6 @@ void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size,
519512
struct iova_domain *iovad = &domain->consistent_iovad;
520513
struct vhost_iotlb_map *map;
521514
struct vdpa_map_file *map_file;
522-
phys_addr_t pa;
523515

524516
spin_lock(&domain->iotlb_lock);
525517
map = vhost_iotlb_itree_first(domain->iotlb, (u64)dma_addr,
@@ -531,12 +523,10 @@ void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size,
531523
map_file = (struct vdpa_map_file *)map->opaque;
532524
fput(map_file->file);
533525
kfree(map_file);
534-
pa = map->addr;
535526
vhost_iotlb_map_free(domain->iotlb, map);
536527
spin_unlock(&domain->iotlb_lock);
537528

538529
vduse_domain_free_iova(iovad, dma_addr, size);
539-
free_pages_exact(phys_to_virt(pa), size);
540530
}
541531

542532
static vm_fault_t vduse_domain_mmap_fault(struct vm_fault *vmf)

drivers/vdpa/vdpa_user/iova_domain.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,8 @@ void vduse_domain_unmap_page(struct vduse_iova_domain *domain,
5858
dma_addr_t dma_addr, size_t size,
5959
enum dma_data_direction dir, unsigned long attrs);
6060

61-
void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain,
62-
size_t size, dma_addr_t *dma_addr,
63-
gfp_t flag, unsigned long attrs);
61+
dma_addr_t vduse_domain_alloc_coherent(struct vduse_iova_domain *domain,
62+
size_t size, void *orig);
6463

6564
void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size,
6665
dma_addr_t dma_addr, unsigned long attrs);

drivers/vdpa/vdpa_user/vduse_dev.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -851,18 +851,23 @@ static void *vduse_dev_alloc_coherent(struct device *dev, size_t size,
851851
{
852852
struct vduse_dev *vdev = dev_to_vduse(dev);
853853
struct vduse_iova_domain *domain = vdev->domain;
854-
unsigned long iova;
855854
void *addr;
856855

857856
*dma_addr = DMA_MAPPING_ERROR;
858-
addr = vduse_domain_alloc_coherent(domain, size,
859-
(dma_addr_t *)&iova, flag, attrs);
857+
858+
addr = alloc_pages_exact(size, flag);
860859
if (!addr)
861860
return NULL;
862861

863-
*dma_addr = (dma_addr_t)iova;
862+
*dma_addr = vduse_domain_alloc_coherent(domain, size, addr);
863+
if (*dma_addr == DMA_MAPPING_ERROR)
864+
goto err;
864865

865866
return addr;
867+
868+
err:
869+
free_pages_exact(addr, size);
870+
return NULL;
866871
}
867872

868873
static void vduse_dev_free_coherent(struct device *dev, size_t size,
@@ -873,6 +878,7 @@ static void vduse_dev_free_coherent(struct device *dev, size_t size,
873878
struct vduse_iova_domain *domain = vdev->domain;
874879

875880
vduse_domain_free_coherent(domain, size, dma_addr, attrs);
881+
free_pages_exact(vaddr, size);
876882
}
877883

878884
static size_t vduse_dev_max_mapping_size(struct device *dev)

0 commit comments

Comments
 (0)