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