Thread (29 messages) 29 messages, 5 authors, 2021-05-19

Re: [PATCH v3] mm, slub: change run-time assertion in kmalloc_index() to compile-time

From: Marco Elver <elver@google.com>
Date: 2021-05-13 08:46:17
Also in: lkml

On Thu, 13 May 2021 at 08:28, Hyeonggon Yoo [off-list ref] wrote:
On Wed, May 12, 2021 at 08:40:24PM -0700, Andrew Morton wrote:
quoted
On Thu, 13 May 2021 12:12:20 +0900 Hyeonggon Yoo [off-list ref] wrote:
quoted
On Wed, May 12, 2021 at 07:52:27PM -0700, Andrew Morton wrote:
quoted
This explodes in mysterious ways.  The patch as I have it is appended,
for reference.

gcc-10.3.0 allmodconfig.

This patch suppresses the error:
Ah, yes, of course, your patch changes kmalloc_index() to require that
it always is called with a constant `size'.  kfence_test doesn't do
that.

kfence is being a bit naughty here - the other kmalloc_index() callers
only comple up the call after verifying that `size' is a compile-time
constant.

Would something like this work?
 include/linux/slab.h    |   12 ++++++++----
 mm/kfence/kfence_test.c |    4 ++--
 2 files changed, 10 insertions(+), 6 deletions(-)
--- a/include/linux/slab.h~b
+++ a/include/linux/slab.h
@@ -374,7 +374,8 @@ static __always_inline enum kmalloc_cach
  * Note: there's no need to optimize kmalloc_index because it's evaluated
  * in compile-time.
  */
-static __always_inline unsigned int kmalloc_index(size_t size)
+static __always_inline unsigned int kmalloc_index(size_t size,
+                                               bool size_is_constant)
 {
      if (!size)
              return 0;
@@ -410,7 +411,10 @@ static __always_inline unsigned int kmal
      if (size <=  16 * 1024 * 1024) return 24;
      if (size <=  32 * 1024 * 1024) return 25;

-     BUILD_BUG_ON_MSG(1, "unexpected size in kmalloc_index()");
+     if (size_is_constant)
+             BUILD_BUG_ON_MSG(1, "unexpected size in kmalloc_index()");
+     else
+             BUG();

kfence is randomly generating size. because kfence is using non-constant
size, we should do run-time assertion or compile-time assertion depending
on situation.

I think we can use __builtin_constant_p here. we don't need to modify
kmalloc_index's prototype.

so what about this?
if you think it makes sense, I'll send patch v4.

I used KMALLOC_MAX_CACHE_SIZE to assure it's safe size.
it's safer than putting BUILD_BUG_ON_MSG(1, ...) to below if statements
because KMALLOC_MAX_CACHE_SIZE can be less than 32MB.
I'm actually inclined to say that Andrew's patch with
'size_is_constant' is the better option, because we want to be
explicit about where it's using constant size and where it isn't. I
think in tests like kfence_test, it should be permitted to use
non-constant size, it's a test after all and performance is no
concern. For non-test code, however, we want to ensure size is
constant, and therefore having the distinguishing argument makes
sense. That way non-test code will not compile if our intent does not
match reality.

Thanks,
-- Marco
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help