Fix hugepage leak on VM termination
When VM is terminated, the hugepages mapped should be unmapped so that the system does not run out of hugepage resources. Therefore, mapped pages are unmapped when VPP notices a disconnect. Change-Id: I7398fb20028036738ab87db0b0e79609e95d69a4 Signed-off-by: Shesha Sreenivasamurthy <shesha@cisco.com>
This commit is contained in:
Shesha Sreenivasamurthy
committed by
Damjan Marion
parent
c0959c9c47
commit
81f7092d34
@ -170,6 +170,7 @@ typedef struct {
|
||||
#endif
|
||||
u64 region_addr[VHOST_MEMORY_MAX_NREGIONS];
|
||||
u32 region_fd[VHOST_MEMORY_MAX_NREGIONS];
|
||||
u64 region_offset[VHOST_MEMORY_MAX_NREGIONS];
|
||||
} dpdk_vu_intf_t;
|
||||
|
||||
typedef void (*dpdk_flowcontrol_callback_t) (vlib_main_t *vm,
|
||||
|
@ -527,8 +527,12 @@ dpdk_vhost_user_set_mem_table(u32 hw_if_index, vhost_user_memory_t * vum, int fd
|
||||
mapped_address += vum->regions[i].mmap_offset;
|
||||
vui->region_addr[i] = mapped_address;
|
||||
vui->region_fd[i] = fd[i];
|
||||
vui->region_offset[i] = vum->regions[i].mmap_offset;
|
||||
mem->regions[i].address_offset = mapped_address - mem->regions[i].guest_phys_address;
|
||||
|
||||
DBG_SOCK("map memory region %d addr 0x%lx off 0x%lx len 0x%lx",
|
||||
i, vui->region_addr[i], vui->region_offset[i], mapped_size);
|
||||
|
||||
if (vum->regions[i].guest_phys_addr == 0) {
|
||||
mem->base_address = vum->regions[i].userspace_addr;
|
||||
mem->mapped_address = mem->regions[i].address_offset;
|
||||
@ -913,6 +917,36 @@ dpdk_vhost_user_vui_register(vlib_main_t * vm, dpdk_device_t *xd)
|
||||
xd->vlib_sw_if_index);
|
||||
}
|
||||
|
||||
static void dpdk_unmap_all_mem_regions(dpdk_device_t * xd)
|
||||
{
|
||||
int i, r;
|
||||
dpdk_vu_intf_t *vui = xd->vu_intf;
|
||||
struct virtio_memory * mem = xd->vu_vhost_dev.mem;
|
||||
|
||||
for (i=0; i<mem->nregions; i++) {
|
||||
if (vui->region_addr[i] != -1) {
|
||||
|
||||
long page_sz = get_huge_page_size(vui->region_fd[i]);
|
||||
|
||||
ssize_t map_sz = (mem->regions[i].memory_size +
|
||||
vui->region_offset[i] + page_sz) & ~(page_sz - 1);
|
||||
|
||||
r = munmap((void *)(vui->region_addr[i] - vui->region_offset[i]), map_sz);
|
||||
|
||||
DBG_SOCK("unmap memory region %d addr 0x%lx off 0x%lx len 0x%lx page_sz 0x%x",
|
||||
i, vui->region_addr[i], vui->region_offset[i], map_sz, page_sz);
|
||||
|
||||
vui->region_addr[i]= -1;
|
||||
|
||||
if (r == -1) {
|
||||
clib_warning("failed to unmap memory region (errno %d)", errno);
|
||||
}
|
||||
close(vui->region_fd[i]);
|
||||
}
|
||||
}
|
||||
mem->nregions = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
dpdk_vhost_user_if_disconnect(dpdk_device_t * xd)
|
||||
{
|
||||
@ -934,6 +968,7 @@ dpdk_vhost_user_if_disconnect(dpdk_device_t * xd)
|
||||
vui->unix_fd = -1;
|
||||
vui->is_up = 0;
|
||||
|
||||
dpdk_unmap_all_mem_regions(xd);
|
||||
DBG_SOCK("interface ifindex %d disconnected", xd->vlib_sw_if_index);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user