TRY...EXCEPT semantics in kernel?

David Woodhouse (David.Woodhouse@mvhi.com)
Tue, 27 Oct 1998 13:21:59 +0000


Would it be possible to further use the 2.1 exception handling system to catch
and fix up exceptions?

For example, the problem which keeps bringing down our router is a simple
memory access fault, which could easily be trapped.

How about keeping a stack of 'exception handlers' for each CPU. If an oops is
generated while an 'exception handler' is in scope, the handler should be
called instead of oopsing.

In this case, the handler would simply drop the packet, which is far
preferable to killing the whole machine (as currently happens.)

Handlers would have to be per-CPU, and we could remove the need for them to be
per-process by banning schedule() while a handler is in scope.

Interrupt service routines would have to 'block' the current handler, which may
be bad for interrupt latency. It's probably worth it though.

Randomly throwing some code together (I haven't worked out how to implement
setjmp() yet)...

struct excepthandler
{
sigjmp_buf env;
struct excepthandler *next;
} *excepthandlers[NR_CPUS] = {NULL, ...} ;


int register_exceptionhandler(struct exceptionhandler *new)
{
int ret;

/* Lock me? Probably not - no other cpu will modify the same one */

ret = setjmp(env);

if (!ret)
{
new->next = excepthandlers[smp_processor_id()];
excepthandlers[smp_processor_id()] = new;
return 0;
}

/* Do we unregister the handler here? Probably. */

return ret;
}

void unregister_exception_handler(struct exceptionhandler *old)
{
/* Locking? */

if (excepthandlers[smp_processor_id()] != old)
{
printk(KERN_CRIT "Tried to unregister exception handler %p,\n", old);
printk(KERN_CRIT " which is not %p\n", excepthandlers[smp_processor_id()]);
*(int *)NULL = 0;
}

excepthandlers[smp_processor_id()] = old->next;
}

void handle_exception()
{
/* To be called from the 'no_context:' part of do_page_fault() */

struct excepthandler* this = excepthandlers[smp_processor_id()];

if (this))
longjmp(this->env, 1);
}

struct excepthandler *block_exception_handler()
{
/* To be called from ISR to block exception handlers */

struct excepthandler *ret = excepthandlers[smp_processor_id()];

excepthandlers[smp_processor_id()] = NULL;

return ret;
}

void unblock_excepthandler(struct excepthandler *saved)
{
/* To be called when ISR has finished, to replace handlers */

excepthandlers[smp_processor_id()] = saved;
}

---- ---- ----
David Woodhouse David.Woodhouse@mvhi.com Office: (+44) 1223 810302
Project Leader, Process Information Systems Mobile: (+44) 976 658355
Axiom (Cambridge) Ltd., Swaffham Bulbeck, Cambridge, CB5 0NA, UK.
finger dwmw2@ferret.lmh.ox.ac.uk for PGP key.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/