mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-18 17:33:43 +00:00
dm: file lock should be held till all mmap is done
Lock should be held till all the mmap operations are done. This is to avoid the mmap failure when multiple guests are created concurrently. For example consider the following case in which vm1 and vm2 are created by acrnd concurrently: - vm1 is created with 4G+2M memory. - 4G+2M memory is reserved in hugetlb now and vm1 continues to allocate memory for the lowmem without lock held. - 2G memory is allocated by vm1 for its lowmem, and 2G+2M memory is available in hugetlb. - At this time vm2 is created with 1G+2M memory. It finds that enough memory is reserved (2G+2M), so it does not try to reserve more memory. - vm2 allocates some memory for its lowmem/highmem/ovmf. - vm1 tries to allocate memory for its highmem/ovmf, the allocation will fail. vm1 creation failed in this case. Tracked-On: #3947 Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com> Reviewed-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
parent
52304348d6
commit
46b157008c
@ -740,15 +740,13 @@ int hugetlb_setup_memory(struct vmctx *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock_acrn_hugetlb();
|
||||||
|
|
||||||
/* it will check each level memory need */
|
/* it will check each level memory need */
|
||||||
has_gap = hugetlb_check_memgap();
|
has_gap = hugetlb_check_memgap();
|
||||||
if (has_gap) {
|
if (has_gap) {
|
||||||
lock_acrn_hugetlb();
|
if (!hugetlb_reserve_pages())
|
||||||
if (!hugetlb_reserve_pages()) {
|
goto err_lock;
|
||||||
unlock_acrn_hugetlb();
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
unlock_acrn_hugetlb();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* align up total size with huge page size for vma alignment */
|
/* align up total size with huge page size for vma alignment */
|
||||||
@ -775,7 +773,7 @@ int hugetlb_setup_memory(struct vmctx *ctx)
|
|||||||
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
if (ptr == MAP_FAILED) {
|
if (ptr == MAP_FAILED) {
|
||||||
perror("anony mmap fail");
|
perror("anony mmap fail");
|
||||||
goto err;
|
goto err_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* align up baseaddr according to hugepage level size */
|
/* align up baseaddr according to hugepage level size */
|
||||||
@ -791,23 +789,25 @@ int hugetlb_setup_memory(struct vmctx *ctx)
|
|||||||
/* mmap lowmem */
|
/* mmap lowmem */
|
||||||
if (mmap_hugetlbfs(ctx, 0, get_lowmem_param, adj_lowmem_param) < 0) {
|
if (mmap_hugetlbfs(ctx, 0, get_lowmem_param, adj_lowmem_param) < 0) {
|
||||||
perror("lowmem mmap failed");
|
perror("lowmem mmap failed");
|
||||||
goto err;
|
goto err_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mmap highmem */
|
/* mmap highmem */
|
||||||
if (mmap_hugetlbfs(ctx, ctx->highmem_gpa_base,
|
if (mmap_hugetlbfs(ctx, ctx->highmem_gpa_base,
|
||||||
get_highmem_param, adj_highmem_param) < 0) {
|
get_highmem_param, adj_highmem_param) < 0) {
|
||||||
perror("highmem mmap failed");
|
perror("highmem mmap failed");
|
||||||
goto err;
|
goto err_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mmap biosmem */
|
/* mmap biosmem */
|
||||||
if (mmap_hugetlbfs(ctx, 4 * GB - ctx->biosmem,
|
if (mmap_hugetlbfs(ctx, 4 * GB - ctx->biosmem,
|
||||||
get_biosmem_param, adj_biosmem_param) < 0) {
|
get_biosmem_param, adj_biosmem_param) < 0) {
|
||||||
perror("biosmem mmap failed");
|
perror("biosmem mmap failed");
|
||||||
goto err;
|
goto err_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock_acrn_hugetlb();
|
||||||
|
|
||||||
/* dump hugepage really setup */
|
/* dump hugepage really setup */
|
||||||
printf("\nreally setup hugepage with:\n");
|
printf("\nreally setup hugepage with:\n");
|
||||||
for (level = HUGETLB_LV1; level < hugetlb_lv_max; level++) {
|
for (level = HUGETLB_LV1; level < hugetlb_lv_max; level++) {
|
||||||
@ -846,6 +846,8 @@ int hugetlb_setup_memory(struct vmctx *ctx)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_lock:
|
||||||
|
unlock_acrn_hugetlb();
|
||||||
err:
|
err:
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
munmap(ptr, total_size);
|
munmap(ptr, total_size);
|
||||||
|
Loading…
Reference in New Issue
Block a user