mm/vmalloc.c: return explicit error value in alloc_vmap_area()

In codes of alloc_vmap_area(), it returns the upper bound 'vend' to
indicate if the allocation is successful or failed.  That is not very
clear.

Here change to return explicit error values and check them to judge if
allocation is successful.

Link: https://lkml.kernel.org/r/20250418223653.243436-6-bhe@redhat.com
Signed-off-by: Baoquan He <bhe@redhat.com>
Reviewed-by: Shivank Garg <shivankg@amd.com>
Reviewed-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
Cc: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Baoquan He
2025-04-19 06:36:53 +08:00
committed by Andrew Morton
parent 8ab8442d44
commit b25f97d0f8

View File

@@ -1716,7 +1716,7 @@ va_clip(struct rb_root *root, struct list_head *head,
*/ */
lva = kmem_cache_alloc(vmap_area_cachep, GFP_NOWAIT); lva = kmem_cache_alloc(vmap_area_cachep, GFP_NOWAIT);
if (!lva) if (!lva)
return -1; return -ENOMEM;
} }
/* /*
@@ -1730,7 +1730,7 @@ va_clip(struct rb_root *root, struct list_head *head,
*/ */
va->va_start = nva_start_addr + size; va->va_start = nva_start_addr + size;
} else { } else {
return -1; return -EINVAL;
} }
if (type != FL_FIT_TYPE) { if (type != FL_FIT_TYPE) {
@@ -1759,19 +1759,19 @@ va_alloc(struct vmap_area *va,
/* Check the "vend" restriction. */ /* Check the "vend" restriction. */
if (nva_start_addr + size > vend) if (nva_start_addr + size > vend)
return vend; return -ERANGE;
/* Update the free vmap_area. */ /* Update the free vmap_area. */
ret = va_clip(root, head, va, nva_start_addr, size); ret = va_clip(root, head, va, nva_start_addr, size);
if (WARN_ON_ONCE(ret)) if (WARN_ON_ONCE(ret))
return vend; return ret;
return nva_start_addr; return nva_start_addr;
} }
/* /*
* Returns a start address of the newly allocated area, if success. * Returns a start address of the newly allocated area, if success.
* Otherwise a vend is returned that indicates failure. * Otherwise an error value is returned that indicates failure.
*/ */
static __always_inline unsigned long static __always_inline unsigned long
__alloc_vmap_area(struct rb_root *root, struct list_head *head, __alloc_vmap_area(struct rb_root *root, struct list_head *head,
@@ -1796,14 +1796,13 @@ __alloc_vmap_area(struct rb_root *root, struct list_head *head,
va = find_vmap_lowest_match(root, size, align, vstart, adjust_search_size); va = find_vmap_lowest_match(root, size, align, vstart, adjust_search_size);
if (unlikely(!va)) if (unlikely(!va))
return vend; return -ENOENT;
nva_start_addr = va_alloc(va, root, head, size, align, vstart, vend); nva_start_addr = va_alloc(va, root, head, size, align, vstart, vend);
if (nva_start_addr == vend)
return vend;
#if DEBUG_AUGMENT_LOWEST_MATCH_CHECK #if DEBUG_AUGMENT_LOWEST_MATCH_CHECK
find_vmap_lowest_match_check(root, head, size, align); if (!IS_ERR_VALUE(nva_start_addr))
find_vmap_lowest_match_check(root, head, size, align);
#endif #endif
return nva_start_addr; return nva_start_addr;
@@ -1933,7 +1932,7 @@ node_alloc(unsigned long size, unsigned long align,
struct vmap_area *va; struct vmap_area *va;
*vn_id = 0; *vn_id = 0;
*addr = vend; *addr = -EINVAL;
/* /*
* Fallback to a global heap if not vmalloc or there * Fallback to a global heap if not vmalloc or there
@@ -2013,20 +2012,20 @@ static struct vmap_area *alloc_vmap_area(unsigned long size,
} }
retry: retry:
if (addr == vend) { if (IS_ERR_VALUE(addr)) {
preload_this_cpu_lock(&free_vmap_area_lock, gfp_mask, node); preload_this_cpu_lock(&free_vmap_area_lock, gfp_mask, node);
addr = __alloc_vmap_area(&free_vmap_area_root, &free_vmap_area_list, addr = __alloc_vmap_area(&free_vmap_area_root, &free_vmap_area_list,
size, align, vstart, vend); size, align, vstart, vend);
spin_unlock(&free_vmap_area_lock); spin_unlock(&free_vmap_area_lock);
} }
trace_alloc_vmap_area(addr, size, align, vstart, vend, addr == vend); trace_alloc_vmap_area(addr, size, align, vstart, vend, IS_ERR_VALUE(addr));
/* /*
* If an allocation fails, the "vend" address is * If an allocation fails, the error value is
* returned. Therefore trigger the overflow path. * returned. Therefore trigger the overflow path.
*/ */
if (unlikely(addr == vend)) if (IS_ERR_VALUE(addr))
goto overflow; goto overflow;
va->va_start = addr; va->va_start = addr;