please use vhost as the commit title prefix (please use git blame to refer),
the same as other commit in this patchset.

How about: vhost: refactor memory helper functions

On 5/15/2026 6:46 AM, [email protected] wrote:
> From: Pravin M Bathija <[email protected]>
> 
> Here we define support functions which are called from the various
> vhost-user back-end message functions like set memory table, get
> memory slots, add memory region, remove memory region.  These are
> essentially common functions to unmap a set of memory regions,
> perform register copy, align memory addresses and dma map/unmap a
> single memory region.

Two much detail, how about:

Extract reusable helper routines for vhost-user backend memory operations:
split DMA map/unmap into per-region logic, decouple and rework memory
region free routines, and iterate over VHOST_MEMORY_MAX_NREGIONS
uniformly across related functions to simplify code reuse.

As above fixed:
Acked-by: Chengwen Feng <[email protected]>

> 
> Signed-off-by: Pravin M Bathija <[email protected]>
> ---
>  lib/vhost/vhost_user.c | 89 ++++++++++++++++++++++++++++--------------
>  1 file changed, 60 insertions(+), 29 deletions(-)
> 
> diff --git a/lib/vhost/vhost_user.c b/lib/vhost/vhost_user.c
> index 4bfb13fb98..0ee3fe7a5e 100644
> --- a/lib/vhost/vhost_user.c
> +++ b/lib/vhost/vhost_user.c
> @@ -171,20 +171,27 @@ get_blk_size(int fd)
>       return ret == -1 ? (uint64_t)-1 : (uint64_t)stat.st_blksize;
>  }
>  
> -static void
> -async_dma_map(struct virtio_net *dev, bool do_map)
> +static int
> +async_dma_map_region(struct virtio_net *dev, struct rte_vhost_mem_region 
> *reg, bool do_map)
>  {
> -     int ret = 0;
>       uint32_t i;
> -     struct guest_page *page;
> +     int ret;
> +     uint64_t reg_start = reg->host_user_addr;
> +     uint64_t reg_end = reg_start + reg->size;
> +
> +     for (i = 0; i < dev->nr_guest_pages; i++) {
> +             struct guest_page *page = &dev->guest_pages[i];
> +
> +             /* Only process pages belonging to this region */
> +             if (page->host_user_addr < reg_start ||
> +                 page->host_user_addr >= reg_end)
> +                     continue;
>  
> -     if (do_map) {
> -             for (i = 0; i < dev->nr_guest_pages; i++) {
> -                     page = &dev->guest_pages[i];
> +             if (do_map) {
>                       ret = 
> rte_vfio_container_dma_map(RTE_VFIO_DEFAULT_CONTAINER_FD,
> -                                                      page->host_user_addr,
> -                                                      page->host_iova,
> -                                                      page->size);
> +                                     page->host_user_addr,
> +                                     page->host_iova,
> +                                     page->size);
>                       if (ret) {
>                               /*
>                                * DMA device may bind with kernel driver, in 
> this case,
> @@ -199,33 +206,57 @@ async_dma_map(struct virtio_net *dev, bool do_map)
>                                * normal case in async path. This is a 
> workaround.
>                                */
>                               if (rte_errno == ENODEV)
> -                                     return;
> +                                     return 0;
>  
>                               /* DMA mapping errors won't stop 
> VHOST_USER_SET_MEM_TABLE. */
>                               VHOST_CONFIG_LOG(dev->ifname, ERR, "DMA engine 
> map failed");
> +                             return -1;
>                       }
> -             }
> -
> -     } else {
> -             for (i = 0; i < dev->nr_guest_pages; i++) {
> -                     page = &dev->guest_pages[i];
> +             } else {
>                       ret = 
> rte_vfio_container_dma_unmap(RTE_VFIO_DEFAULT_CONTAINER_FD,
> -                                                        page->host_user_addr,
> -                                                        page->host_iova,
> -                                                        page->size);
> +                                     page->host_user_addr,
> +                                     page->host_iova,
> +                                     page->size);
>                       if (ret) {
>                               /* like DMA map, ignore the kernel driver case 
> when unmap. */
>                               if (rte_errno == EINVAL)
> -                                     return;
> +                                     return 0;
>  
>                               VHOST_CONFIG_LOG(dev->ifname, ERR, "DMA engine 
> unmap failed");
> +                             return -1;
>                       }
>               }
>       }
> +
> +     return 0;
> +}
> +
> +static void
> +async_dma_map(struct virtio_net *dev, bool do_map)
> +{
> +     uint32_t i;
> +     struct rte_vhost_mem_region *reg;
> +
> +     for (i = 0; i < VHOST_MEMORY_MAX_NREGIONS; i++) {
> +             reg = &dev->mem->regions[i];
> +             if (reg->host_user_addr == 0)
> +                     continue;
> +             async_dma_map_region(dev, reg, do_map);
> +     }
>  }
>  
>  static void
> -free_mem_region(struct virtio_net *dev)
> +free_mem_region(struct rte_vhost_mem_region *reg)
> +{
> +     if (reg != NULL && reg->mmap_addr) {
> +             munmap(reg->mmap_addr, reg->mmap_size);
> +             close(reg->fd);
> +             memset(reg, 0, sizeof(struct rte_vhost_mem_region));
> +     }
> +}
> +
> +static void
> +free_all_mem_regions(struct virtio_net *dev)
>  {
>       uint32_t i;
>       struct rte_vhost_mem_region *reg;
> @@ -236,12 +267,10 @@ free_mem_region(struct virtio_net *dev)
>       if (dev->async_copy && rte_vfio_is_enabled("vfio"))
>               async_dma_map(dev, false);
>  
> -     for (i = 0; i < dev->mem->nregions; i++) {
> +     for (i = 0; i < VHOST_MEMORY_MAX_NREGIONS; i++) {
>               reg = &dev->mem->regions[i];
> -             if (reg->host_user_addr) {
> -                     munmap(reg->mmap_addr, reg->mmap_size);
> -                     close(reg->fd);
> -             }
> +             if (reg->mmap_addr)
> +                     free_mem_region(reg);
>       }
>  }
>  
> @@ -255,7 +284,7 @@ vhost_backend_cleanup(struct virtio_net *dev)
>               vdpa_dev->ops->dev_cleanup(dev->vid);
>  
>       if (dev->mem) {
> -             free_mem_region(dev);
> +             free_all_mem_regions(dev);
>               rte_free(dev->mem);
>               dev->mem = NULL;
>       }
> @@ -704,7 +733,7 @@ numa_realloc(struct virtio_net **pdev, struct 
> vhost_virtqueue **pvq)
>       vhost_devices[dev->vid] = dev;
>  
>       mem_size = sizeof(struct rte_vhost_memory) +
> -             sizeof(struct rte_vhost_mem_region) * dev->mem->nregions;
> +             sizeof(struct rte_vhost_mem_region) * VHOST_MEMORY_MAX_NREGIONS;
>       mem = rte_realloc_socket(dev->mem, mem_size, 0, node);
>       if (!mem) {
>               VHOST_CONFIG_LOG(dev->ifname, ERR,
> @@ -808,8 +837,10 @@ hua_to_alignment(struct rte_vhost_memory *mem, void *ptr)
>       uint32_t i;
>       uintptr_t hua = (uintptr_t)ptr;
>  
> -     for (i = 0; i < mem->nregions; i++) {
> +     for (i = 0; i < VHOST_MEMORY_MAX_NREGIONS; i++) {
>               r = &mem->regions[i];
> +             if (r->host_user_addr == 0)
> +                     continue;
>               if (hua >= r->host_user_addr &&
>                       hua < r->host_user_addr + r->size) {
>                       return get_blk_size(r->fd);

Reply via email to