From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.6 required=3.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HK_RANDOM_FROM,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 499E5C4743F for ; Tue, 8 Jun 2021 18:45:10 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id C01FE613EF for ; Tue, 8 Jun 2021 18:45:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C01FE613EF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 50B946B006C; Tue, 8 Jun 2021 14:45:09 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 4BC356B006E; Tue, 8 Jun 2021 14:45:09 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 2E8366B0070; Tue, 8 Jun 2021 14:45:09 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id F05B16B006C for ; Tue, 8 Jun 2021 14:45:08 -0400 (EDT) Received: from smtpin40.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id 7E1158249980 for ; Tue, 8 Jun 2021 18:45:08 +0000 (UTC) X-FDA: 78231433896.40.8BC3167 Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) by imf30.hostedemail.com (Postfix) with ESMTP id 46341E000259 for ; Tue, 8 Jun 2021 18:45:06 +0000 (UTC) Received: by mail-pg1-f170.google.com with SMTP id j12so17250650pgh.7 for ; Tue, 08 Jun 2021 11:45:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=8ar7hX0x4bElwp++h79L59g6QXIYp/aqo6EszkivfR0=; b=MWUKUzDuBSE3EUdyb+jqIC2OhEq/+9ov3CZE/K+a2UrSU1RdCPsW7kh7iGekqA1BGd yoi0STWVyuhJ4veKpWaKn1ANFdjkB6W8s6WWNrkqGYddt2yZnGnecC4qoAWBZkYldBXY 04Mvb2xhV2Hxg37HCvLU85wtptdrr0GZJ731/HTP9h2QoyS2eYA3z93CLvAXKxD/RoGc BKEvoodHydwZoezqKKcPDvMOWa/NLMcj4lr6xRGfvza/3g4dqp2b0+DgN9ejSZHP5gC8 1d01Pp6Me1bZjt6IgHprYfDYtjFoDLr+9OaOEYzJq+1PC15rnF/jQqgUF4zF2MuXwhkR N1jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=8ar7hX0x4bElwp++h79L59g6QXIYp/aqo6EszkivfR0=; b=a7CKZdh3kryj2tKV1sO8mn3NtnoxH7d6srn1Q5aeneY4XQrw9IMnHoPq0IeHcVz+BF z5dmpVH9Oib1jy4xPW0+i/1U8YZyulM6Dh9K4FZYwjtDrN2QqVqxoWwG4LbmU3APqIo3 o+3dChOl/wv5KH0fAiGURws4VRJf0/N8mJIhtL+Sctwu7ixJnCPKniIsPKo9o4ZtHy3L QTRQHCoPnni+IKSOaiNkblPgxVvdkZJHV1qWguj117X9dX/irtmfl4yWKmQb4+/uqk9O ThFQzS29H9M/gLnhvOAe8qg/DKv6W3nErYRu0U2ZVHpivCdfNgfhNtrx0R5wl2hZ0bba NekQ== X-Gm-Message-State: AOAM533+3cnrPRWBCB1sdmWuSNuf6I+WVoBHgiK7pNbRqmirZDE3pQ05 RyysmpgFgW5LrDJC7okgiPA= X-Google-Smtp-Source: ABdhPJygF6/L9UWarmyqtqn081A7EqCGY+rMGJbm4d8MIz/E+ON1P7dYlP1g8dkw0RNa6RzfRddzeQ== X-Received: by 2002:a62:1a49:0:b029:2eb:6de0:9890 with SMTP id a70-20020a621a490000b02902eb6de09890mr1266772pfa.39.1623177906935; Tue, 08 Jun 2021 11:45:06 -0700 (PDT) Received: from hyeyoo ([183.99.11.150]) by smtp.gmail.com with ESMTPSA id q23sm12216079pgj.61.2021.06.08.11.45.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Jun 2021 11:45:06 -0700 (PDT) Date: Wed, 9 Jun 2021 03:45:01 +0900 From: Hyeonggon Yoo <42.hyeyoo@gmail.com> To: Vlastimil Babka Cc: kernel test robot , kbuild-all@lists.01.org, Linux Memory Management List , Andrew Morton Subject: Re: [linux-next:master 7012/7430] include/linux/compiler_types.h:328:38: error: call to '__compiletime_assert_183' declared with attribute error: unexpected size in kmalloc_index() Message-ID: <20210608184501.GA5505@hyeyoo> References: <202106051442.G1VJubTz-lkp@intel.com> <20210606110839.GA13828@hyeyoo> <20210607122550.GA752464@hyeyoo> <06af75da-ffe9-7070-1da8-bcb2cb7881d2@suse.cz> <20210607154957.GB927582@hyeyoo> <6e1d48f2-409c-0a71-4d04-a907fe4183b8@suse.cz> <20210608170528.GA28015@hyeyoo> <2d2d792e-e189-99a4-36cb-f1473a4df9ad@suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <2d2d792e-e189-99a4-36cb-f1473a4df9ad@suse.cz> Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=gmail.com header.s=20161025 header.b=MWUKUzDu; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf30.hostedemail.com: domain of 42hyeyoo@gmail.com designates 209.85.215.170 as permitted sender) smtp.mailfrom=42hyeyoo@gmail.com X-Stat-Signature: x6iwf377gt647a8eqwq1dspxjwfqkowx X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 46341E000259 X-HE-Tag: 1623177906-918996 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On Tue, Jun 08, 2021 at 07:27:52PM +0200, Vlastimil Babka wrote: > On 6/8/21 7:05 PM, Hyeonggon Yoo wrote: > > On Tue, Jun 08, 2021 at 09:57:18AM +0200, Vlastimil Babka wrote: > >> On 6/7/21 5:49 PM, Hyeonggon Yoo wrote: > >> > On Mon, Jun 07, 2021 at 05:27:27PM +0200, Vlastimil Babka wrote: > >> >> On 6/7/21 2:25 PM, Hyeonggon Yoo wrote: > >> >> > On Mon, Jun 07, 2021 at 01:40:02PM +0200, Vlastimil Babka wrote= : > >> >> >> On 6/6/21 1:08 PM, Hyeonggon Yoo wrote: > >> >> >> > On Sat, Jun 05, 2021 at 02:10:46PM +0800, kernel test robot = wrote: > >> >> >>=20 > >> >> >> But what exactly is the gcc problem here? > >> >> >> Did you have to reproduce it with specific gcc version and/or = architecture? > >> >> >>=20 > >> >> >=20 > >> >> > Before replying, I should say that I'm not an expert on gcc. > >> >> > I just tried some ways to fix the error, and it seemed to me th= at > >> >> > gcc is doing something wrong. > >> >>=20 > >> >> I'm involving my gcc colleagues, will report results... > >>=20 > >> Well, it seems the bot's .config included CONFIG_PROFILE_ALL_BRANCHE= S as the > >> main factor to trigger the problem. And (according to my colleagues) > >=20 > > Wow, AWESOME! How did your colleague find it? that was a big hint for= me. > > when CONFIG_PROFILE_ALL_BRANCHES is not set, it doesn't make an error= . >=20 > Well, we started with me doing "make kernel/bpf/local_storage.i" to cre= ate a > preprocessed C source that can be copied out and debugged outside of th= e whole > kernel build context. I send that to my colleague and he reduced the te= stcase > using cvise: >=20 > https://gcc.gnu.org/wiki/A_guide_to_testcase_reduction >=20 > While the reduction wasn't successful in preserving enough of the testc= ase, from > the result it was clear that there was lots of ftrace_branch_data stuff= and so > it was easy to find this is due to > CONFIG_PROFILE_ALL_BRANCHES. >=20 First time to hear about testcase reduction and cvise! Thank you for letting me know it :) I'm going to read it. but I ask some questions before that (see below) > > mm.. when the size passed to bpf_map_kmalloc_node is not constant, > > (__builtin_constant_p(size) && size <=3D KMALLOC_MAX_CACHE_SIZE) is f= alse. > > then __builtin_constant_p(!!false) is true. So it calls kmalloc_index= . > >=20 > > what change should be made? > > just checking CONFIG_PROFILE_ALL_BRANCHES to kmalloc_index's if condi= tion > > doesn't make sense, because kmalloc_node is not working as expected. > > If I understood my colleagues right, the problem is that, while kmalloc= _index() > seems to contains a number of *independent* "if (size <=3D X) condition= s in a > sequence, the machinery of CONFIG_PROFILE_ALL_BRANCHES turns it to a de= eply > nested if-then-else { if-then-else { if-then-else {...}}} thing (in fac= t using > the ternary operators, not if-then-else). > At some point of the deep nesting gcc > "forgets" that __builtin_constant_p() is true and starts behaving as if= it wasn't. >=20 > Without CONFIG_PROFILE_ALL_BRANCHES it's able to keep track of it fine. > I think you are talking about some if statements in kmalloc_index. How do you know gcc "forgets" __builtin_constant_p() is true? can it be debugged using cvise? (not offending, just because I don't know about cvise yet). Also, as I understand right, kmalloc_index doesn't have information about the value of __builtin_constant_p(size). the caller of kmalloc_index (kmalloc_node here) has that information. If I understand right, what CONFIG_PROFILE_ALL_BRANCHES does is below. replacing if(cond) { body } -> if ( __builtin_constant_p(cond) ? then (cond) else (cond, record something) ) { body } I think it does not make deep nested statements. the below is some part of preprocessor output. CONFIG_PROFILE_ALL_BRANCHES makes some ugly ternary operators, but there is no deep-nested if-then-else statements. if ( (__builtin_constant_p(!!(size <=3D 8)) ? (!!(size <=3D 8)) : ({ stat= ic struct ftrace_branch_data __attribute__((__aligned__(4))) __attribute_= _((__section__("_ftrace_branch"))) __if_trace =3D { .func =3D __func__, .= file =3D "include/linux/slab.h", .line =3D 392, }; (!!(size <=3D 8)) ? (_= _if_trace.miss_hit[1]++,1) : (__if_trace.miss_hit[0]++,0); })) ) return 3= ; if ( (__builtin_constant_p(!!(size <=3D 16)) ? (!!(size <=3D 16)) : ({ st= atic struct ftrace_branch_data __attribute__((__aligned__(4))) __attribut= e__((__section__("_ftrace_branch"))) __if_trace =3D { .func =3D __func__,= .file =3D "include/linux/slab.h", .line =3D 393, }; (!!(size <=3D 16)) ?= (__if_trace.miss_hit[1]++,1) : (__if_trace.miss_hit[0]++,0); })) ) retur= n 4; if ( (__builtin_constant_p(!!(size <=3D 32)) ? (!!(size <=3D 32)) : ({ st= atic struct ftrace_branch_data __attribute__((__aligned__(4))) __attribut= e__((__section__("_ftrace_branch"))) __if_trace =3D { .func =3D __func__,= .file =3D "include/linux/slab.h", .line =3D 394, }; (!!(size <=3D 32)) ?= (__if_trace.miss_hit[1]++,1) : (__if_trace.miss_hit[0]++,0); })) ) retur= n 5; .... and some if statements ... And I think, the problem is on kmalloc_node, not on kmalloc_index. the original code of kmalloc_node is below: static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int n= ode) { #ifndef CONFIG_SLOB if (__builtin_constant_p(size) && size <=3D KMALLOC_MAX_CACHE_SIZE) { unsigned int i =3D kmalloc_index(size); and which is changed to below: (by CONFIG_PROFILE_ALL_BRANCHES) static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int n= ode) { if ( ( __builtin_constant_p( !!(__builtin_constant_p(size) && size <=3D (1UL << ((11 + 12 - 1) <=3D = 25 ? (11 + 12 - 1) : 25))) ) ? (!!(__builtin_constant_p(size) && size <=3D (1UL << ((11 + 12 - 1) <= =3D 25 ? (11 + 12 - 1) : 25))))=20 : ({ static struct ftrace_branch_data __attribute__((__aligned__(4))) = __attribute__((__section__("_ftrace_branch"))) __if_trace =3D { .func =3D= __func__, .file =3D "include/linux/slab.h", .line =3D 601, }; (!!(__buil= tin_constant_p(size) && size <=3D (1UL << ((11 + 12 - 1) <=3D 25 ? (11 + = 12 - 1) : 25)))) ? (__if_trace.miss_hit[1]++,1) : (__if_trace.miss_hit[0]= ++,0); })) ) { unsigned int i =3D __kmalloc_index(size, true); they are so ugly but the point is: > > It seems that gcc evaluates > >=20 > > __builtin_constant_p( > > !!(builtin_constant_p(size) > > && size <=3D KMALLOC_MAX_CACHE_SIZE) > > ) > > as true. > >=20 > > mm.. when the size passed to bpf_map_kmalloc_node is not constant, > > (__builtin_constant_p(size) && size <=3D KMALLOC_MAX_CACHE_SIZE) is f= alse. > > then __builtin_constant_p(!!false) is true. So it calls kmalloc_index= . > >=20 > > what change should be made? > > just checking CONFIG_PROFILE_ALL_BRANCHES to kmalloc_index's if condi= tion > > 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. > > void *kmalloc_node(size_t size, gfp_t flags, int node){ > >=20 > > if ( (__builtin_constant_p( > > !!(__builtin_constant_p(size) > > && size <=3D (1UL << ((11 + 12 - 1) <=3D 25 ? (11 + 12 - 1) : = 25)))) > > ? (!!(__builtin_constant_p(size) && size <=3D (1UL << ((1= 1 + 12 - 1) <=3D 25 ? (11 + 12 - 1) : 25)))) > > if ( (__builtin_constant_p(!!((0 || 110000 >=3D 110000) && size_is_co= nstant)) ? (!!((0 || 110000 >=3D 110000) && size_is_constant)) : ({ stati= c struct ftrace_branch_data __attribute__((__aligned__(4))) __attribute__= ((__section__("_ftrace_branch"))) __if_trace =3D { .func =3D __func__, .f= ile =3D "include/linux/slab.h", .line =3D 416, }; (!!((0 || 110000 >=3D 1= 10000) && size_is_constant)) ? (__if_trace.miss_hit[1]++,1) : (__if_trace= .miss_hit[0]++,0); })) ) > > do { > >=20 > >=20 > > extern void __compiletime_assert_131(void) ; > > // here - compiletime_assert_131 does NOTHING >=20 > It doesn't seem to do nothing? see below >=20 > > if ( (__builtin_constant_p(!!(!(!(1)))) > > ? (!!(!(!(1)))) > > : ({ static struct ftrace_branch_data __attribute__((__= aligned__(4))) __attribute__((__section__("_ftrace_branch"))) __if_trace = =3D { .func =3D __func__, .file =3D "include/linux/slab.h", .line =3D 417= , }; (!!(!(!(1)))) ? (__if_trace.miss_hit[1]++,1) : (__if_trace.miss_hit[= 0]++,0); })) ) __compiletime_assert_131(); } while (0); >=20 > The thing above seems to be exactly the "if (!(condition)) > prefix ## suffix(); } while (0)" as the definition you posted below. >=20 > Anyway, you can verify that clang works by commenting out the highest s= ize > checks and passing a constant size that makes it reach the BUILD_BUG_O= N_MSG() ? >=20 I verified as below. clang didn't make an error, gcc worked as expected. then I can explain why there is no error with clang: it just did nothing with BUILD_BUG_ON. hyeyoo@hyeyoo:~/=EB=B0=94=ED=83=95=ED=99=94=EB=A9=B4/linux-next$ git diff diff --git a/include/linux/slab.h b/include/linux/slab.h index 8d8dd8571261..f2f9a6a7e663 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -379,6 +379,9 @@ static __always_inline enum kmalloc_cache_type kmallo= c_type(gfp_t flags) static __always_inline unsigned int __kmalloc_index(size_t size, bool size_is_constant= ) { + + BUILD_BUG_ON(1); + if (!size) return 0; hyeyoo@hyeyoo:~/=EB=B0=94=ED=83=95=ED=99=94=EB=A9=B4/linux-next$ make mm/= kfence/kfence_test.o CC=3Dclang-11 CALL scripts/checksyscalls.sh ... some headers omitted ... CC mm/kfence/kfence_test.o In file included from : In function =E2=80=98__kmalloc_index=E2=80=99, inlined from =E2=80=98kmalloc_cache_alignment=E2=80=99 at mm/kfence/k= fence_test.c:200:50: ././include/linux/compiler_types.h:328:38: error: call to =E2=80=98__comp= iletime_assert_131=E2=80=99 declared with attribute error: BUILD_BUG_ON f= ailed: 1 328 | _compiletime_assert(condition, msg, __compiletime_assert_, __COU= NTER__) | ^ ././include/linux/compiler_types.h:309:4: note: in definition of macro =E2= =80=98__compiletime_assert=E2=80=99 309 | prefix ## suffix(); \ | ^~~~~~ ././include/linux/compiler_types.h:328:2: note: in expansion of macro =E2= =80=98_compiletime_assert=E2=80=99 328 | _compiletime_assert(condition, msg, __compiletime_assert_, __COU= NTER__) | ^~~~~~~~~~~~~~~~~~~ ./include/linux/build_bug.h:39:37: note: in expansion of macro =E2=80=98c= ompiletime_assert=E2=80=99 39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), m= sg) | ^~~~~~~~~~~~~~~~~~ ./include/linux/build_bug.h:50:2: note: in expansion of macro =E2=80=98BU= ILD_BUG_ON_MSG=E2=80=99 50 | BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition) | ^~~~~~~~~~~~~~~~ ./include/linux/slab.h:383:2: note: in expansion of macro =E2=80=98BUILD_= BUG_ON=E2=80=99 383 | BUILD_BUG_ON(1); | ^~~~~~~~~~~~ In function =E2=80=98__kmalloc_index=E2=80=99, inlined from =E2=80=98test_alloc=E2=80=99 at mm/kfence/kfence_test.c:= 271:47: ././include/linux/compiler_types.h:328:38: error: call to =E2=80=98__comp= iletime_assert_131=E2=80=99 declared with attribute error: BUILD_BUG_ON f= ailed: 1 328 | _compiletime_assert(condition, msg, __compiletime_assert_, __COU= NTER__) | ^ ././include/linux/compiler_types.h:309:4: note: in definition of macro =E2= =80=98__compiletime_assert=E2=80=99 309 | prefix ## suffix(); \ | ^~~~~~ ././include/linux/compiler_types.h:328:2: note: in expansion of macro =E2= =80=98_compiletime_assert=E2=80=99 328 | _compiletime_assert(condition, msg, __compiletime_assert_, __COU= NTER__) | ^~~~~~~~~~~~~~~~~~~ ./include/linux/build_bug.h:39:37: note: in expansion of macro =E2=80=98c= ompiletime_assert=E2=80=99 39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), m= sg) | ^~~~~~~~~~~~~~~~~~ ./include/linux/build_bug.h:50:2: note: in expansion of macro =E2=80=98BU= ILD_BUG_ON_MSG=E2=80=99 50 | BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition) | ^~~~~~~~~~~~~~~~ ./include/linux/slab.h:383:2: note: in expansion of macro =E2=80=98BUILD_= BUG_ON=E2=80=99 383 | BUILD_BUG_ON(1); | ^~~~~~~~~~~~ make[2]: *** [scripts/Makefile.build:272: mm/kfence/kfence_test.o] =EC=98= =A4=EB=A5=98 1 make[1]: *** [scripts/Makefile.build:533: mm/kfence] =EC=98=A4=EB=A5=98 2 make: *** [Makefile:1948: mm] =EC=98=A4=EB=A5=98 2