From: zijun_hu <zijun_hu@zoho.com>
To: tj@kernel.org, akpm@linux-foundation.org
Cc: zijun_hu@htc.com, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, cl@linux.com
Subject: [RFC PATCH 1/1] mm/percpu.c: fix memory leakage issue when allocate a odd alignment area
Date: Tue, 11 Oct 2016 21:24:50 +0800 [thread overview]
Message-ID: <bc3126cd-226d-91c7-d323-48881095accf@zoho.com> (raw)
From: zijun_hu <zijun_hu@htc.com>
the LSB of a chunk->map element is used for free/in-use flag of a area
and the other bits for offset, the sufficient and necessary condition of
this usage is that both size and alignment of a area must be even numbers
however, pcpu_alloc() doesn't force its @align parameter a even number
explicitly, so a odd @align maybe causes a series of errors, see below
example for concrete descriptions.
lets assume area [16, 36) is free but its previous one is in-use, we want
to allocate a @size == 8 and @align == 7 area. the larger area [16, 36) is
split to three areas [16, 21), [21, 29), [29, 36) eventually. however, due
to the usage for a chunk->map element, the actual offset of the aim area
[21, 29) is 21 but is recorded in relevant element as 20; moreover the
residual tail free area [29, 36) is mistook as in-use and is lost silently
as explained above, inaccurate either offset or free/in-use state of
a area is recorded into relevant chunk->map element if request a odd
alignment area, and so causes memory leakage issue
fix it by forcing the @align of a area to allocate a even number
as do for @size.
BTW, macro ALIGN() within pcpu_fit_in_area() is replaced by roundup() too
due to back reason. in order to align a value @v up to @a boundary, macro
roundup(v, a) is more generic than ALIGN(x, a); the latter doesn't work
well when @a isn't a power of 2 value. for example, roundup(10, 6) == 12
but ALIGN(10, 6) == 10, the former result is desired obviously
Signed-off-by: zijun_hu <zijun_hu@htc.com>
---
include/linux/kernel.h | 1 +
mm/percpu.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 74fd6f05bc5b..ddf46638ef21 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -45,6 +45,7 @@
#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
+/* @a is a power of 2 value */
#define ALIGN(x, a) __ALIGN_KERNEL((x), (a))
#define __ALIGN_MASK(x, mask) __ALIGN_KERNEL_MASK((x), (mask))
#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
diff --git a/mm/percpu.c b/mm/percpu.c
index c2f0d9734d8c..26d1c73bd9e2 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -502,7 +502,7 @@ static int pcpu_fit_in_area(struct pcpu_chunk *chunk, int off, int this_size,
int cand_off = off;
while (true) {
- int head = ALIGN(cand_off, align) - off;
+ int head = roundup(cand_off, align) - off;
int page_start, page_end, rs, re;
if (this_size < head + size)
@@ -879,11 +879,13 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved,
/*
* We want the lowest bit of offset available for in-use/free
- * indicator, so force >= 16bit alignment and make size even.
+ * indicator, so force alignment >= 2 even and make size even.
*/
if (unlikely(align < 2))
align = 2;
+ if (WARN_ON_ONCE(!IS_ALIGNED(align, 2)))
+ align = ALIGN(align, 2);
size = ALIGN(size, 2);
if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE)) {
--
1.9.1
next reply other threads:[~2016-10-11 13:25 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-11 13:24 zijun_hu [this message]
2016-10-11 17:22 ` Michal Hocko
2016-10-12 0:28 ` zijun_hu
2016-10-12 6:53 ` Michal Hocko
2016-10-12 7:20 ` zijun_hu
2016-10-12 7:24 ` zijun_hu
2016-10-12 8:25 ` Michal Hocko
2016-10-12 8:44 ` zijun_hu
2016-10-12 9:54 ` Michal Hocko
2016-10-12 9:59 ` zijun_hu
2016-10-13 23:31 ` Tejun Heo
2016-10-14 0:23 ` zijun_hu
2016-10-14 0:28 ` Tejun Heo
2016-10-14 0:58 ` zijun_hu
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=bc3126cd-226d-91c7-d323-48881095accf@zoho.com \
--to=zijun_hu@zoho.com \
--cc=akpm@linux-foundation.org \
--cc=cl@linux.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=tj@kernel.org \
--cc=zijun_hu@htc.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®