bcachefs bugs should go to the bcachefs mailing list; I assume this is
just a case where we need min_t instead of min, if so I'll fix it
shortly
On Tue, Feb 13, 2024 at 02:56:40PM -0700, Nathan Chancellor wrote:
> Hi all,
>
> I am not really sure where to go with this, so I figured I would loop
> some people in and see if we can figure out what is going on here.
>
> After commit 67a8e7de7ef0 ("bcachefs: Clamp replicas_required to
> replicas") in linux-next, I see a massive error occur when building for
> ARCH=arm64 with both CONFIG_BCACHEFS_FS and CONFIG_LTO enabled, which is
> important because arm64 defines its own __READ_ONCE() with LTO enabled.
> The error appears to be related to the minmax.h changes that went into
> 6.7; I think it is specifically around commit d03eba99f5bf ("minmax:
> allow min()/max()/clamp() if the arguments have the same signedness.").
>
> As far as I can tell, replicas_want and the metadata_replicas_required
> member in struct bch_opts should have the same signedness, unless the
> __READ_ONCE() macro is messing something up, which is kind of hard to
> tell at this point...
>
> I'll keep poking at this tomorrow unless someone else beats me to it.
>
> Cheers,
> Nathan
>
> $ echo 'CONFIG_BCACHEFS_FS=y
> CONFIG_LTO_NONE=n
> CONFIG_LTO_CLANG_THIN=y' >kernel/configs/repro.config
>
> $ make -skj"$(nproc)" ARCH=arm64 LLVM=1 clean defconfig repro.config
> fs/bcachefs/journal_io.o
> fs/bcachefs/journal_io.c:1509:27: error: static assertion failed due to
> requirement '__builtin_choose_expr((sizeof(int) == sizeof (*(8 ? ((void
> *)((long)((((unsigned int)(-1)) < (unsigned int)1)) * 0L)) : (int *)8))),
> (((unsigned int)(-1)) < (unsigned int)1), 0) ==
> __builtin_choose_expr((sizeof(int) == sizeof (*(8 ? ((void
> *)((long)((((int)(-1)) < (int)1)) * 0L)) : (int *)8))), (((int)(-1)) <
> (int)1), 0) || __builtin_choose_expr((sizeof(int) == sizeof (*(8 ? ((void
> *)((long)((((unsigned int)(-1)) < (unsigned int)1)) * 0L)) : (int *)8))),
> (((unsigned int)(-1)) < (unsigned int)1), 0) ==
> __builtin_choose_expr((sizeof(int) == sizeof (*(8 ? ((void
> *)((long)((((int)(-1)) < (int)1)) * 0L)) : (int *)8))), (((int)(-1)) <
> (int)1), 0) || (__builtin_choose_expr((sizeof(int) == sizeof (*(8 ? ((void
> *)((long)(replicas_want) * 0L)) : (int *)8))) &&
> __builtin_choose_expr((sizeof(int) == sizeof (*(8 ? ((void
> *)((long)((((unsigned int)(-1)) < (unsigned int)1)) * 0L)) : (int *)8))),
> (((unsigned int)(-1)) < (unsigned int)1), 0), replicas_want, -1) >= 0) ||
> (__builtin_choose_expr((sizeof(int) == sizeof (*(8 ? ((void *)((long)(({
> do {
> extern void __compiletime_assert_578(void);
> if (!((sizeof (c->opts.metadata_replicas_required) == sizeof(char) ||
> sizeof (c->opts.metadata_replicas_required) == sizeof(short) || sizeof
> (c->opts.metadata_replicas_required) == sizeof(int) || sizeof
> (c->opts.metadata_replicas_required) == sizeof(long)) || sizeof
> (c->opts.metadata_replicas_required) == sizeof(long long)))
> __compiletime_assert_578();
> } while (0);
> ({
> unsigned char *__x = &(c->opts.metadata_replicas_required);
> int atomic = 1;
> union {
> unsigned char __val;
> char __c[1];
> } __u;
> switch (sizeof (c->opts.metadata_replicas_required)) {
> case 1:
> asm volatile (".if 1 == 1\n661:\n\tldarb\t%w0,
> %1\n662:\n.pushsection .altinstructions,\"a\"\n .word 661b - .\n .word 663f -
> .\n .hword 34\n .byte 662b-661b\n .byte 664f-663f\n.popsection\n.subsection
> 1\n663:\n\t.arch_extension rcpc\nldaprb\t%w0, %1\n664:\n\t.org\t. -
> (664b-663b) + (662b-661b)\n\t.org\t. - (662b-661b) +
> (664b-663b)\n\t.previous\n.endif\n" : "=r" (*(unsigned char *)__u.__c) : "Q"
> (*__x) : "memory");
> break;
> case 2:
> asm volatile (".if 1 == 1\n661:\n\tldarh\t%w0,
> %1\n662:\n.pushsection .altinstructions,\"a\"\n .word 661b - .\n .word 663f -
> .\n .hword 34\n .byte 662b-661b\n .byte 664f-663f\n.popsection\n.subsection
> 1\n663:\n\t.arch_extension rcpc\nldaprh\t%w0, %1\n664:\n\t.org\t. -
> (664b-663b) + (662b-661b)\n\t.org\t. - (662b-661b) +
> (664b-663b)\n\t.previous\n.endif\n" : "=r" (*(unsigned short *)__u.__c) : "Q"
> (*__x) : "memory");
> break;
> case 4:
> asm volatile (".if 1 == 1\n661:\n\tldar\t%w0,
> %1\n662:\n.pushsection .altinstructions,\"a\"\n .word 661b - .\n .word 663f -
> .\n .hword 34\n .byte 662b-661b\n .byte 664f-663f\n.popsection\n.subsection
> 1\n663:\n\t.arch_extension rcpc\nldapr\t%w0, %1\n664:\n\t.org\t. -
> (664b-663b) + (662b-661b)\n\t.org\t. - (662b-661b) +
> (664b-663b)\n\t.previous\n.endif\n" : "=r" (*(unsigned int *)__u.__c) : "Q"
> (*__x) : "memory");
> break;
> case 8:
> asm volatile (".if 1 == 1\n661:\n\tldar\t%0,
> %1\n662:\n.pushsection .altinstructions,\"a\"\n .word 661b - .\n .word 663f -
> .\n .hword 34\n .byte 662b-661b\n .byte 664f-663f\n.popsection\n.subsection
> 1\n663:\n\t.arch_extension rcpc\nldapr\t%0, %1\n664:\n\t.org\t. - (664b-663b)
> + (662b-661b)\n\t.org\t. - (662b-661b) + (664b-663b)\n\t.previous\n.endif\n"
> : "=r" (*(unsigned long long *)__u.__c) : "Q" (*__x) : "memory");
> break;
> default:
> atomic = 0;
> }
> atomic ? (unsigned char)__u.__val : (*(unsigned char *volatile)__x);
> });
> })) * 0L)) : (int *)8))) && __builtin_choose_expr((sizeof(int) == sizeof (*(8
> ? ((void *)((long)((((int)(-1)) < (int)1)) * 0L)) : (int *)8))), (((int)(-1))
> < (int)1), 0), ({
> do {
> extern void __compiletime_assert_578(void);
> if (!((sizeof (c->opts.metadata_replicas_required) == sizeof(char) ||
> sizeof (c->opts.metadata_replicas_required) == sizeof(short) || sizeof
> (c->opts.metadata_replicas_required) == sizeof(int) || sizeof
> (c->opts.metadata_replicas_required) == sizeof(long)) || sizeof
> (c->opts.metadata_replicas_required) == sizeof(long long)))
> __compiletime_assert_578();
> } while (0);
> ({
> unsigned char *__x = &(c->opts.metadata_replicas_required);
> int atomic = 1;
> union {
> unsigned char __val;
> char __c[1];
> } __u;
> switch (sizeof (c->opts.metadata_replicas_required)) {
> case 1:
> asm volatile (".if 1 == 1\n661:\n\tldarb\t%w0,
> %1\n662:\n.pushsection .altinstructions,\"a\"\n .word 661b - .\n .word 663f -
> .\n .hword 34\n .byte 662b-661b\n .byte 664f-663f\n.popsection\n.subsection
> 1\n663:\n\t.arch_extension rcpc\nldaprb\t%w0, %1\n664:\n\t.org\t. -
> (664b-663b) + (662b-661b)\n\t.org\t. - (662b-661b) +
> (664b-663b)\n\t.previous\n.endif\n" : "=r" (*(unsigned char *)__u.__c) : "Q"
> (*__x) : "memory");
> break;
> case 2:
> asm volatile (".if 1 == 1\n661:\n\tldarh\t%w0,
> %1\n662:\n.pushsection .altinstructions,\"a\"\n .word 661b - .\n .word 663f -
> .\n .hword 34\n .byte 662b-661b\n .byte 664f-663f\n.popsection\n.subsection
> 1\n663:\n\t.arch_extension rcpc\nldaprh\t%w0, %1\n664:\n\t.org\t. -
> (664b-663b) + (662b-661b)\n\t.org\t. - (662b-661b) +
> (664b-663b)\n\t.previous\n.endif\n" : "=r" (*(unsigned short *)__u.__c) : "Q"
> (*__x) : "memory");
> break;
> case 4:
> asm volatile (".if 1 == 1\n661:\n\tldar\t%w0,
> %1\n662:\n.pushsection .altinstructions,\"a\"\n .word 661b - .\n .word 663f -
> .\n .hword 34\n .byte 662b-661b\n .byte 664f-663f\n.popsection\n.subsection
> 1\n663:\n\t.arch_extension rcpc\nldapr\t%w0, %1\n664:\n\t.org\t. -
> (664b-663b) + (662b-661b)\n\t.org\t. - (662b-661b) +
> (664b-663b)\n\t.previous\n.endif\n" : "=r" (*(unsigned int *)__u.__c) : "Q"
> (*__x) : "memory");
> break;
> case 8:
> asm volatile (".if 1 == 1\n661:\n\tldar\t%0,
> %1\n662:\n.pushsection .altinstructions,\"a\"\n .word 661b - .\n .word 663f -
> .\n .hword 34\n .byte 662b-661b\n .byte 664f-663f\n.popsection\n.subsection
> 1\n663:\n\t.arch_extension rcpc\nldapr\t%0, %1\n664:\n\t.org\t. - (664b-663b)
> + (662b-661b)\n\t.org\t. - (662b-661b) + (664b-663b)\n\t.previous\n.endif\n"
> : "=r" (*(unsigned long long *)__u.__c) : "Q" (*__x) : "memory");
> break;
> default:
> atomic = 0;
> }
> atomic ? (unsigned char)__u.__val : (*(unsigned char *volatile)__x);
> });
> }), -1) >= 0)': min(replicas_want, ({ do { __attribute__((__noreturn__))
> extern void __compiletime_assert_578(void)
> __attribute__((__error__("Unsupported access size for
> {READ,WRITE}_ONCE()."))); if (!((sizeof(c->opts.metadata_replicas_required)
> == sizeof(char) || sizeof(c->opts.metadata_replicas_required) ==
> sizeof(short) || sizeof(c->opts.metadata_replicas_required) == sizeof(int) ||
> sizeof(c->opts.metadata_replicas_required) == sizeof(long)) ||
> sizeof(c->opts.metadata_replicas_required) == sizeof(long long)))
> __compiletime_assert_578(); } while (0); ({
> typeof(&(c->opts.metadata_replicas_required)) __x =
> &(c->opts.metadata_replicas_required); int atomic = 1; union { typeof(
> _Generic((*__x), char: (char)0, unsigned char: (unsigned char)0, signed char:
> (signed char)0, unsigned short: (unsigned short)0, signed short: (signed
> short)0, unsigned int: (unsigned int)0, signed int: (signed int)0, unsigned
> long: (unsigned long)0, signed long: (signed long)0, unsigned long long:
> (unsigned long long)0, signed long long: (signed long long)0, default:
> (*__x))) __val; char __c[1]; } __u; switch
> (sizeof(c->opts.metadata_replicas_required)) { case 1: asm volatile(".if
> ""1"" == 1\n" "661:\n\t" "ldar" "b" "\t" "%w0, %1" "\n" "662:\n"
> ".pushsection .altinstructions,\"a\"\n" " .word 661b - .\n" " .word 663f -
> .\n" " .hword " "34" "\n" " .byte 662b-661b\n" " .byte 664f-663f\n"
> ".popsection\n" ".subsection 1\n" "663:\n\t" ".arch_extension rcpc\n" "ldapr"
> "b" "\t" "%w0, %1" "\n" "664:\n\t" ".org . - (664b-663b) +
> (662b-661b)\n\t" ".org . - (662b-661b) + (664b-663b)\n\t"
> ".previous\n" ".endif\n" : "=r" (*(__u8 *)__u.__c) : "Q" (*__x) : "memory");
> break; case 2: asm volatile(".if ""1"" == 1\n" "661:\n\t" "ldar" "h" "\t"
> "%w0, %1" "\n" "662:\n" ".pushsection .altinstructions,\"a\"\n" " .word 661b
> - .\n" " .word 663f - .\n" " .hword " "34" "\n" " .byte 662b-661b\n" " .byte
> 664f-663f\n" ".popsection\n" ".subsection 1\n" "663:\n\t" ".arch_extension
> rcpc\n" "ldapr" "h" "\t" "%w0, %1" "\n" "664:\n\t" ".org . - (664b-663b) +
> (662b-661b)\n\t" ".org . - (662b-661b) + (664b-663b)\n\t"
> ".previous\n" ".endif\n" : "=r" (*(__u16 *)__u.__c) : "Q" (*__x) : "memory");
> break; case 4: asm volatile(".if ""1"" == 1\n" "661:\n\t" "ldar" "" "\t"
> "%w0, %1" "\n" "662:\n" ".pushsection .altinstructions,\"a\"\n" " .word 661b
> - .\n" " .word 663f - .\n" " .hword " "34" "\n" " .byte 662b-661b\n" " .byte
> 664f-663f\n" ".popsection\n" ".subsection 1\n" "663:\n\t" ".arch_extension
> rcpc\n" "ldapr" "" "\t" "%w0, %1" "\n" "664:\n\t" ".org . - (664b-663b) +
> (662b-661b)\n\t" ".org . - (662b-661b) + (664b-663b)\n\t"
> ".previous\n" ".endif\n" : "=r" (*(__u32 *)__u.__c) : "Q" (*__x) : "memory");
> break; case 8: asm volatile(".if ""1"" == 1\n" "661:\n\t" "ldar" "" "\t" "%0,
> %1" "\n" "662:\n" ".pushsection .altinstructions,\"a\"\n" " .word 661b - .\n"
> " .word 663f - .\n" " .hword " "34" "\n" " .byte 662b-661b\n" " .byte
> 664f-663f\n" ".popsection\n" ".subsection 1\n" "663:\n\t" ".arch_extension
> rcpc\n" "ldapr" "" "\t" "%0, %1" "\n" "664:\n\t" ".org . - (664b-663b) +
> (662b-661b)\n\t" ".org . - (662b-661b) + (664b-663b)\n\t"
> ".previous\n" ".endif\n" : "=r" (*(__u64 *)__u.__c) : "Q" (*__x) : "memory");
> break; default: atomic = 0; } atomic ? (typeof(*__x))__u.__val : (*(volatile
> typeof(__x))__x);}); })) signedness error, fix types or consider umin()
> before min_t()
> 1509 | unsigned replicas_need = min(replicas_want,
> | ^~~~~~~~~~~~~~~~~~
> 1510 |
> READ_ONCE(c->opts.metadata_replicas_required));
> |
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/minmax.h:85:19: note: expanded from macro 'min'
> 85 | #define min(x, y) __careful_cmp(min, x, y)
> | ^~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/minmax.h:58:3: note: expanded from macro '__careful_cmp'
> 58 | __cmp_once(op, x, y, __UNIQUE_ID(__x),
> __UNIQUE_ID(__y)))
> |
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/minmax.h:51:16: note: expanded from macro '__cmp_once'
> 51 | static_assert(__types_ok(x, y), \
> | ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 52 | #op "(" #x ", " #y ") signedness error, fix types or
> consider u" #op "() before " #op "_t()"); \
> |
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to
> see all)
> include/linux/minmax.h:31:2: note: expanded from macro '__is_signed'
> 31 |
> __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \
> | ^
> include/linux/build_bug.h:77:50: note: expanded from macro 'static_assert'
> 77 | #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__,
> #expr)
> |
> ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:78:56: note: expanded from macro '__static_assert'
> 78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
> | ^~~~
> 1 error generated.