The trivial mod would have been to stub do_bottom_half to simply call
bh_handler, and then move the current do_bottom_half to some other
name. However, a function who's only purpose is to call another
function seemed ugly. So, I modified kernel/sched.c and
arch/i386/kernel/irq.c to call (bh_handler)() instead of
do_bottom_half. If this patch is considered generally useful then
someone would need to make similar changes to the other architectures.
(Not making the change to a specific architecture isn't catastrophic,
it just makes the patch not very useful as do_bottom_half rarely gets
called from the scheduler.)
What good is it? I am not sure it is interesting to anyone but me,
but I have played with a few bottom half handlers that each behave a
little differently. One has a hard limit on how long it will run
before it returns (in this case it is running as a kernel thread so
after it yields it eventually gets rescheduled to finish up - the
bh_handler simply wakes the kernel thread up.) One I would like to
play with is changing the bottom half handler to isolate the work to
be done for the network bottom half and treat it differently. I could
do a quick demux on the incoming packet (ignoring fragments for now)
and possibly associate some them with a process (or, more easily with
a port). If this works the next step might be to give special
priority and possibly even dedicated backlog queues to certain
processes (or ports). Modifying a server that is primarily
acting as a web server to favor port 80 might be useful.
Making the bottom halves handler a function pointer allows all of the
changes to exist within a module instead of having to rebuild the entire
kernel. Of course, it allows to you more easily toast your system as
well.
pete
this patch is against 2.2.7.
diff -ur linux-2.2.7.clean/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- linux-2.2.7.clean/arch/i386/kernel/irq.c Mon May 3 14:11:07 1999
+++ linux/arch/i386/kernel/irq.c Mon May 3 14:02:12 1999
@@ -813,7 +813,7 @@
*/
if (1) {
if (bh_active & bh_mask)
- do_bottom_half();
+ (bh_handler)();
}
}
diff -ur linux-2.2.7.clean/include/linux/interrupt.h linux/include/linux/interrupt.h
--- linux-2.2.7.clean/include/linux/interrupt.h Mon May 3 14:11:18 1999
+++ linux/include/linux/interrupt.h Mon May 3 14:01:26 1999
@@ -21,6 +21,7 @@
extern unsigned long bh_active;
extern unsigned long bh_mask;
extern void (*bh_base[32])(void);
+extern void (*bh_handler)(void);
asmlinkage void do_bottom_half(void);
diff -ur linux-2.2.7.clean/kernel/ksyms.c linux/kernel/ksyms.c
--- linux-2.2.7.clean/kernel/ksyms.c Mon May 3 14:10:55 1999
+++ linux/kernel/ksyms.c Mon May 3 14:02:38 1999
@@ -398,3 +398,9 @@
/* library functions */
EXPORT_SYMBOL(strnicmp);
+
+/* bottom half handler */
+EXPORT_SYMBOL(bh_handler);
+EXPORT_SYMBOL(do_bottom_half);
+extern asmlinkage int sys_sched_yield(void);
+EXPORT_SYMBOL(sys_sched_yield);
diff -ur linux-2.2.7.clean/kernel/sched.c linux/kernel/sched.c
--- linux-2.2.7.clean/kernel/sched.c Mon May 3 14:10:44 1999
+++ linux/kernel/sched.c Mon May 3 14:02:27 1999
@@ -58,6 +58,8 @@
DECLARE_TASK_QUEUE(tq_immediate);
DECLARE_TASK_QUEUE(tq_scheduler);
+void (*bh_handler)(void)=&do_bottom_half;
+
/*
* phase-lock loop variables
*/
@@ -665,7 +667,7 @@
/* Do "administrative" work here while we don't hold any locks */
if (bh_active & bh_mask)
- do_bottom_half();
+ (bh_handler)();
spin_lock(&scheduler_lock);
spin_lock_irq(&runqueue_lock);
-
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/