On Wed, Jun 09, 2021 at 03:45:01AM +0900, Hyeonggon Yoo wrote:
static __always_inline void *kmalloc_node(size_t size, gfp_t flags,
int node)
{
if ( (
__builtin_constant_p(
!!(__builtin_constant_p(size) && size <= (1UL << ((11 + 12 - 1) <=
25 ? (11 + 12 - 1) : 25)))
)
? (!!(__builtin_constant_p(size) && size <= (1UL << ((11 + 12 - 1)
<= 25 ? (11 + 12 - 1) : 25))))
: ({ static struct ftrace_branch_data __attribute__((__aligned__(4)))
__attribute__((__section__("_ftrace_branch"))) __if_trace = { .func = __func__,
.file = "include/linux/slab.h", .line = 601, }; (!!(__builtin_constant_p(size)
&& size <= (1UL << ((11 + 12 - 1) <= 25 ? (11 + 12 - 1) : 25)))) ?
(__if_trace.miss_hit[1]++,1) : (__if_trace.miss_hit[0]++,0); })) )
{
unsigned int i = __kmalloc_index(size, true);
they are so ugly but the point is:
> > It seems that gcc evaluates
> >
> > __builtin_constant_p(
> > !!(builtin_constant_p(size)
> > && size <= KMALLOC_MAX_CACHE_SIZE)
> > )
> > as true.
> >
> > mm.. when the size passed to bpf_map_kmalloc_node is not constant,
> > (__builtin_constant_p(size) && size <= KMALLOC_MAX_CACHE_SIZE) is
false.
> > then __builtin_constant_p(!!false) is true. So it calls kmalloc_index.
> >
There were some logical errors on my words. I still think the compiler
evaluate it as true, but that is not reason why kmalloc_node calls
__kmalloc_index for non-constant size.
I wonder why kmalloc_node called __kmalloc_index(size, size_is_constant=true)
for non-constant size.
Thanks,
Hyeonggon
> > what change should be made?
> > just checking CONFIG_PROFILE_ALL_BRANCHES to kmalloc_index's if condition
> > doesn't make sense, because kmalloc_node is not working as expected.
> some evidence to add:
>
> there are 4 calls of bpf_map_kmalloc_node.
> if you comment out two calls of bpf_map_kmalloc_node with non-constant
> (in line 168, 508), it doesn't make an error. So I thought
> it was problem when non-constant size was passed.
>
> And if "kmalloc_index makes problem with non-constant size" is
> true, then it is caller's fault because it is not allowed (except
> in __kmalloc_index)
>
> kmalloc_node shouldn't call kmalloc_index if the size was not
> constant.