public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC] [PATCH] C exceptions in kernel
@ 2002-02-22 21:12 Dan Aloni
  2002-02-22 21:28 ` Davide Libenzi
                   ` (6 more replies)
  0 siblings, 7 replies; 29+ messages in thread
From: Dan Aloni @ 2002-02-22 21:12 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1567 bytes --]

The attached patch implements C exceptions in the kernel, which *don't*
depend on special support from the compiler. This is a 'request for
comments'. The patch is very initial, should not be applied.

I actually got this code to work in the kernel:

        try {
                printk("TEST: before throwing \n");
                throw(1000);
                printk("TEST: won't run\n");
        }
        catch(unsigned long, value) {
                printk("TEST: caught: %ld\n", value);
        } yrt;

I know it would a *hugh* task to get all existing code in the kernel
to use exceptions, but the design allows exceptions to be used locally
within the local call branches in *new* code. Basically, exception
handling needs to be added only to functions who call functions which
already use exceptions.

Although this patch is against 2.4, it should go to 2.5 (2.5.5-dj1
currently breaks here, so I am temporarily developing it using 2.4)

This patch implements only for i386 at the moment. Theoretically can be
ported to other archs. Of course, the arch dependant functions in this
code are separated for the ease of porting.

I haven't written it with interrupts and SMP in mind. I wonder what
are the race conditions and what should be protected there.

For unhandled exceptions, there's a possibility to add a function that
printk's the information about the unhandled exception (file, line
number, etc), and optionally calls panic() or BUG().

The code supports re-throwing from catches.

Last thing: I must get rid of that yrt closer macro. Suggestions?

[-- Attachment #2: exceptions.diff --]
[-- Type: text/x-patch, Size: 7314 bytes --]

diff -urN 2.4.18-ac3/arch/i386/kernel/Makefile 2.4.18-ac3-exceptions/arch/i386/kernel/Makefile
--- 2.4.18-ac3/arch/i386/kernel/Makefile	Sat Jan 19 10:22:58 2002
+++ 2.4.18-ac3-exceptions/arch/i386/kernel/Makefile	Fri Feb 22 20:09:09 2002
@@ -18,7 +18,8 @@
 
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
-		pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o
+		pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o \
+		exception.o
 
 
 ifdef CONFIG_PCI
diff -urN 2.4.18-ac3/arch/i386/kernel/exception.S 2.4.18-ac3-exceptions/arch/i386/kernel/exception.S
--- 2.4.18-ac3/arch/i386/kernel/exception.S	Thu Jan  1 02:00:00 1970
+++ 2.4.18-ac3-exceptions/arch/i386/kernel/exception.S	Fri Feb 22 20:18:45 2002
@@ -0,0 +1,112 @@
+/*
+ *   linux/arch/i386/kernel/exception.S
+ *
+ *   2002, Dan Aloni <da-x@gmx.net>
+ *
+ *   i386-specific exceptions implementation
+ */
+
+/* 
+ * offsets of stuff in except_t 
+ */
+	
+#define VALUE_OFFSET 0x18
+#define PREV_OFFSET 0x1c
+
+/* 
+ * no data, define anyway
+ */
+	
+.data
+.align 4
+
+/*
+ * code section
+ */
+	
+.text	
+.align 4
+
+/*
+ * long try_exception(except_t **current_frame, *this_exception)
+ *
+ * This function is used in the beginning of the try block. The function
+ * saves the current state of execution, which is the stack pointers, IP
+ * to return to, and the registers that a reserved during function calls.
+ *
+ * This function returns *twice*. Once with return value 0, for the normal. 
+ * execution, and second when the exception is caught, throw_exception 
+ * restores the execution state and sets the return value to 1.
+ *
+ * current_frame is the per-process variable that stores a pointer to
+ * the current exception frame (except_t), i.e, the exception frame that 
+ * was created by the most recent 'try' block in the current execution.
+ *
+ * this_exception is the new exception frame to initialize.
+ */
+	
+.globl try_exception
+try_exception:
+	movl 0x4(%esp),%ecx /* current_frame */
+	movl 0x8(%esp),%eax /* this_exception */
+
+	/* this_exception->prev = current_frame */
+	/* current_frame = this_exception */
+	
+	movl (%ecx), %edx
+	movl %edx, PREV_OFFSET (%eax)
+	movl %eax, (%ecx)
+
+	/* save return address, ebp, esi, edi, ebx, esp */
+	movl (%esp), %ecx
+	movl %ecx, 0x0(%eax)
+	movl %ebp, 0x4(%eax)
+	movl %esi, 0x8(%eax)
+	movl %edi, 0xC(%eax) 
+	movl %ebx, 0x10(%eax)
+	movl %esp, 0x14(%eax)
+	xorl %eax, %eax
+	ret
+
+/*
+ * throw_exception(except_t *current_frame, unsigned long value)
+ *
+ * Throws an exception with the given value. This restores the state that
+ * was saved in the frame using try_exception, and jumps back to where
+ * try_exception was called, with return value of 1. current_frame points
+ * to the current exception. 
+ *
+ * If current_frame == NULL, there is no code to catch the exception!
+ * in that case, throw_exception will return 1
+ *
+ */
+	
+.align 4
+.globl throw_exception
+throw_exception:
+	movl 0x4(%esp), %eax /* current_frame */
+	test %eax, %eax      /* return 1 if there's no handler */
+	jz no_handler
+	movl 0x8(%esp), %edx /* value */
+
+	/* restore execution state */
+	movl 0x0(%eax), %ecx
+	movl 0x4(%eax), %ebp
+	movl 0x8(%eax), %esi
+	movl 0xC(%eax), %edi 
+	movl 0x10(%eax), %ebx
+	movl 0x14(%eax), %esp
+
+	/* set the exception value */
+	addl $4, %esp
+	movl %edx, VALUE_OFFSET (%eax)
+
+	/* jump back to where try_exception returns */
+	movl $0x1, %eax
+	jmpl *%ecx
+
+no_handler:
+	xorl %eax, %eax
+	ret 
+	
+.align 4
diff -urN 2.4.18-ac3/include/asm-i386/exception.h 2.4.18-ac3-exceptions/include/asm-i386/exception.h
--- 2.4.18-ac3/include/asm-i386/exception.h	Thu Jan  1 02:00:00 1970
+++ 2.4.18-ac3-exceptions/include/asm-i386/exception.h	Fri Feb 22 21:08:21 2002
@@ -0,0 +1,13 @@
+#ifndef _I386_EXCEPTION_H
+#define _I386_EXCEPTION_H
+
+struct exception_arch_struct {
+	unsigned long eip; /* 0x0 */
+	unsigned long ebp; /* 0x4 */
+	unsigned long esi; /* 0x8 */
+	unsigned long edi; /* 0xC */
+	unsigned long ebx; /* 0x10 */
+	unsigned long esp; /* 0x14 */
+};
+
+#endif
diff -urN 2.4.18-ac3/include/linux/exception.h 2.4.18-ac3-exceptions/include/linux/exception.h
--- 2.4.18-ac3/include/linux/exception.h	Thu Jan  1 02:00:00 1970
+++ 2.4.18-ac3-exceptions/include/linux/exception.h	Fri Feb 22 21:12:40 2002
@@ -0,0 +1,83 @@
+#ifndef _LINUX_EXCEPTION_H
+#define _LINUX_EXCEPTION_H
+
+/*
+ * linux/include/linux/exception.h
+ *
+ * 2002, Dan Aloni <da-x@gmx.net>
+ *
+ * C exceptions for the Linux kernel.
+ */
+
+#include <asm/exception.h>
+#include <linux/sched.h>
+
+/* 
+ * struct exception_struct - an exception frame 
+ *
+ * These are linked together from the current->exception and down using the 'prev' field
+ * to the first exception in the current thread.
+ */
+
+struct exception_struct {
+	struct exception_arch_struct arch;  /* arch dependant stuff */
+	unsigned long value;                /* exception value */
+	struct exception_struct *prev;      /* previous frame */
+	unsigned char caught;               /* was this frame's catch ran already */
+};
+
+typedef struct exception_struct except_t;
+
+/* implementation can be found in arch/<arch>/kernel/exception.S */
+
+extern long try_exception(struct exception_struct **current_frame, struct exception_struct *e);
+extern void throw_exception(struct exception_struct *current_frame, unsigned long value);
+
+/*
+ * try, catch, throw, and yrt overlapping macros with current->exception as the
+ * current exception frame.
+ */
+
+#define try try__cur_frame(current->exception)
+#define catch(_type_, _dec_) catch__cur_frame(current->exception, _type_, _dec_)
+#define throw(_value_) throw__cur_frame(current->exception, _value_)
+#define yrt yrt__cur_frame(current->exception)
+
+
+/* 
+ * begin a try block:
+ */
+
+#define try__cur_frame(_cur_frame_) { \
+	struct exception_struct _exception_; \
+	if (!try_exception(&(_cur_frame_), &_exception_)) \
+
+/*
+ * begin a catch block:
+ */
+
+#define catch__cur_frame(_cur_frame_, _type_, _dec_) \
+        else { \
+		struct exception_struct *_this_frame_ = _cur_frame_; \
+		_type_ _dec_ = (_type_)_this_frame_->value; \
+		_exception_.caught = 1; \
+		_cur_frame_ = _this_frame_->prev; { 
+
+/*
+ * throw function: 
+ */
+
+#define throw__cur_frame(_cur_frame_, _value_) \
+		throw_exception(_cur_frame_, (unsigned long)_value_)
+
+/*
+ * yrt - this macro must end an exception frame declaration.
+ */
+
+#define yrt__cur_frame(_cur_frame_) } }; \
+	if (!_exception_.caught) \
+		_cur_frame_ = (_cur_frame_)->prev;  \
+}
+
+#endif
+
diff -urN 2.4.18-ac3/include/linux/sched.h 2.4.18-ac3-exceptions/include/linux/sched.h
--- 2.4.18-ac3/include/linux/sched.h	Fri Feb 22 11:51:15 2002
+++ 2.4.18-ac3-exceptions/include/linux/sched.h	Fri Feb 22 20:28:40 2002
@@ -385,6 +385,7 @@
 	struct sem_queue *semsleeping;
 /* CPU-specific state of this task */
 	struct thread_struct thread;
+	struct exception_struct *exception;
 /* filesystem information */
 	struct fs_struct *fs;
 /* open file information */

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-22 21:12 [RFC] [PATCH] C exceptions in kernel Dan Aloni
@ 2002-02-22 21:28 ` Davide Libenzi
  2002-02-22 22:10 ` Richard B. Johnson
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 29+ messages in thread
From: Davide Libenzi @ 2002-02-22 21:28 UTC (permalink / raw)
  To: Dan Aloni; +Cc: linux-kernel

On 22 Feb 2002, Dan Aloni wrote:

> The attached patch implements C exceptions in the kernel, which *don't*
> depend on special support from the compiler. This is a 'request for
> comments'. The patch is very initial, should not be applied.
>
> I actually got this code to work in the kernel:
>
>         try {
>                 printk("TEST: before throwing \n");
>                 throw(1000);
>                 printk("TEST: won't run\n");
>         }
>         catch(unsigned long, value) {
>                 printk("TEST: caught: %ld\n", value);
>         } yrt;
>
> I know it would a *hugh* task to get all existing code in the kernel
> to use exceptions, but the design allows exceptions to be used locally
> within the local call branches in *new* code. Basically, exception
> handling needs to be added only to functions who call functions which
> already use exceptions.
>
> Although this patch is against 2.4, it should go to 2.5 (2.5.5-dj1
> currently breaks here, so I am temporarily developing it using 2.4)
>
> This patch implements only for i386 at the moment. Theoretically can be
> ported to other archs. Of course, the arch dependant functions in this
> code are separated for the ease of porting.
>
> I haven't written it with interrupts and SMP in mind. I wonder what
> are the race conditions and what should be protected there.
>
> For unhandled exceptions, there's a possibility to add a function that
> printk's the information about the unhandled exception (file, line
> number, etc), and optionally calls panic() or BUG().
>
> The code supports re-throwing from catches.
>
> Last thing: I must get rid of that yrt closer macro. Suggestions?

Is today the 1st of April ? You kidding, don't you ?



- Davide




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-22 21:12 [RFC] [PATCH] C exceptions in kernel Dan Aloni
  2002-02-22 21:28 ` Davide Libenzi
@ 2002-02-22 22:10 ` Richard B. Johnson
  2002-02-22 22:34 ` David B. Stevens
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 29+ messages in thread
From: Richard B. Johnson @ 2002-02-22 22:10 UTC (permalink / raw)
  To: Dan Aloni; +Cc: linux-kernel

On 22 Feb 2002, Dan Aloni wrote:

> The attached patch implements C exceptions in the kernel, which *don't*
> depend on special support from the compiler. This is a 'request for
> comments'. The patch is very initial, should not be applied.
> 
> I actually got this code to work in the kernel:
> 
>         try {
>                 printk("TEST: before throwing \n");
>                 throw(1000);
>                 printk("TEST: won't run\n");
>         }
>         catch(unsigned long, value) {
>                 printk("TEST: caught: %ld\n", value);
>         } yrt;
> 

What is this supposed to do?  Are these a bunch of solutions waiting
for a problem? Or is my Calendar wrong?


Cheers,

Dick Johnson

Penguin : Linux version 2.4.1 on an i686 machine (797.90 BogoMips).

        111,111,111 * 111,111,111 = 12,345,678,987,654,321


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-22 21:12 [RFC] [PATCH] C exceptions in kernel Dan Aloni
  2002-02-22 21:28 ` Davide Libenzi
  2002-02-22 22:10 ` Richard B. Johnson
@ 2002-02-22 22:34 ` David B. Stevens
  2002-02-22 22:48   ` Davide Libenzi
  2002-02-23  3:37 ` Edgar Toernig
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 29+ messages in thread
From: David B. Stevens @ 2002-02-22 22:34 UTC (permalink / raw)
  To: Dan Aloni; +Cc: Davide Libenzi, Linux Kernel, Richard B. Johnson

Dan,

Don't let'em get to ya, they are having a time warp problem.

Finally a method of preventing oops'es.

Cheers,
  Dave


Dan Aloni wrote:
> 
> The attached patch implements C exceptions in the kernel, which *don't*
> depend on special support from the compiler. This is a 'request for
> comments'. The patch is very initial, should not be applied.
> 
> I actually got this code to work in the kernel:
> 
>         try {
>                 printk("TEST: before throwing \n");
>                 throw(1000);
>                 printk("TEST: won't run\n");
>         }
>         catch(unsigned long, value) {
>                 printk("TEST: caught: %ld\n", value);
>         } yrt;

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-22 22:34 ` David B. Stevens
@ 2002-02-22 22:48   ` Davide Libenzi
  0 siblings, 0 replies; 29+ messages in thread
From: Davide Libenzi @ 2002-02-22 22:48 UTC (permalink / raw)
  To: David B. Stevens; +Cc: Dan Aloni, Linux Kernel, Richard B. Johnson

On Fri, 22 Feb 2002, David B. Stevens wrote:

> Dan,
>
> Don't let'em get to ya, they are having a time warp problem.

Yup, if exceptions inside kernel code is the current time, my time warp is
so huge that Spilberg could use me like 1st actor in Jurassic Park IV
Buf i've got to tell you, life in Jurassica is pretty fine ...




- Davide



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-22 21:12 [RFC] [PATCH] C exceptions in kernel Dan Aloni
                   ` (2 preceding siblings ...)
  2002-02-22 22:34 ` David B. Stevens
@ 2002-02-23  3:37 ` Edgar Toernig
       [not found] ` <mailman.1014437101.26721.linux-kernel2news@redhat.com>
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 29+ messages in thread
From: Edgar Toernig @ 2002-02-23  3:37 UTC (permalink / raw)
  To: Dan Aloni; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 226 bytes --]

Dan Aloni wrote:
> 
> The attached patch implements C exceptions in the kernel,

Bad idea ...

> which *don't* depend on special support from the compiler.

... which can be implemented in simple ANSI-C.  See below.

Ciao, ET.

[-- Attachment #2: try-n-catch.c --]
[-- Type: text/plain, Size: 889 bytes --]

#include <setjmp.h>

struct _catch
{
    struct _catch *next;
    jmp_buf buf;
};

static struct _catch _catch_top[1];
struct _catch *_catch = _catch_top;

#define throw()				\
    do {				\
	_catch = _catch->next;		\
	longjmp(_catch->buf, 1);	\
    } while (0)


#define try				\
    if (setjmp(_catch->buf) == 0) {	\
	struct _catch _catch_new[1];	\
	_catch_new->next = _catch;	\
	_catch = _catch_new;

#define catch \
	_catch = _catch->next;		\
    } else


/**** example below ****/

#include <stdio.h>

int a = 1;

void
foo(int x)
{
    a=2;
    if (x & 1)
	throw();
}

int
main(int argc, char **argv)
{
    int i;

    for (i = 0; i < 10; ++i)
    {
	a=i;
	try
	{
	    try foo(i); catch
	    {
		printf("2: caught at %d (a=%d)\n", i, a);
		if ((i&3)==1)
		    throw();
	    }
	}
	catch
	{
	    printf("1: caught at %d (a=%d)\n", i, a);
	}
	printf("a=%d\n", a);
    }
    return 0;
}


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
       [not found] ` <mailman.1014437101.26721.linux-kernel2news@redhat.com>
@ 2002-02-23 10:11   ` Pete Zaitcev
  2002-02-23 12:26     ` Keith Owens
  0 siblings, 1 reply; 29+ messages in thread
From: Pete Zaitcev @ 2002-02-23 10:11 UTC (permalink / raw)
  To: Edgar Toernig; +Cc: linux-kernel

>> The attached patch implements C exceptions in the kernel,
> 
> Bad idea ...

Why is it bad? I can see a couple of reasons, but this does
not help me undestand your, unspecified, reasons.

>> which *don't* depend on special support from the compiler.
> 
> ... which can be implemented in simple ANSI-C.  See below.

Right, but the question is, do we support setjump/longjump
in kernel? The patch as I saw it does reimplement a similar thing
(check out its assembler fragments).

-- Pete

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 10:11   ` Pete Zaitcev
@ 2002-02-23 12:26     ` Keith Owens
  2002-02-23 12:50       ` Pete Zaitcev
  0 siblings, 1 reply; 29+ messages in thread
From: Keith Owens @ 2002-02-23 12:26 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: linux-kernel

On Sat, 23 Feb 2002 05:11:36 -0500, 
Pete Zaitcev <zaitcev@redhat.com> wrote:
>>> The attached patch implements C exceptions in the kernel,

Kernel code already has exception tables to handle invalid addresses,
invalid opcodes etc.  See copy_to_user and wrmsr_eio for examples.
Apart from that, the kernel code assumes that it knows what it is doing
and does not need exceptions, any unexpected exceptions quite correctly
fall into the oops handler.

The kernel model is "get it right the first time, so we don't need
exception handlers".  You have not given any reason why the existing
mechanisms are failing.

>do we support setjump/longjump
>in kernel? The patch as I saw it does reimplement a similar thing
>(check out its assembler fragments).

Standard kernel code does not support setjmp/longjmp.  AFAIK the only
code that does is the kdb patch where I need the extra protection, when
kdb is entered it is a fair bet that something has already gone wrong.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 12:26     ` Keith Owens
@ 2002-02-23 12:50       ` Pete Zaitcev
  2002-02-23 23:07         ` Jes Sorensen
  2002-02-23 23:50         ` Bill Huey
  0 siblings, 2 replies; 29+ messages in thread
From: Pete Zaitcev @ 2002-02-23 12:50 UTC (permalink / raw)
  To: Keith Owens; +Cc: Pete Zaitcev, linux-kernel

> From: Keith Owens <kaos@ocs.com.au>
> Date: Sat, 23 Feb 2002 23:26:52 +1100

> Kernel code already has exception tables to handle invalid addresses,
> invalid opcodes etc.  See copy_to_user and wrmsr_eio for examples.

I think you confuse hardware interrupts or exceptions with
language exceptions (which are the topic of current discussion).
Language exceptions constitute a fancy equivalent of return
code checking. Every time you see the following code, an exception
is handled:

int foo () {
   int rc;
   bar_t *x;

   if ((x = do_bar()) == NULL) { rc = -ENOMEM; goto out_nobar; }
   if ((rc = quux()) != 0) goto out_noquux;
   more_stuff();
   return 0;

 out_noquux;
   undo_bar(x);
 out_nobar:
   return rc;
}

> The kernel model is "get it right the first time, so we don't need
> exception handlers".  You have not given any reason why the existing
> mechanisms are failing.

If you understand that we are not talking about oopses here,
you will see that we emulate quite a bit of stuff with gotos.
The problem with current practice is that it takes a fair bit
of discipline to prevent it from growing into spaghetti [*].

Personally, I have no problem handling current practices.
But I may see the point of the guy with the try/catch patch.
Do not make me to defend him though. I am trying to learn
is those exceptions are actually helpful. BTW, we all know
where they come from (all of Cutler's NT is written that way),
but let it not cloud our judgement.

[*] List of subtlietes in the example, that a number of driver
monkeys get wrong:
1. rc must always be set right. Sometimes it's extracted from ERR_PTR,
   sometimes other ways.
2. You must have the Russian Doll commit-uncommit order. If you
   cannot fall into this rigid scheme, you must use more functions.
3. Names for labels correspond to what fails, not what has to be undone
   (or else you cannot move stuff around).

-- Pete

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-22 21:12 [RFC] [PATCH] C exceptions in kernel Dan Aloni
                   ` (4 preceding siblings ...)
       [not found] ` <mailman.1014437101.26721.linux-kernel2news@redhat.com>
@ 2002-02-23 15:13 ` Felix von Leitner
  2002-02-23 15:21 ` bert hubert
  6 siblings, 0 replies; 29+ messages in thread
From: Felix von Leitner @ 2002-02-23 15:13 UTC (permalink / raw)
  To: Dan Aloni, linux-kernel

Thus spake Dan Aloni (da-x@gmx.net):
> The attached patch implements C exceptions in the kernel, which *don't*
> depend on special support from the compiler. This is a 'request for
> comments'. The patch is very initial, should not be applied.

First of all: setjmp/longjmp is quite inefficient.

But my real problem with this is that the point about exceptions in C++
is the automatic stack unwinding.  You use local variables and if an
exception is thrown, they automatically self-destruct.  In particular,
you could implement spin locks as a class, and an exception will release
the lock automatically.  Since this is not there in C, this is no more
elegant than using explicit goto.

Also, it makes understanding the code (and correlating assembly output
with C code) less easy, because you also have to look at that exception
implementation.

Felix

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-22 21:12 [RFC] [PATCH] C exceptions in kernel Dan Aloni
                   ` (5 preceding siblings ...)
  2002-02-23 15:13 ` Felix von Leitner
@ 2002-02-23 15:21 ` bert hubert
  2002-02-23 16:05   ` Dan Aloni
  2002-02-23 17:47   ` Alexander Viro
  6 siblings, 2 replies; 29+ messages in thread
From: bert hubert @ 2002-02-23 15:21 UTC (permalink / raw)
  To: Dan Aloni; +Cc: linux-kernel

On Fri, Feb 22, 2002 at 09:18:29PM +0000, Dan Aloni wrote:
> The attached patch implements C exceptions in the kernel, which *don't*
> depend on special support from the compiler. This is a 'request for
> comments'. The patch is very initial, should not be applied.
> 
> I actually got this code to work in the kernel:
> 
>         try {
>                 printk("TEST: before throwing \n");
>                 throw(1000);
>                 printk("TEST: won't run\n");
>         }
>         catch(unsigned long, value) {
>                 printk("TEST: caught: %ld\n", value);
>         } yrt;

Can they fall through multiple function calls? How do they jive with
preemtive scheduling? How much is the stack unwinding overhead?

Potentially this is very cool but I'm again appalled at the INSTANT
rejection seen here by kernel hackers, minor and major. Do NOT reject an
idea before you've thought it through. Do NOT reject an idea simply because
it is new.

Also, do not jump on the bandwagon BECAUSE it is new. But still - people
here should get a life if they get off on rejecting new stuff because it is
new.

Regards,

bert


-- 
http://www.PowerDNS.com          Versatile DNS Software & Services
http://www.tk                              the dot in .tk
Netherlabs BV / Rent-a-Nerd.nl           - Nerd Available -
Linux Advanced Routing & Traffic Control: http://ds9a.nl/lartc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 15:21 ` bert hubert
@ 2002-02-23 16:05   ` Dan Aloni
  2002-02-23 16:22     ` Larry McVoy
  2002-02-23 17:47   ` Alexander Viro
  1 sibling, 1 reply; 29+ messages in thread
From: Dan Aloni @ 2002-02-23 16:05 UTC (permalink / raw)
  To: bert hubert; +Cc: linux-kernel

On Sat, 2002-02-23 at 17:21, bert hubert wrote:
> On Fri, Feb 22, 2002 at 09:18:29PM +0000, Dan Aloni wrote:
> > The attached patch implements C exceptions in the kernel, which *don't*
> > depend on special support from the compiler. This is a 'request for
> > comments'. The patch is very initial, should not be applied.
> > 
> > I actually got this code to work in the kernel:
> > 
> >         try {
> >                 printk("TEST: before throwing \n");
> >                 throw(1000);
> >                 printk("TEST: won't run\n");
> >         }
> >         catch(unsigned long, value) {
> >                 printk("TEST: caught: %ld\n", value);
> >         } yrt;
> 
> Can they fall through multiple function calls? How do they jive with
> preemtive scheduling? How much is the stack unwinding overhead?

They fall through several function calls like they should.

I don't see any problem with preemtive scheduling (every kernel thread
has its own seperated exception frames). 

The overhead on the stack is 36 bytes for each exception frame (a
context of a try block). The unwinding procedure itself is short, the
throw macro calls a rather small asm function for an unwind.

> Potentially this is very cool but I'm again appalled at the INSTANT
> rejection seen here by kernel hackers, minor and major. Do NOT reject an
> idea before you've thought it through. Do NOT reject an idea simply because
> it is new.
 
> Also, do not jump on the bandwagon BECAUSE it is new. But still - people
> here should get a life if they get off on rejecting new stuff because it is
> new.

Whether it is accepted or not, I can't see it being used in the core
kernel code, just because there is too much code to rewrite for it to
happen. Maybe if this thing was proposed back in 1992/3 it would have
been different.

But, it CAN be used in *local* driver call branches. Writing a new
driver? have a lot of local nested calls? Hate goto's? You can use
exceptions.

The only problem is that because C is natively not object oriented, it's
hard to come up with an exception scheme for the C language that is
better than ye' old goto's, like in C++ when you have automatic
destruction during unwinding.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 16:05   ` Dan Aloni
@ 2002-02-23 16:22     ` Larry McVoy
  2002-02-23 17:00       ` Dan Aloni
  2002-02-23 17:07       ` bert hubert
  0 siblings, 2 replies; 29+ messages in thread
From: Larry McVoy @ 2002-02-23 16:22 UTC (permalink / raw)
  To: Dan Aloni; +Cc: bert hubert, linux-kernel

On Sat, Feb 23, 2002 at 06:05:48PM +0200, Dan Aloni wrote:
> But, it CAN be used in *local* driver call branches. Writing a new
> driver? have a lot of local nested calls? Hate goto's? You can use
> exceptions.

Is this really anything other than syntactic sugar?  Maybe it's different 
in drivers, but I find myself doing the following in user space all the time

	#define	unless(x)	if (!(x))	/* perl/BCPL corrupted me */

	function(...)
	{
		char	*foo = 0, *bar = 0;
		int	locked = 0;
		int	rc = -1;

		if (bad args or something) {
	out:		if (foo) free(foo);
			if (bar) free(bar);
			if (locked) unlock();
			return (rc);
		}

		unless (locked = get_the_lock()) goto out;
		unless (foo = allocate_foo()) goto out;
		unless (bar = allocate_bar()) goto out;

		more code....

		rc = 0;
		goto out;
	}

It seems ugly at first but it has some nice attributes:

    a) all the cleanup is in one place, for both the error path and the 
       non-error path.  I could put it at the bottom, I like it at the
       top because that's where I tend to have the list of things needed
       to be cleaned.

    b) all the error cases are branches, the normal path is straightline.

    c) it's as dense as I can make it.

So how would you do the same thing with exceptions?
-- 
---
Larry McVoy            	 lm at bitmover.com           http://www.bitmover.com/lm 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 16:22     ` Larry McVoy
@ 2002-02-23 17:00       ` Dan Aloni
  2002-02-23 17:52         ` Francois Romieu
  2002-02-23 17:07       ` bert hubert
  1 sibling, 1 reply; 29+ messages in thread
From: Dan Aloni @ 2002-02-23 17:00 UTC (permalink / raw)
  To: linux-kernel

On Sat, 2002-02-23 at 18:22, Larry McVoy wrote:
> On Sat, Feb 23, 2002 at 06:05:48PM +0200, Dan Aloni wrote:
> > But, it CAN be used in *local* driver call branches. Writing a new
> > driver? have a lot of local nested calls? Hate goto's? You can use
> > exceptions.
> 
> Is this really anything other than syntactic sugar?  Maybe it's 
> different in drivers, but I find myself doing the following in user 
> space all the time
> 
> 	#define	unless(x)	if (!(x))	/* perl/BCPL corrupted me */
> 
> 	function(...)
> 	{
> 		char	*foo = 0, *bar = 0;
> 		int	locked = 0;
> 		int	rc = -1;
> 
> 		if (bad args or something) {
> 	out:		if (foo) free(foo);
> 			if (bar) free(bar);
> 			if (locked) unlock();
> 			return (rc);
> 		}
> 
> 		unless (locked = get_the_lock()) goto out;
> 		unless (foo = allocate_foo()) goto out;
> 		unless (bar = allocate_bar()) goto out;
> 
> 		more code....
> 
> 		rc = 0;
> 		goto out;
> 	}
> 
> It seems ugly at first but it has some nice attributes:
> 
>     a) all the cleanup is in one place, for both the error path and
the 
>        non-error path.  I could put it at the bottom, I like it at the
>        top because that's where I tend to have the list of things
needed
>        to be cleaned.
> 
>     b) all the error cases are branches, the normal path is
straightline.
> 
>     c) it's as dense as I can make it.
> 
> So how would you do the same thing with exceptions?

Like this:

function(...)
{
	char	*foo = 0, *bar = 0;
	int	locked = 0;
	int	rc = -1;
 
	try {
		if (bad args or something) 
			throw;
 
		locked = get_the_lock();
		foo = allocate_foo();
		bar = allocate_bar();

		more code....

		rc = 0;
	}	
	cleanup {
		if (foo) free(foo);
		if (bar) free(bar);
		if (locked) unlock();
	}  
	return rc;
}

Looks much better, IMHO.

The cleanup() block will run after the try block even if an exception 
did not occur, and will run also if the exception occured, passing the
exception to the next catch() or cleanup() block in stack.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 16:22     ` Larry McVoy
  2002-02-23 17:00       ` Dan Aloni
@ 2002-02-23 17:07       ` bert hubert
  1 sibling, 0 replies; 29+ messages in thread
From: bert hubert @ 2002-02-23 17:07 UTC (permalink / raw)
  To: Larry McVoy, Dan Aloni, linux-kernel

On Sat, Feb 23, 2002 at 08:22:11AM -0800, Larry McVoy wrote:
> On Sat, Feb 23, 2002 at 06:05:48PM +0200, Dan Aloni wrote:
> > But, it CAN be used in *local* driver call branches. Writing a new
> > driver? have a lot of local nested calls? Hate goto's? You can use
> > exceptions.
> 
> Is this really anything other than syntactic sugar?  Maybe it's different 
> in drivers, but I find myself doing the following in user space all the time

Exceptions provide implicit handling. You should see tham as an alternate
return path. And because of that implicitness, it is not syntactic sugar.

However, one thing which your example does emphasize, it the risk of
resource leaks. Bjarne Stroustrup, who is no mean architect himself, spends
a lot of pages discussing those leaks.

Basically, an exception may fall through several functions before being
caught. Any resources acquired by those intermediate functions will not be
released unless this is done automatically during stack unwinding, ie,
destroctors or alloca(3).

So while having an alternate return path is cool, it really needs
destructors in order to be useful in a real world. 

This url documents the problem, which is solved by adopting the 'Resource
Acquisition is Initialization' paradigm:
   http://sourceforge.net/docman/display_doc.php?docid=8673&group_id=9028

Regards,

bert

-- 
http://www.tk                              the dot in .tk
Netherlabs BV / Rent-a-Nerd.nl           - Nerd Available -
Linux Advanced Routing & Traffic Control: http://ds9a.nl/lartc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 15:21 ` bert hubert
  2002-02-23 16:05   ` Dan Aloni
@ 2002-02-23 17:47   ` Alexander Viro
  2002-02-23 18:21     ` bert hubert
  1 sibling, 1 reply; 29+ messages in thread
From: Alexander Viro @ 2002-02-23 17:47 UTC (permalink / raw)
  To: bert hubert; +Cc: Dan Aloni, linux-kernel



On Sat, 23 Feb 2002, bert hubert wrote:

> Potentially this is very cool but I'm again appalled at the INSTANT
> rejection seen here by kernel hackers, minor and major. Do NOT reject an
> idea before you've thought it through.

Quite a few of us _had_ thought it through.

> Do NOT reject an idea simply because
> it is new.

There was a new idea in this proposal?  Where?

You know, there's a reason why most of letal mutations are recessive.
Namely, it's not the first time when they happen and mechanisms making
them recessive had been selected for.

Same story here.  It's _not_ the first time this topic had been discussed
on l-k.  It might be new for you, but it sure as hell _not_ new for quite
a few people here.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 17:00       ` Dan Aloni
@ 2002-02-23 17:52         ` Francois Romieu
  0 siblings, 0 replies; 29+ messages in thread
From: Francois Romieu @ 2002-02-23 17:52 UTC (permalink / raw)
  To: Dan Aloni; +Cc: linux-kernel

Dan Aloni <da-x@gmx.net> :
[...]
> 	cleanup {
> 		if (foo) free(foo);
                ^^
> 		if (bar) free(bar);
                ^^
                    
> 		if (locked) unlock();
                ^^
> 	}  
> 	return rc;
> }
> 
> Looks much better, IMHO.
> 
> The cleanup() block will run after the try block even if an exception 
> did not occur, and will run also if the exception occured, passing the
> exception to the next catch() or cleanup() block in stack.

Three useless "if" if no exception occured.

-- 
Ueimor

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 17:47   ` Alexander Viro
@ 2002-02-23 18:21     ` bert hubert
  2002-02-23 18:31       ` Larry McVoy
  2002-02-23 23:05       ` Jes Sorensen
  0 siblings, 2 replies; 29+ messages in thread
From: bert hubert @ 2002-02-23 18:21 UTC (permalink / raw)
  To: Alexander Viro; +Cc: Dan Aloni, linux-kernel

On Sat, Feb 23, 2002 at 05:49:04PM +0000, Alexander Viro wrote:

> On Sat, 23 Feb 2002, bert hubert wrote:
> 
> > Potentially this is very cool but I'm again appalled at the INSTANT
> > rejection seen here by kernel hackers, minor and major. Do NOT reject an
> > idea before you've thought it through.
> 
> Quite a few of us _had_ thought it through.

Good.

> You know, there's a reason why most of letal mutations are recessive.
> Namely, it's not the first time when they happen and mechanisms making
> them recessive had been selected for.

An ostrich might reason that way too. And that is basically my main gripe.

> Same story here.  It's _not_ the first time this topic had been discussed
> on l-k.  It might be new for you, but it sure as hell _not_ new for quite
> a few people here.

Oh I've seen it. What I resent is the kneejerk reaction. Most people
replying obviously hadn't even looked at the source. Keith Owen's reaction
was wonderful:

	The kernel model is "get it right the first time, so we don't need
	exception handlers".  You have not given any reason why the existing
	mechanisms are failing.

Or Edgar Toernig, who also had an implementation and rejected Dan's in one
line: 

	Bad idea ...

Richard B. Johnson:

	What is this supposed to do?  Are these a bunch of solutions waiting
	for a problem? Or is my Calendar wrong?

Davide Libenzi:

	Is today the 1st of April ? You kidding, don't you ?

I mean, this is just pathetic. There is valid criticism to new ideas, but
this isn't it.

Regards,

bert

-- 
http://www.PowerDNS.com          Versatile DNS Software & Services
http://www.tk                              the dot in .tk
Netherlabs BV / Rent-a-Nerd.nl           - Nerd Available -
Linux Advanced Routing & Traffic Control: http://ds9a.nl/lartc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 18:21     ` bert hubert
@ 2002-02-23 18:31       ` Larry McVoy
  2002-02-23 18:38         ` bert hubert
  2002-02-23 23:05       ` Jes Sorensen
  1 sibling, 1 reply; 29+ messages in thread
From: Larry McVoy @ 2002-02-23 18:31 UTC (permalink / raw)
  To: bert hubert, Alexander Viro, Dan Aloni, linux-kernel

> I mean, this is just pathetic. There is valid criticism to new ideas, but
> this isn't it.

There are places to learn how to do basic programming and this isn't it.
There is no way that the kernel list can handle every bad idea over and
over again in a kind and gentle way.  Doing so requires so much time that
noone would ever get any real work done.  At some point, you just say
no.  If we didn't, we'd still be arguing about STREAMS, redoing the kernel
in C++, etc.
-- 
---
Larry McVoy            	 lm at bitmover.com           http://www.bitmover.com/lm 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 18:31       ` Larry McVoy
@ 2002-02-23 18:38         ` bert hubert
  2002-02-23 19:12           ` Kurt Ferreira
  0 siblings, 1 reply; 29+ messages in thread
From: bert hubert @ 2002-02-23 18:38 UTC (permalink / raw)
  To: Larry McVoy, Alexander Viro, Dan Aloni, linux-kernel

On Sat, Feb 23, 2002 at 10:31:01AM -0800, Larry McVoy wrote:
> > I mean, this is just pathetic. There is valid criticism to new ideas, but
> > this isn't it.
> 
> There are places to learn how to do basic programming and this isn't it.
> There is no way that the kernel list can handle every bad idea over and
> over again in a kind and gentle way.  Doing so requires so much time that
> noone would ever get any real work done.  At some point, you just say

Lots of people found the time to send derogative answers though - and how
well known are these in extinguising discussion and allowing us more time to
code! 

Typing in the few reasons why this, or any idea, is so well rejected hardly
takes more time and *does* extinguish the thread rapidly.

Regards,

bert

-- 
http://www.PowerDNS.com          Versatile DNS Software & Services
http://www.tk                              the dot in .tk
Netherlabs BV / Rent-a-Nerd.nl           - Nerd Available -
Linux Advanced Routing & Traffic Control: http://ds9a.nl/lartc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 18:38         ` bert hubert
@ 2002-02-23 19:12           ` Kurt Ferreira
  0 siblings, 0 replies; 29+ messages in thread
From: Kurt Ferreira @ 2002-02-23 19:12 UTC (permalink / raw)
  To: bert hubert; +Cc: linux-kernel

Hello,

On Sat, 23 Feb 2002, bert hubert wrote:

> Lots of people found the time to send derogative answers though - and how
> well known are these in extinguising discussion and allowing us more time to
> code! 
> 
> Typing in the few reasons why this, or any idea, is so well rejected hardly
> takes more time and *does* extinguish the thread rapidly.
>

I think you might not being understanding.  It has been discussed.  In
some cases over and over.  A search of the mailing list archives give the
reasons why these (and many like it) have been rejected.  The terse 'no'
is most likley fustration that the poster did not do his/her homework by
searching archives before posting.

Kurt


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 18:21     ` bert hubert
  2002-02-23 18:31       ` Larry McVoy
@ 2002-02-23 23:05       ` Jes Sorensen
  1 sibling, 0 replies; 29+ messages in thread
From: Jes Sorensen @ 2002-02-23 23:05 UTC (permalink / raw)
  To: bert hubert; +Cc: Alexander Viro, Dan Aloni, linux-kernel

bert hubert <ahu@ds9a.nl> writes:

> On Sat, Feb 23, 2002 at 05:49:04PM +0000, Alexander Viro wrote:
> Davide Libenzi:
> 
> 	Is today the 1st of April ? You kidding, don't you ?
> 
> I mean, this is just pathetic. There is valid criticism to new ideas, but
> this isn't it.

When the idea is as broken as this, then the above is what you are to
expect.

Jes

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 12:50       ` Pete Zaitcev
@ 2002-02-23 23:07         ` Jes Sorensen
  2002-02-23 23:40           ` Keith Owens
  2002-02-23 23:50         ` Bill Huey
  1 sibling, 1 reply; 29+ messages in thread
From: Jes Sorensen @ 2002-02-23 23:07 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: Keith Owens, linux-kernel

Pete Zaitcev <zaitcev@redhat.com> writes:

> Personally, I have no problem handling current practices.
> But I may see the point of the guy with the try/catch patch.
> Do not make me to defend him though. I am trying to learn
> is those exceptions are actually helpful. BTW, we all know
> where they come from (all of Cutler's NT is written that way),
> but let it not cloud our judgement.

The problem here is that when using exceptions, you stop thinking
about what is going on underneath at the low level which is really not
what one wants in the kernel.

After all, C is just and advanced assembly interface, which is exactly
why it's such a great language ;-)

Jes

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 23:07         ` Jes Sorensen
@ 2002-02-23 23:40           ` Keith Owens
  2002-02-24  1:02             ` Jes Sorensen
  0 siblings, 1 reply; 29+ messages in thread
From: Keith Owens @ 2002-02-23 23:40 UTC (permalink / raw)
  To: linux-kernel

On 24 Feb 2002 00:07:13 +0100, 
Jes Sorensen <jes@sunsite.dk> wrote:
>Pete Zaitcev <zaitcev@redhat.com> writes:
>
>> Personally, I have no problem handling current practices.
>> But I may see the point of the guy with the try/catch patch.
>> Do not make me to defend him though. I am trying to learn
>> is those exceptions are actually helpful. BTW, we all know
>> where they come from (all of Cutler's NT is written that way),
>> but let it not cloud our judgement.
>
>The problem here is that when using exceptions, you stop thinking
>about what is going on underneath at the low level which is really not
>what one wants in the kernel.
>
>After all, C is just and advanced assembly interface, which is exactly
>why it's such a great language ;-)

What is worse is that the exceptions patch has to use assembler to walk
the stack frames.  Exceptions are being touted as a replacement for
goto in new driver code but the sample patch only works for i386.  No
arch independent code can use exceptions until you have arch specific
code that does the equivalent of longjmp for _all_ architectures.

Doing longjmp in the kernel is _hard_, I know because I had to do it
for kdb on i386 and ia64.  The kernel does things differently from user
space and sometimes the arch maintainers decide to change the internal
register usage.  They are allowed to do this because it only affects
the kernel, but any change to kernel register usage will probably
require a corresponding change to setjmp/longjmp.

So you have arch dependent code which has to be done for all
architectures before any driver can use it and the code has to be kept
up to date by each arch maintainer.  Tell me again why the existing
mechanisms are not working and why we need exceptions?  IOW, what
existing problem justifies all the extra arch work and maintenance?


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 12:50       ` Pete Zaitcev
  2002-02-23 23:07         ` Jes Sorensen
@ 2002-02-23 23:50         ` Bill Huey
  2002-02-24  1:31           ` Davide Libenzi
  1 sibling, 1 reply; 29+ messages in thread
From: Bill Huey @ 2002-02-23 23:50 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: Keith Owens, linux-kernel

On Sat, Feb 23, 2002 at 07:50:02AM -0500, Pete Zaitcev wrote:
> Personally, I have no problem handling current practices.
> But I may see the point of the guy with the try/catch patch.
> Do not make me to defend him though. I am trying to learn
> is those exceptions are actually helpful. BTW, we all know
> where they come from (all of Cutler's NT is written that way),
> but let it not cloud our judgement.

Uh, that's probably not right. If I've been told/remember correctly,
it's a technique that certain old school mainframe OSes use to
implement sophisticate fault recovery of various sorts. As you know,
one basically rewinds to the original point before the block is
called so that you can recover/continue from it.

It's not clear if an OS like Linux could really benefit from it since
everything that is so inheritently hotwired in the kernel, nor is it
clear how something like exceptions would conceptual map onto that
kind of system. Maybe DB/FS stuff would be a good of that stuff if
you have a condition that prevents a write to a disk (etc.l.) and
because they are data structure intensive systems.

But what about the TCP/IP stack ? or things in the bottom half ?

Those things are a bit more sticky and seem less compatible with
exceptions it seems.

bill


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 23:40           ` Keith Owens
@ 2002-02-24  1:02             ` Jes Sorensen
  2002-02-24 23:45               ` Richard Gooch
  0 siblings, 1 reply; 29+ messages in thread
From: Jes Sorensen @ 2002-02-24  1:02 UTC (permalink / raw)
  To: Keith Owens; +Cc: linux-kernel

Keith Owens <kaos@ocs.com.au> writes:

> So you have arch dependent code which has to be done for all
> architectures before any driver can use it and the code has to be kept
> up to date by each arch maintainer.  Tell me again why the existing
> mechanisms are not working and why we need exceptions?  IOW, what
> existing problem justifies all the extra arch work and maintenance?

Sorry, can't tell you why as I agree wholeheartedly with you. My point
was that even if it was possible to implement exceptions 'for free' on
all architectures, then it's still not what we want in the
kernel. It's just too gross and makes people think about the code the
wrong way.

Cheers,
Jes

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-23 23:50         ` Bill Huey
@ 2002-02-24  1:31           ` Davide Libenzi
  2002-02-24  2:55             ` Bill Huey
  0 siblings, 1 reply; 29+ messages in thread
From: Davide Libenzi @ 2002-02-24  1:31 UTC (permalink / raw)
  To: Bill Huey; +Cc: Pete Zaitcev, Keith Owens, linux-kernel

On Sat, 23 Feb 2002, Bill Huey wrote:

> On Sat, Feb 23, 2002 at 07:50:02AM -0500, Pete Zaitcev wrote:
> > Personally, I have no problem handling current practices.
> > But I may see the point of the guy with the try/catch patch.
> > Do not make me to defend him though. I am trying to learn
> > is those exceptions are actually helpful. BTW, we all know
> > where they come from (all of Cutler's NT is written that way),
> > but let it not cloud our judgement.
>
> Uh, that's probably not right. If I've been told/remember correctly,
> it's a technique that certain old school mainframe OSes use to
> implement sophisticate fault recovery of various sorts. As you know,
> one basically rewinds to the original point before the block is
> called so that you can recover/continue from it.

You can't do that w/out an integrated resource allocation/deallocation
system. This because real code ends up by allocating resources ( or doing
whatever operation that needs an undo ) during its path and if you do not
have an automatic resource deallocation you're going to leak resources
more than Harleys engine oil. So w/out such system you've to catch
exceptions at every level where you actually own resources with the code
that is likely->surely to be way worse than the kernel gotos. Where you're
going to save is in cases where your code does not allocate any resource (
book's code ) and here you save the cost of multiple unwinding 'return's
against a single catch link. So, in case that an exception happen ( very
low probability compared to the common path ) and in case your code
underneath the catch point does not own resources, you're going to have a
'little' advantage. What is the cost ? You're going to push onto the
common path the exception code by slowing down the CPU's fast path.




- Davide




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-24  1:31           ` Davide Libenzi
@ 2002-02-24  2:55             ` Bill Huey
  0 siblings, 0 replies; 29+ messages in thread
From: Bill Huey @ 2002-02-24  2:55 UTC (permalink / raw)
  To: Davide Libenzi; +Cc: Pete Zaitcev, Keith Owens, linux-kernel

On Sat, Feb 23, 2002 at 05:31:33PM -0800, Davide Libenzi wrote:
> You can't do that w/out an integrated resource allocation/deallocation
> system. This because real code ends up by allocating resources ( or doing
> whatever operation that needs an undo ) during its path and if you do not
> have an automatic resource deallocation you're going to leak resources
> more than Harleys engine oil. So w/out such system you've to catch
> exceptions at every level where you actually own resources with the code
> that is likely->surely to be way worse than the kernel gotos. Where you're

It's a different attitude to doing recoverable systems. I can't fault
nor praise it because I've never used a system like that.

> going to save is in cases where your code does not allocate any resource (
> book's code ) and here you save the cost of multiple unwinding 'return's
> against a single catch link. So, in case that an exception happen ( very

Right, not many systems inside a kernel are the kind that you need a
sophisticated resource allocation/deallocation system except for, maybe,
FSes and possibly long chains of IO operations. I'm not sure what else would
fit in this category, but it's generally counter to the coding attitude
in Unix.

The things that exception would work well for seem to typically be modular
and can function independently from other subsystems in the kernel. Unix, on
the other hand, is pretty tightly interconnected so each subsystem's state is
some what dependent on the others, which can be unwieldly or impossible to
unwind properly.

It's almost the same kind of design style issue as the classic dead lock
problem. Some OSs provide a facility to detect those circular allocation,
but others just bail on that heavy weight idea and make it intrinsic to the
system that dead locks shouldn't exist in the first place. Both solutions have
their advantages, but Unix prefers the latter and it seems to lead to a
much snappier system from my intuition of it.

> low probability compared to the common path ) and in case your code
> underneath the catch point does not own resources, you're going to have a
> 'little' advantage. What is the cost ? You're going to push onto the
> common path the exception code by slowing down the CPU's fast path.

Not sure, memory allocators are typically pretty primitive relative to
modern GCs. I guess you could apply generational techniques to memory
allocation (stack allocation of objects typical) and have it run pretty
fast, but certainly not as fast as the typical hotwired C path.

It's not the only resource that might need to be unwound. Like what do you do
about IO system commits ? I'm not sure here.

Just bored and babbling here. ;-)

bill


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC] [PATCH] C exceptions in kernel
  2002-02-24  1:02             ` Jes Sorensen
@ 2002-02-24 23:45               ` Richard Gooch
  0 siblings, 0 replies; 29+ messages in thread
From: Richard Gooch @ 2002-02-24 23:45 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Keith Owens, linux-kernel

Jes Sorensen writes:
> Keith Owens <kaos@ocs.com.au> writes:
> 
> > So you have arch dependent code which has to be done for all
> > architectures before any driver can use it and the code has to be kept
> > up to date by each arch maintainer.  Tell me again why the existing
> > mechanisms are not working and why we need exceptions?  IOW, what
> > existing problem justifies all the extra arch work and maintenance?
> 
> Sorry, can't tell you why as I agree wholeheartedly with you. My
> point was that even if it was possible to implement exceptions 'for
> free' on all architectures, then it's still not what we want in the
> kernel. It's just too gross and makes people think about the code
> the wrong way.

This seems worthy of a new FAQ entry: http://www.tux.org/lkml/#s15-5
And while I was at it, I moved a bunch of these religious questions
into their own section. Section 1 is a bit of a hodge-podge.

				Regards,

					Richard....
Permanent: rgooch@atnf.csiro.au
Current:   rgooch@ras.ucalgary.ca

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2002-02-24 23:45 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-02-22 21:12 [RFC] [PATCH] C exceptions in kernel Dan Aloni
2002-02-22 21:28 ` Davide Libenzi
2002-02-22 22:10 ` Richard B. Johnson
2002-02-22 22:34 ` David B. Stevens
2002-02-22 22:48   ` Davide Libenzi
2002-02-23  3:37 ` Edgar Toernig
     [not found] ` <mailman.1014437101.26721.linux-kernel2news@redhat.com>
2002-02-23 10:11   ` Pete Zaitcev
2002-02-23 12:26     ` Keith Owens
2002-02-23 12:50       ` Pete Zaitcev
2002-02-23 23:07         ` Jes Sorensen
2002-02-23 23:40           ` Keith Owens
2002-02-24  1:02             ` Jes Sorensen
2002-02-24 23:45               ` Richard Gooch
2002-02-23 23:50         ` Bill Huey
2002-02-24  1:31           ` Davide Libenzi
2002-02-24  2:55             ` Bill Huey
2002-02-23 15:13 ` Felix von Leitner
2002-02-23 15:21 ` bert hubert
2002-02-23 16:05   ` Dan Aloni
2002-02-23 16:22     ` Larry McVoy
2002-02-23 17:00       ` Dan Aloni
2002-02-23 17:52         ` Francois Romieu
2002-02-23 17:07       ` bert hubert
2002-02-23 17:47   ` Alexander Viro
2002-02-23 18:21     ` bert hubert
2002-02-23 18:31       ` Larry McVoy
2002-02-23 18:38         ` bert hubert
2002-02-23 19:12           ` Kurt Ferreira
2002-02-23 23:05       ` Jes Sorensen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox