perf tools build broken for RISCV 32 bit

Emiliano Ingrassia ingrassia at epigenesys.com
Mon Jan 18 11:34:10 EST 2021


Hi Arnd,

On Mon, Jan 18, 2021 at 04:44:36PM +0100, Arnd Bergmann wrote:
> On Mon, Jan 18, 2021 at 4:33 PM Emiliano Ingrassia
> <ingrassia at epigenesys.com> wrote:
>
> > Ok, I totally agree with you on this point.
> >
> > So, it is right to conclude that the problem is not in perf
> > implementation but in the libc implementation?
>
> No, libc does not provide a futex abstraction, and the SYS_* macros
> just refer to the low-level interfaces that operate on kernel types rather
> than libc types. An application that uses them must pass the
> correct types.
>
> > That is, for example, glibc should define SYS_futex as SYS_futex_time64
> > in case of riscv 32 bit because of its support to 64 bit time_t?
>
> As I explained, SYS_futex would refer to the time32 syscall, which
> does not exist on rv32, redefining it to a different syscall would lead to
> data corruption as well.
>

I tried to apply the patch you proposed in your first reply:

> #ifdef __NR_futex
> #define do_futex (sizeof(time_t) == sizeof(__kernel_long_t)) ? \
>          __NR_futex : __NR_futex_time64
> #else
> #define do_futex __NR_futex
> #done

in a simple user space app which calls futex (I changed do_futex with
SYS_futex):

#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/futex.h>
#include <sys/time.h>

#ifdef __NR_futex
#define SYS_futex (sizeof(time_t) == sizeof(__kernel_long_t)) ? \
				           __NR_futex : __NR_futex_time64
#else
#define SYS_futex __NR_futex
#endif

static int
futex(uint32_t *uaddr, int futex_op, uint32_t val,
      const struct timespec *timeout, uint32_t *uaddr2, uint32_t val3)
{
	return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
}

int main(void)
{
	return futex(NULL, FUTEX_WAKE, 0, NULL, NULL, 0);
}

But what I get is:

error: ‘__NR_futex’ undeclared (first use in this function)
   12 | #define SYS_futex __NR_futex


The problem is that if __NR_futex is not defined it will not work anyway.


So the only viable solution to correctly compile and use perf on riscv
32 bit is the implementation of time32 syscall for that architecture?

And this is true for all 32 bit applications that want to call futex
syscall with a non NULL timer parameter, right?


> If you call futex_time64, you have to pass a __kernel_timespec structure,
> while the old futex call must take a __kernel_old_timespec structure.
> Depending on the architecture, only one of the two syscalls might be
> available, and if you pass a timespec defined by libc, you have to
> know which of the two syscalls that corresponds to, or convert
> the arguments when calling it.
>
>       Arnd

Thank you, best regards.

Emiliano



More information about the linux-riscv mailing list