From: "bhe@redhat.com" <bhe@redhat.com>
To: Uladzislau Rezki <urezki@gmail.com>
Cc: Jaeseon Sim <jason.sim@samsung.com>,
"akpm@linux-foundation.org" <akpm@linux-foundation.org>,
"hch@infradead.org" <hch@infradead.org>,
"lstoakes@gmail.com" <lstoakes@gmail.com>,
"linux-mm@kvack.org" <linux-mm@kvack.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Jaewon Kim <jaewon31.kim@samsung.com>
Subject: Re: [PATCH] mm/vmalloc: Remove WARN_ON_ONCE related to adjust_va_to_fit_type
Date: Wed, 27 Sep 2023 21:33:04 +0800 [thread overview]
Message-ID: <ZRQvEFUepsUH/BUi@MiWiFi-R3L-srv> (raw)
In-Reply-To: <ZRQW5Wb2cT1FnrvH@pc638.lan>
On 09/27/23 at 01:49pm, Uladzislau Rezki wrote:
> > > Yes, but GFP_NOWAIT-alloc-error can easily occur for low-memory device.
> > >
> > Agree. You are really in a low memory condition. We end up here only if
> > pre-loading also has not succeeded, i.e. GFP_KERNEL also fails.
> >
> > But i agree with you, we should "improve the warning" because we drain
> > and repeat.
> >
> > > How about changing fix as below?:
> > >
> > > <snip>
> > > --- a/mm/vmalloc.c
> > > +++ b/mm/vmalloc.c
> > > @@ -1468,6 +1468,7 @@ adjust_va_to_fit_type(struct rb_root *root, struct list_head *head,
> > > */
> > > va->va_start = nva_start_addr + size;
> > > } else {
> > > + WARN_ON_ONCE(1);
> > > return -1;
> > > }
> > >
> > > @@ -1522,7 +1523,7 @@ __alloc_vmap_area(struct rb_root *root, struct list_head *head,
> > >
> > > /* Update the free vmap_area. */
> > > ret = adjust_va_to_fit_type(root, head, va, nva_start_addr, size);
> > > - if (WARN_ON_ONCE(ret))
> > > + if (ret)
> > > return vend;
> > >
> > > #if DEBUG_AUGMENT_LOWEST_MATCH_CHECK
> > > @@ -4143,7 +4144,7 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
> > > ret = adjust_va_to_fit_type(&free_vmap_area_root,
> > > &free_vmap_area_list,
> > > va, start, size);
> > > - if (WARN_ON_ONCE(unlikely(ret)))
> > > + if (unlikely(ret))
> > > /* It is a BUG(), but trigger recovery instead. */
> > > goto recovery;
> > >
> > > <snip>
> > > It will WARN_ONCE_ONCE() only if classify_va_fit_type() is "(type == NOTHING_FIT)".
> > >
> > This is good but i think it should be improved further. We need to
> > understand from the warning when no memory and when there is no a
> > vmap space, so:
> >
> > - if NOTHING_FIT, we should WARN() for sure;
> > - Second place in the pcpu_get_vm_area(), we do not use NE_FIT. Only in
> > the begging after boot, but potentially we can trigger -ENOMEM and we
> > should warn in this case. Otherwise you just hide it;
> > - And last one if after repeating we still do not manage to allocate.
> >
>
> We should understand a reason of failing. I think error handling should
> be improved. Something like:
This looks good to me, while the parameter 'error' looks a little ugly.
How about this?
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index ef8599d394fd..32805c82373b 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1454,7 +1454,7 @@ adjust_va_to_fit_type(struct rb_root *root, struct list_head *head,
*/
lva = kmem_cache_alloc(vmap_area_cachep, GFP_NOWAIT);
if (!lva)
- return -1;
+ return -ENOMEM;
}
/*
@@ -1468,7 +1468,7 @@ adjust_va_to_fit_type(struct rb_root *root, struct list_head *head,
*/
va->va_start = nva_start_addr + size;
} else {
- return -1;
+ return -EINVAL;
}
if (type != FL_FIT_TYPE) {
@@ -1509,7 +1509,7 @@ __alloc_vmap_area(struct rb_root *root, struct list_head *head,
va = find_vmap_lowest_match(root, size, align, vstart, adjust_search_size);
if (unlikely(!va))
- return vend;
+ return -ENOENT;
if (va->va_start > vstart)
nva_start_addr = ALIGN(va->va_start, align);
@@ -1518,12 +1518,12 @@ __alloc_vmap_area(struct rb_root *root, struct list_head *head,
/* Check the "vend" restriction. */
if (nva_start_addr + size > vend)
- return vend;
+ return -ERANGE;
/* Update the free vmap_area. */
ret = adjust_va_to_fit_type(root, head, va, nva_start_addr, size);
- if (WARN_ON_ONCE(ret))
- return vend;
+ if (ret)
+ return ret;
#if DEBUG_AUGMENT_LOWEST_MATCH_CHECK
find_vmap_lowest_match_check(root, head, size, align);
@@ -1616,13 +1616,13 @@ static struct vmap_area *alloc_vmap_area(unsigned long size,
size, align, vstart, vend);
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(addr));
/*
- * If an allocation fails, the "vend" address is
+ * If an allocation fails, the error value is
* returned. Therefore trigger the overflow path.
*/
- if (unlikely(addr == vend))
+ if (unlikely(IS_ERR(addr)))
goto overflow;
va->va_start = addr;
@@ -1662,8 +1662,9 @@ static struct vmap_area *alloc_vmap_area(unsigned long size,
}
if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit())
- pr_warn("vmap allocation for size %lu failed: use vmalloc=<size> to increase size\n",
- size);
+ pr_warn("vmap allocation for size %lu failed: "
+ "use vmalloc=<size> to increase size, errno: (%d)\n",
+ size, addr);
kmem_cache_free(vmap_area_cachep, va);
return ERR_PTR(-EBUSY);
@@ -4143,8 +4144,8 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
ret = adjust_va_to_fit_type(&free_vmap_area_root,
&free_vmap_area_list,
va, start, size);
- if (WARN_ON_ONCE(unlikely(ret)))
- /* It is a BUG(), but trigger recovery instead. */
+ if ((unlikely(ret)))
+ WARN_ONCE(1, "%s error: errno (%d)\n", __func__, ret);
goto recovery;
/* Allocated area. */
>
> <snip>
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index ef8599d394fd..03a36921a3fc 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -1454,7 +1454,7 @@ adjust_va_to_fit_type(struct rb_root *root, struct list_head *head,
> */
> lva = kmem_cache_alloc(vmap_area_cachep, GFP_NOWAIT);
> if (!lva)
> - return -1;
> + return -ENOMEM;
> }
>
> /*
> @@ -1468,7 +1468,7 @@ adjust_va_to_fit_type(struct rb_root *root, struct list_head *head,
> */
> va->va_start = nva_start_addr + size;
> } else {
> - return -1;
> + return -EINVAL;
> }
>
> if (type != FL_FIT_TYPE) {
> @@ -1488,7 +1488,8 @@ adjust_va_to_fit_type(struct rb_root *root, struct list_head *head,
> static __always_inline unsigned long
> __alloc_vmap_area(struct rb_root *root, struct list_head *head,
> unsigned long size, unsigned long align,
> - unsigned long vstart, unsigned long vend)
> + unsigned long vstart, unsigned long vend,
> + int *error)
> {
> bool adjust_search_size = true;
> unsigned long nva_start_addr;
> @@ -1508,8 +1509,10 @@ __alloc_vmap_area(struct rb_root *root, struct list_head *head,
> adjust_search_size = false;
>
> va = find_vmap_lowest_match(root, size, align, vstart, adjust_search_size);
> - if (unlikely(!va))
> + if (unlikely(!va)) {
> + *error = -ENOENT;
> return vend;
> + }
>
> if (va->va_start > vstart)
> nva_start_addr = ALIGN(va->va_start, align);
> @@ -1517,13 +1520,17 @@ __alloc_vmap_area(struct rb_root *root, struct list_head *head,
> nva_start_addr = ALIGN(vstart, align);
>
> /* Check the "vend" restriction. */
> - if (nva_start_addr + size > vend)
> + if (nva_start_addr + size > vend) {
> + *error = -ERANGE;
> return vend;
> + }
>
> /* Update the free vmap_area. */
> ret = adjust_va_to_fit_type(root, head, va, nva_start_addr, size);
> - if (WARN_ON_ONCE(ret))
> + if (ret) {
> + *error = ret;
> return vend;
> + }
>
> #if DEBUG_AUGMENT_LOWEST_MATCH_CHECK
> find_vmap_lowest_match_check(root, head, size, align);
> @@ -1589,7 +1596,7 @@ static struct vmap_area *alloc_vmap_area(unsigned long size,
> unsigned long freed;
> unsigned long addr;
> int purged = 0;
> - int ret;
> + int ret, error;
>
> if (unlikely(!size || offset_in_page(size) || !is_power_of_2(align)))
> return ERR_PTR(-EINVAL);
> @@ -1613,7 +1620,7 @@ static struct vmap_area *alloc_vmap_area(unsigned long size,
> retry:
> preload_this_cpu_lock(&free_vmap_area_lock, gfp_mask, node);
> addr = __alloc_vmap_area(&free_vmap_area_root, &free_vmap_area_list,
> - size, align, vstart, vend);
> + size, align, vstart, vend, &error);
> spin_unlock(&free_vmap_area_lock);
>
> trace_alloc_vmap_area(addr, size, align, vstart, vend, addr == vend);
> @@ -1662,8 +1669,9 @@ static struct vmap_area *alloc_vmap_area(unsigned long size,
> }
>
> if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit())
> - pr_warn("vmap allocation for size %lu failed: use vmalloc=<size> to increase size\n",
> - size);
> + pr_warn("vmap allocation for size %lu failed: "
> + "use vmalloc=<size> to increase size, errno: (%d)\n",
> + size, error);
>
> kmem_cache_free(vmap_area_cachep, va);
> return ERR_PTR(-EBUSY);
> @@ -4143,9 +4151,10 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
> ret = adjust_va_to_fit_type(&free_vmap_area_root,
> &free_vmap_area_list,
> va, start, size);
> - if (WARN_ON_ONCE(unlikely(ret)))
> - /* It is a BUG(), but trigger recovery instead. */
> + if (unlikely(ret)) {
> + WARN_ONCE(1, "%s error: errno (%d)\n", __func__, ret);
> goto recovery;
> + }
>
> /* Allocated area. */
> va = vas[area];
> <snip>
>
> Any thoughts?
next prev parent reply other threads:[~2023-09-27 13:33 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20230922061715epcms1p7cd5a37f4bba0abf4bc159b844bd8ee65@epcms1p1>
2023-09-22 6:27 ` [PATCH] mm/vmalloc: Remove WARN_ON_ONCE related to adjust_va_to_fit_type Jaeseon Sim
2023-09-22 9:34 ` bhe
2023-09-22 9:42 ` bhe
2023-09-25 10:51 ` Jaeseon Sim
2023-09-25 13:40 ` Uladzislau Rezki
2023-09-26 5:21 ` Jaeseon Sim
2023-09-26 6:05 ` Uladzislau Rezki
2023-09-26 12:05 ` Jaeseon Sim
2023-09-26 12:35 ` Uladzislau Rezki
2023-09-27 11:49 ` Uladzislau Rezki
2023-09-27 13:33 ` bhe [this message]
2023-09-27 15:25 ` Uladzislau Rezki
2023-09-22 13:41 ` Uladzislau Rezki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZRQvEFUepsUH/BUi@MiWiFi-R3L-srv \
--to=bhe@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=hch@infradead.org \
--cc=jaewon31.kim@samsung.com \
--cc=jason.sim@samsung.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lstoakes@gmail.com \
--cc=urezki@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.