ARM architecture lacks support for pselect() and ppoll()
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Release Notes for Ubuntu |
Fix Released
|
Undecided
|
Unassigned | ||
linux (Ubuntu) |
Invalid
|
Wishlist
|
Amit Kucheria | ||
Jaunty |
Won't Fix
|
Wishlist
|
Amit Kucheria | ||
Karmic |
Invalid
|
Undecided
|
Unassigned | ||
linux-fsl-imx51 (Ubuntu) |
Fix Released
|
Wishlist
|
Bryan Wu | ||
Jaunty |
Won't Fix
|
Wishlist
|
Amit Kucheria | ||
Karmic |
Won't Fix
|
Wishlist
|
Unassigned | ||
linux-mvl-dove (Ubuntu) |
Won't Fix
|
Wishlist
|
Eric Miao | ||
Jaunty |
Invalid
|
Undecided
|
Unassigned | ||
Karmic |
Won't Fix
|
Wishlist
|
Unassigned |
Bug Description
The ARM architecture in the upstream kernel lacks support for the pselect() and ppoll() system calls.
pselect is defined in POSIX.1g, and in POSIX.1-2001, while ppoll is Linux specific but matches the intent of pselect.
The difference between select() and pselect() & poll() and ppoll() is that the latter system calls accept an additional sigmask parameter. Effectively they are equivalent to:
sigprocmask (SIG_SETMASK, &mask, &oldmask);
select (...);
sigprocmask (SIG_SETMASK, &oldmask, NULL);
*EXCEPT* that this is performed atomically!
When these syscalls do not exist, glibc emulates them with the above code - which defeats the entire object of their existance.
Consider when the mask is empty, and the normal process mark blocks SIGCHLD. With pselect()/ppoll() you are guaranteed to only have the SIGCHLD delivered while in the syscall, and thus guaranteed that any child death will terminate the syscall with -EINTR.
With the non-atomic code, the SIGCHLD signal may be delivered between the sigprocmask() and select() system calls, in which case the select will NOT terminate. Software will randomly hang in select and not reap its children.
In some cases, the software may be self-imposing a limit on the number of its children. If the children die at the wrong point, the daemon may hang indefinitely - since it will not process the death.
One such process that uses ppoll() and limits its children is udev!
Related branches
Changed in linux: | |
importance: | Undecided → High |
Changed in linux: | |
status: | New → Triaged |
Changed in linux: | |
assignee: | nobody → amitk |
milestone: | none → ubuntu-9.04-beta |
Changed in linux (Ubuntu Jaunty): | |
status: | Triaged → New |
Changed in linux (Ubuntu Jaunty): | |
status: | New → In Progress |
tags: |
added: armel removed: arm |
Changed in linux-fsl-imx51 (Ubuntu): | |
milestone: | none → ubuntu-9.10-beta |
Changed in linux-fsl-imx51 (Ubuntu Jaunty): | |
milestone: | none → jaunty-updates |
Changed in linux-fsl-imx51 (Ubuntu): | |
milestone: | ubuntu-9.10-beta → lucid-updates |
Changed in linux-mvl-dove (Ubuntu): | |
milestone: | ubuntu-9.10-beta → lucid-updates |
milestone: | lucid-updates → lucid-alpha-1 |
Changed in linux-fsl-imx51 (Ubuntu): | |
milestone: | lucid-updates → lucid-alpha-1 |
milestone: | lucid-alpha-1 → karmic-updates |
milestone: | karmic-updates → lucid-alpha-1 |
Changed in linux-fsl-imx51 (Ubuntu): | |
status: | In Progress → Invalid |
status: | Invalid → In Progress |
Changed in linux-fsl-imx51 (Ubuntu Karmic): | |
milestone: | none → karmic-updates |
Changed in linux-mvl-dove (Ubuntu Karmic): | |
milestone: | none → karmic-updates |
Changed in linux-mvl-dove (Ubuntu Jaunty): | |
milestone: | none → jaunty-updates |
Changed in linux (Ubuntu Karmic): | |
status: | New → Invalid |
Taking a look at the kernel source, the syscall id numbers for both ppoll and pselect are properly reserved for ARM. The pselect function (sys_pselect7) is defined in fs/select.c; it is a C function with no specific arch dependent bits, but does require the sigmask_set_restore function to be available (threading is partially arch specific). This is a simple stub which sets the necessary flag (it lives in arch/*arch* /include/ thread_ info.h on architectures where it is defined, and sets the necessary flag in that architectures flag control block).
A couple greps of the source say that this flag is only used in a small bit of the thread block control code, used to push or pop the saved sigmask from the control block; implementing it shouldn't been too difficult, although it is possible that there is more to implementation than my greps can pick up.
glibc does not autodetect the presence of this call (possibly because depending on the architecture, the number of arguments change (since some arches can't hand 7 argument syscalls), so it will also have be modified to use the kernel's ppoll/psystem mechanisms once they are implemented in the kernel.