Re: 2.1.68 brokenness.

Linus Torvalds (torvalds@transmeta.com)
1 Dec 1997 03:06:10 GMT


In article <19971130194259.33168@jackalz>,
Myrdraal <myrdraal@jackalz.dyn.ml.org> wrote:
>Hi,
> Sound and various other parts of the kernel seem to be broken by the
> signal change stuff in 2.1.68.

Indeed. The signal stuff also breaks some of the other Linux platforms
(essentially everything but x86 and alpha). The other platforms will
take some time to sort out, and generally require a deeper understanding
of what the thing does, but everybody can chip in and help with the
"simple" things, ie device drivers etc that got broken.

Fixing stuff up isn't all that hard, you just have to understand that
the signal semantics got extended in order for the kernel to support new
signals and the semantics required by the POSIX real-time signal stuff.

The easiest case is actually the most common one: there are some places
(notably the sound driver) that use the older way of testing for pending
signals. They have code like

if (current->signal & ~current->blocked)
return -EINTR;

which is very easy to just change to

if (signal_pending(current))
return -EINTR;

so you can _almost_ fix these things up by just having a global
search-and-replace for this.

Some drivers, notably the ftape driver, have a slightly more complex
setup where they actually want to change the blocked signals. Then you
actually have to do some more work, and while it's not complex it's also
not just a search-anr-replace kind of thing.

For example, the ftape driver seems to do things like

int old_sigmask = current->blocked;

current->blocked = _BLOCK_ALL;
...
current->blocked = oldmask;

which wasn't really correct even before (it breaks on 64-bit
architectures), but got totally broken by the new signal stuff. In the
new order, the code would need to do something like this instead:

sigset_t old_sigmask;

spin_lock_irq(&current->sigmask_lock);
oldset = current->blocked;
siginitset(&current->blocked, _BLOCK_ALL);
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);

...

spin_lock_irq(&current->sigmask_lock);
current->blocked = old_sigmask;
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);

(the above is just a rough suggestion - you'd better look at some of the
examples in the current patches).

If you notice that ftape does a lot of the above, I'd suggest creating
the proper helper functions to do it, rather than blindly doing the
above every time..

Anyway, do we have any takers? Especially the sound patches should be
simple: I don't think the sound drivers try to mess around with signal
masks at all, so they should all be of the trivial kind to fix.

Linus