Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run-time failure on ppc64le: invalid input constraint 'YZ<>' in asm #5172

Open
vt-alt opened this issue Dec 17, 2024 · 5 comments
Open

Run-time failure on ppc64le: invalid input constraint 'YZ<>' in asm #5172

vt-alt opened this issue Dec 17, 2024 · 5 comments

Comments

@vt-alt
Copy link
Contributor

vt-alt commented Dec 17, 2024

jfyi, test run of cpudist from 0.31.0 started to fail on Linux v6.12.5 on ppc64le with:

[00:02:05] ++ /usr/src/tmp/bcc-buildroot/usr/share/bcc/tools/cpudist 1 1
[00:02:08] In file included from /virtual/main.c:2:
[00:02:08] In file included from include/uapi/linux/ptrace.h:145:
[00:02:08] In file included from arch/powerpc/include/asm/ptrace.h:141:
[00:02:08] In file included from arch/powerpc/include/asm/paca.h:25:
[00:02:08] arch/powerpc/include/asm/atomic.h:183:53: error: invalid input constraint 'YZ<>' in asm
[00:02:08]   183 |                 __asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : DS_FORM_CONSTRAINT (v->counter));
[00:02:08]       |                                                                   ^
[00:02:08] arch/powerpc/include/asm/asm-compat.h:43:28: note: expanded from macro 'DS_FORM_CONSTRAINT'
[00:02:08]    43 | #define DS_FORM_CONSTRAINT "YZ<>"
[00:02:08]       |                            ^
[00:02:08] In file included from /virtual/main.c:2:
[00:02:08] In file included from include/uapi/linux/ptrace.h:145:
[00:02:08] In file included from arch/powerpc/include/asm/ptrace.h:141:
[00:02:08] In file included from arch/powerpc/include/asm/paca.h:25:
[00:02:08] arch/powerpc/include/asm/atomic.h:194:44: error: invalid output constraint '=YZ<>' in asm
[00:02:08]   194 |                 __asm__ __volatile__("std%U0%X0 %1,%0" : "=" DS_FORM_CONSTRAINT (v->counter) : "r"(i));
[00:02:08]       |                                                          ^
[00:02:08] 2 errors generated.
[00:02:08] Traceback (most recent call last):
[00:02:08]   File "/usr/src/tmp/bcc-buildroot/usr/share/bcc/tools/cpudist", line 210, in <module>
[00:02:08]     b = BPF(text=bpf_text, cflags=["-DMAX_PID=%d" % max_pid])
[00:02:08]         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[00:02:08]   File "/usr/src/tmp/bcc-buildroot/usr/lib64/python3/site-packages/bcc/__init__.py", line 480, in __init__
[00:02:08]     raise Exception("Failed to compile BPF module %s" % (src_file or "<text>"))
[00:02:08] Exception: Failed to compile BPF module <text>

This test was working OK on Linux v6.10.6 (I'm not implying that kernel version difference is the cause of failure though).

This architecture is low priority for us, thus I'm just disabling build of bcc package on ppc64le for ALT Linux, but this failure might interesting for you, so I'm reporting it here.

@yonghong-song
Copy link
Collaborator

Thanks for reporting.
I briefly checked the source. The reason is due to the following static inline function in atomic.h

static __inline__ s64 arch_atomic64_read(const atomic64_t *v)
{
        s64 t;

        /* -mprefixed can generate offsets beyond range, fall back hack */
        if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
                __asm__ __volatile__("ld %0,0(%1)" : "=r"(t) : "b"(&v->counter));
        else
                __asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : DS_FORM_CONSTRAINT (v->counter));

        return t;
}

static __inline__ void arch_atomic64_set(atomic64_t *v, s64 i)
{
        /* -mprefixed can generate offsets beyond range, fall back hack */
        if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
                __asm__ __volatile__("std %1,0(%2)" : "=m"(v->counter) : "r"(i), "b"(&v->counter));
        else
                __asm__ __volatile__("std%U0%X0 %1,%0" : "=" DS_FORM_CONSTRAINT (v->counter) : "r"(i));
}

They are supposed to be removed during arch specific compilation (powerpc) since nobody uses those functions but apparently they are still there for later bpf backend code generation.

I do not have environments to debug this and hopefully somebody else could help take a look if possible.

@dubeyabhishek
Copy link

In arch/powerpc/include/asm/asm-compat.h, we have ::
#ifdef CONFIG_CC_IS_CLANG
#define DS_FORM_CONSTRAINT "Z<>"
#else
#define DS_FORM_CONSTRAINT "YZ<>"
#endif

Can we compile the kernel headers in bcc setting CONFIG_CC_IS_CLANG, we get correct DS_FORM?

@yonghong-song
Copy link
Collaborator

You can add -DCONFIG_CC_IS_CLANG in cflags of BPF constructor like below.

b = BPF(text=bpf_text, cflags=['-DMAX_CPUS=%s' % str(num_cpus)])

@hramrach
Copy link

These are kernel-internal headers which are configured for use with the compiler that was used to build the kernel, and for that compiler YZ<> is the correct constraint.

However, bcc pulls that kernel-internal header into a different project, built with a different compiler. That's why the build fails. This is outside of what the kernel build system supports.

intel-lab-lkp pushed a commit to intel-lab-lkp/linux that referenced this issue Feb 18, 2025
Due to include chain (below), powerpc's asm-compat.h is part of UAPI,
thus it should use the __clang__ macro to directly detect whether Clang
is used rather then relying on the kernel config setting. The later is
unreliable because the userspace tools that uses UAPI may be compile
with a different compiler than the one used for the kernel, leading to
incorrect constrain selection (see link for an example of such).

  include/uapi/linux/ptrace.h
  arch/powerpc/include/asm/ptrace.h
  arch/powerpc/include/asm/paca.h
  arch/powerpc/include/asm/atomic.h
  arch/powerpc/include/asm/asm-compat.h

Link: iovisor/bcc#5172
Signed-off-by: Shung-Hsi Yu <[email protected]>
@shunghsiyu
Copy link
Contributor

Would it make sense to define CONFIG_CC_IS_CLANG as part of KBuildHelper::get_flags()? There's quite a few Clang-specific workaround wrapped with such macro, and defining it once instead of per effect scripts seems like the easier way out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants