Path: utzoo!mnetor!uunet!munnari!otc!metro!ipso!runx!brucee
From: brucee@runx.ips.oz (Bruce Evans)
Newsgroups: comp.os.minix
Subject: Re: cause_sig problems?
Message-ID: <1509@runx.ips.oz>
Date: 8 May 88 12:38:41 GMT
References: <2378@louie.udel.EDU>
Reply-To: brucee@runx.OZ (Bruce Evans)
Organization: RUNX  Un*x Timeshare. Sydney, Australia.
Lines: 51
Summary: mini_send() in inform() is critical.

Leisner.Henr@xerox.com (Marty) writes:

> However, it seems to me a number of tasks/processes can get into cause_sig
> from
> different places (clock, tty and I'm calling it for SIGFPE, SIGSEGV and
> SIGILL).

> It seems like manipulated p_pending and sig_procs should be treated like
> critical sections, so I'm thinking of:

> [locks inside kernel/system/cause_sig() and kernel/system/inform()]

In the standard kernel, there is no problem with the call to cause_sig()
*itself* because
(1) It is only called by tasks (just clock and tty).
(2) The scheduler lets tasks run to completion.
(3) The scheduler does not use the critical variables (sig_procs and
	proc->p_pending).
For the same reasons, cause_sig() may be safely called from a hardware signal
handler which goes through interrupt() to a task (though a hardware signal
from inside the kernel is probably a bug).

Direct calls from mm and fs are not safe since these processes have lower
priorities than tasks and may be interrupted. Similarly, it is not safe
to introduce new task priorities (e.g., associated with multiple interrupt
priorites) without fixing the call to cause_sig(), and possibly every other
PUBLIC procedure in the kernel ...

The "itself" hedge above is because there seems to be a bug with the call to
mini_send() from inside inform(). In Marty's locking scheme (and the original
kernel), this seems to run with interrupts ENABLED. It is the only call to
mini_send() from outside proc.c. The calls from inside proc.c are properly
protected since they are inside interrupt routines which run entirely with
interrupts disabled.

I locked this call to mini_send() some time ago for completely different
reasons! (To allow most of the other explicit locks in proc.c to be removed,
where there was already an implicit lock.) I had been troubled by poor
response to the DEL key and fixed it without finding the exact cause. Maybe
this was it?

To summarise, there should be a lock()/restore() around the call to mini_send()
inside inform(). I don't like this as a final solution, because interrupts
may stay off too long. My kernel runs syscall() (and so many calls to
mini_send()) with interrupts enabled. Interrupts which occur while syscall()
is busy are treated specially. This does wonders for the serial driver. In a
perfect world, everything would run with interrupts enabled and be protected
by the tasking mechanism.

Bruce Evans
Internet: brucee@runx.ips.oz.au    UUCP: uunet!runx.ips.oz.au!brucee