[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#311053: libc6: sched_setaffinity broken on ppc



Package: libc6
Version: 2.3.2.ds1-22
Severity: important
Tags: patch

I tested sched_setaffinity on a recent glibc (with the sched-update
patch) and noticed some weird behaviour. A simple test that did a
setaffinity and that worked on the previous glibc version failed:

sched_setaffinity: Interrupted system call

setaffinity doesnt ever send back EINTR! The new setaffinity calls
getaffinity in order to work out how big the cpumask is. A strace of the
test case showed no such call:

getpid()                                = 20473
getpid()                                = 20473
sched_setaffinity(20473, 128,  { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }) = 0

The assembly shows the problem:

<sched_setaffinity@@GLIBC_2.3.4+280>:        bl 0xff1cc58 <getpid>
<sched_setaffinity@@GLIBC_2.3.4+284>:        mr      r5,r24
<sched_setaffinity@@GLIBC_2.3.4+288>:        mr      r4,r23
<sched_setaffinity@@GLIBC_2.3.4+292>:        sc

We should be loading r0 with the system call number, but we dont and
therefore do a random system call. The reason we sometimes get EINTR
and sometimes re-call getpid is due to the way ptrace works in the
kernel. Its not important to this bug so I'll leave it at that.

It turns out the problem is the way we have a function call inside an
INTERNAL_SYSCALL macro:

INTERNAL_SYSCALL (sched_getaffinity, err, 3, getpid (), psize, p)

The INTERNAL_SYSCALL macro in the debian glibc is buggy and we load r0
before we do the function call for getpid. The compiler then realises
that r0 is clobbered by the getpid function call and removes it
completely.

One fix is to get the sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
file out of CVS glibc. The other fix is to use a temp variable and avoid
calling getpid inside the INTERNAL_SYSCALL macro, recognising that when
we rebase to a newer glibc we can drop this patch. The patch for that is
below, and a build with it shows setaffinity working as expected:

getpid()                                = 20546
sched_getaffinity(20546, 128,  { f0003, 0, 0, 0 }) = 16
sched_setaffinity(20546, 128,  { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }) = 0

I hope we can get this fixed during the freeze, at the moment
setaffinity is completely broken on ppc.

--- glibc-2.3.2/sysdeps/unix/sysv/linux/sched_setaffinity.c~	2005-05-28 09:14:18.290043888 +1000
+++ glibc-2.3.2/sysdeps/unix/sysv/linux/sched_setaffinity.c	2005-05-28 15:25:16.265623000 +1000
@@ -37,11 +37,12 @@
     {
       INTERNAL_SYSCALL_DECL (err);
       int res;
+      pid_t mypid = getpid ();
 
       size_t psize = 128;
       void *p = alloca (psize);
 
-      while (res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, getpid (),
+      while (res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, mypid,
 				     psize, p),
 	     INTERNAL_SYSCALL_ERROR_P (res, err)
 	     && INTERNAL_SYSCALL_ERRNO (res, err) == EINVAL)

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: powerpc (ppc)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.12-rc3
Locale: LANG=en_AU, LC_CTYPE=en_AU (charmap=ISO-8859-1)

Versions of packages libc6 depends on:
ii  libdb1-compat                 2.1.3-7    The Berkeley database routines [gl

-- no debconf information



Reply to: