perf tools build broken for RISCV 32 bit

Arnd Bergmann arnd at kernel.org
Mon Jan 18 14:58:50 EST 2021


On Mon, Jan 18, 2021 at 4:33 PM Emiliano Ingrassia
<ingrassia at epigenesys.com> wrote:
> On Mon, Jan 18, 2021 at 04:19:47PM +0100, Arnd Bergmann wrote:
> > On Mon, Jan 18, 2021 at 3:53 PM Emiliano Ingrassia <ingrassia at epigenesys.com> wrote:
> > >
> > > Hi,
> > >
> > > after some searching I found this patch from Yocto project:
> > >
> > > https://www.mail-archive.com/linux-yocto@lists.yoctoproject.org/msg01004.html.
> > >
> > > I don't know if it's ever been proposed as mainline patch.
> > >
> > > What do you think about it? Could it be the right solution?
> >
> > No. While this makes it work on rv32, it does not fix it in a
> > way that makes it work on other architectures with a time64
> > libc. If you fix it, please do it in a way that works on all architectures.
>
> 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?
> 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?

Actually, there might be a somewhat less ugly workaround, if we decide
to put a correct wrapper into the exported kernel headers, e.g. adding
something along these lines to include/uapi/linux/futex.h or a new header
from the kernel:

#ifndef __KERNEL__
#include <linux/futex.h>
#include <linux/time_types.h>
#include <asm/unistd.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>

#define __kernel_futex __kernel_futex
typedef union __attribute__ ((__transparent_union__)) {
       const struct timespec *timeout;
       unsigned int intval;
} __kernel_futex_union;

struct __kernel_old_timespec {
       __kernel_time_t tv_sec;                 /* seconds */
       long            tv_nsec;                /* nanoseconds */
};

static inline int __kernel_futex(int *uaddr, int op, int val,
                                 __kernel_futex_union val2,
                                 unsigned *uaddr2, int val3)
{
        int cmd = op & FUTEX_CMD_MASK;
        int ret = -ENOSYS;
#ifdef __NR_futex64
        {
                if (((cmd != FUTEX_WAIT) && (cmd != FUTEX_WAIT_BITSET)) ||
                    (sizeof(time_t) == sizeof(__u64))) {
                        ret = syscall(__NR_futex64, uaddr, op, val,
                                      val2.timeout, uaddr2, val3);
                }

                if (ret != -ENOSYS && ret != -EPERM)
                        return ret;
        }
#endif
#ifdef __NR_futex
        {
                if (((cmd != FUTEX_WAIT) && (cmd != FUTEX_WAIT_BITSET)) ||
                    sizeof(time_t) == sizeof(__kernel_long_t)) {
                        ret = syscall(__NR_futex, uaddr, op, val,
                                       val2.timeout, uaddr2, val3);
                } else {
                        struct __kernel_old_timespec oldtimeout = {
                                .tv_sec  = val2.timeout->tv_sec,
                                .tv_nsec = val2.timeout->tv_nsec,
                        };
                        ret = syscall(__NR_futex, uaddr, op, val,
                                      &oldtimeout, uaddr2, val3);
                }
        }
#endif
        return ret;
}
#endif /* __KERNEL__

With this, applications can be changed to define their own

#ifdef __kernel_futex
#define futex(uaddr, futex_op, val, val2, uaddr2, val3) \
      __kernel_futex(uaddr, futex_op, val, val2, uaddr2, val3)
#else
#define futex(uaddr, futex_op, val, val2, uaddr2, val3) \
       syscall(__NR_futex, uaddr, futex_op, val, val2, uaddr2, val3)
#endif

         Arnd



More information about the linux-riscv mailing list