Skip to contentSkip to conversation

I-pipe: Core implementation

PATCH In review Philippe Gerum 4 participants 8 messages Jun 17, 2005 – Jun 21, 2005

Subsystems (7)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 I-pipe: Core implementation

diffstat:

 include/linux/hardirq.h                          |   13
 linux-2.6.12-rc6-ipipe-0.5/Makefile              |    2
 linux-2.6.12-rc6-ipipe-0.5/include/linux/ipipe.h |  368 +++++++++++++++++
 linux-2.6.12-rc6-ipipe-0.5/include/linux/sched.h |    1
 linux-2.6.12-rc6-ipipe-0.5/init/Kconfig          |    1
 linux-2.6.12-rc6-ipipe-0.5/init/main.c           |    3
 linux-2.6.12-rc6-ipipe-0.5/ipipe/Kconfig         |   12
 linux-2.6.12-rc6-ipipe-0.5/ipipe/Makefile        |    9
 linux-2.6.12-rc6-ipipe-0.5/ipipe/generic.c       |  265 ++++++++++++
 linux-2.6.12-rc6-ipipe-0.5/kernel/Makefile       |    1
 linux-2.6.12-rc6-ipipe-0.5/kernel/ipipe.c        |  479 
+++++++++++++++++++++++
 linux-2.6.12-rc6-ipipe-0.5/kernel/irq/handle.c   |    9
 linux-2.6.12-rc6-ipipe-0.5/kernel/printk.c       |  102 +++-
 linux-2.6.12-rc6-ipipe-0.5/kernel/sysctl.c       |    3
 linux-2.6.12-rc6-ipipe-0.5/lib/kernel_lock.c     |    4
 linux-2.6.12-rc6-ipipe-0.5/mm/vmalloc.c          |    4
 16 files changed, 1254 insertions(+), 22 deletions(-)
Makefile +2 -0
diff -uNrp linux-2.6.12-rc6/Makefile linux-2.6.12-rc6-ipipe-0.5/Makefile
@@ -564,6 +564,8 @@ export MODLIB
 ifeq ($(KBUILD_EXTMOD),)
 core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/
 
+core-$(CONFIG_IPIPE) += ipipe/
+
 vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
 		     $(net-y) $(net-m) $(libs-y) $(libs-m)))
include/linux/hardirq.h +13 -0
@@ -86,8 +86,21 @@ extern void synchronize_irq(unsigned int
 # define synchronize_irq(irq)	barrier()
 #endif
 
+#ifdef CONFIG_IPIPE_CORE
+#define nmi_enter() \
+do { \
+    if (ipipe_current_domain == ipipe_root_domain) \
+	irq_enter(); \
+} while(0)
+#define nmi_exit() \
+do { \
+    if (ipipe_current_domain == ipipe_root_domain) \
+	sub_preempt_count(HARDIRQ_OFFSET); \
+} while(0)
+#else /* !CONFIG_IPIPE_CORE */
 #define nmi_enter()		irq_enter()
 #define nmi_exit()		sub_preempt_count(HARDIRQ_OFFSET)
+#endif /* CONFIG_IPIPE_CORE */
 
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 static inline void account_user_vtime(struct task_struct *tsk)
include/linux/ipipe.h +368 -0

368 lines not on this page · raw message

include/linux/sched.h +1 -0
diff -uNrp linux-2.6.12-rc6/include/linux/sched.h linux-2.6.12-rc6-ipipe-0.5/include/linux/sched.h
@@ -4,6 +4,7 @@
 #include <asm/param.h>	/* for HZ */
 
 #include <linux/config.h>
+#include <linux/ipipe.h>
 #include <linux/capability.h>
 #include <linux/threads.h>
 #include <linux/kernel.h>
init/Kconfig +1 -0
diff -uNrp linux-2.6.12-rc6/init/Kconfig linux-2.6.12-rc6-ipipe-0.5/init/Kconfig
@@ -69,6 +69,7 @@ menu "General setup"
 
 config LOCALVERSION
 	string "Local version - append to kernel release"
+	default "-ipipe"
 	help
 	  Append an extra string to the end of your kernel version.
 	  This will show up when you type uname, for example.
init/main.c +3 -0
diff -uNrp linux-2.6.12-rc6/init/main.c linux-2.6.12-rc6-ipipe-0.5/init/main.c
@@ -464,6 +464,7 @@ asmlinkage void __init start_kernel(void
 	trap_init();
 	rcu_init();
 	init_IRQ();
+ 	ipipe_init();
 	pidhash_init();
 	init_timers();
 	softirq_init();
@@ -596,6 +597,8 @@ static void __init do_basic_setup(void)
 	sock_init();
 
 	do_initcalls();
+
+	ipipe_takeover();
 }
 
 static void do_pre_smp_initcalls(void)
ipipe/Kconfig +12 -0
diff -uNrp linux-2.6.12-rc6/ipipe/Kconfig linux-2.6.12-rc6-ipipe-0.5/ipipe/Kconfig
@@ -0,0 +1,12 @@
+config IPIPE
+	tristate "Interrupt pipeline"
+	default y
+	---help---
+	  Activate this option if you want the interrupt pipeline to be
+	  compiled in.
+
+config IPIPE_CORE
+	def_bool IPIPE
+
+config IPIPE_PREEMPT_RT
+	def_bool PREEMPT_NONE || PREEMPT_VOLUNTARY || PREEMPT_DESKTOP || PREEMPT_RT
ipipe/Makefile +9 -0
diff -uNrp linux-2.6.12-rc6/ipipe/Makefile linux-2.6.12-rc6-ipipe-0.5/ipipe/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the I-pipe support.
+#
+
+obj-$(CONFIG_IPIPE)	+= ipipe.o
+
+ipipe-objs		:= generic.o
+
+ipipe-$(CONFIG_X86)	+= x86.o
ipipe/generic.c +265 -0

265 lines not on this page · raw message

diff -uNrp linux-2.6.12-rc6/ipipe/x86.c linux-2.6.12-rc6-ipipe-0.5/ipipe/x86.c

kernel/Makefile +1 -0
diff -uNrp linux-2.6.12-rc6/kernel/Makefile linux-2.6.12-rc6-ipipe-0.5/kernel/Makefile
@@ -9,6 +9,7 @@ obj-y     = sched.o fork.o exec_domain.o
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o
 
+obj-$(CONFIG_IPIPE_CORE) += ipipe.o
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += cpu.o spinlock.o
kernel/ipipe.c +479 -0

479 lines not on this page · raw message

kernel/irq/handle.c +9 -0
diff -uNrp linux-2.6.12-rc6/kernel/irq/handle.c linux-2.6.12-rc6-ipipe-0.5/kernel/irq/handle.c
@@ -81,6 +81,15 @@ fastcall int handle_IRQ_event(unsigned i
 {
 	int ret, retval = 0, status = 0;
 
+#ifdef CONFIG_IPIPE_CORE
+	/* If processing a timer tick, pass the original regs as
+	   collected during preemption and not our phony - always
+	   kernel-originated - frame, so that we don't wreck the
+	   profiling code. */
+	if (ipipe_running && __ipipe_tick_irq == irq)
+		regs = __ipipe_tick_regs + smp_processor_id();
+#endif /* CONFIG_IPIPE_CORE */
+
 	if (!(action->flags & SA_INTERRUPT))
 		local_irq_enable();
 
kernel/printk.c +80 -22

208 lines not on this page · raw message

kernel/sysctl.c +3 -0
diff -uNrp linux-2.6.12-rc6/kernel/sysctl.c linux-2.6.12-rc6-ipipe-0.5/kernel/sysctl.c
@@ -968,6 +968,9 @@ void __init sysctl_init(void)
 #ifdef CONFIG_PROC_FS
 	register_proc_table(root_table, proc_sys_root);
 	init_irq_proc();
+#ifdef CONFIG_IPIPE_CORE
+	__ipipe_init_proc();
+#endif /* CONFIG_IPIPE_CORE */
 #endif
 }
 
lib/kernel_lock.c +4 -0
diff -uNrp linux-2.6.12-rc6/lib/kernel_lock.c linux-2.6.12-rc6-ipipe-0.5/lib/kernel_lock.c
@@ -20,6 +20,10 @@ unsigned int smp_processor_id(void)
 	unsigned long preempt_count = preempt_count();
 	int this_cpu = __smp_processor_id();
 	cpumask_t this_mask;
+#ifdef CONFIG_IPIPE_CORE
+	if (ipipe_current_domain != ipipe_root_domain)
+	    return this_cpu;
+#endif /* CONFIG_IPIPE_CORE */
 
 	if (likely(preempt_count))
 		goto out;
mm/vmalloc.c +4 -0
diff -uNrp linux-2.6.12-rc6/mm/vmalloc.c linux-2.6.12-rc6-ipipe-0.5/mm/vmalloc.c
@@ -18,6 +18,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
 
 
 DEFINE_RWLOCK(vmlist_lock);
@@ -148,10 +149,13 @@ int map_vm_area(struct vm_struct *area,
 	pgd = pgd_offset_k(addr);
 	spin_lock(&init_mm.page_table_lock);
 	do {
+		pgd_t oldpgd = *pgd;
 		next = pgd_addr_end(addr, end);
 		err = vmap_pud_range(pgd, addr, next, prot, pages);
 		if (err)
 			break;
+		if (pgd_val(oldpgd) != pgd_val(*pgd))
+			set_pgdir(addr, *pgd);
 	} while (pgd++, addr = next, addr != end);
 	spin_unlock(&init_mm.page_table_lock);
 	flush_cache_vmap((unsigned long) area->addr, end);
Signature · 1 line
Philippe.
#1 lore raw

Hi!

Quoted 3 lines
 linux-2.6.12-rc6-ipipe-0.5/ipipe/Kconfig         |   12
 linux-2.6.12-rc6-ipipe-0.5/ipipe/Makefile        |    9
 linux-2.6.12-rc6-ipipe-0.5/ipipe/generic.c       |  265 ++++++++++++

Top-level directory for 3 files seems a bit excessive to me...
Pavel

Signature · 1 line
64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 ms         
#2 lore raw

Hello,

Quoted 10 lines · Pavel Machek

Hi!

Quoted 3 lines
linux-2.6.12-rc6-ipipe-0.5/ipipe/Kconfig         |   12
linux-2.6.12-rc6-ipipe-0.5/ipipe/Makefile        |    9
linux-2.6.12-rc6-ipipe-0.5/ipipe/generic.c       |  265 ++++++++++++

Top-level directory for 3 files seems a bit excessive to me...
Pavel

There's a fourth one (ipipe/x86.c) added by the arch-dependent patch, but yes, I agree that this could sound rather overkill to have this support in its own dir, especially a top-level one. The files under ipipe/ can be built as a loadable module, hence the current layout. Would you see this belonging to, e.g., the driver tree instead?

Signature · 1 line
Philippe.
#3 lore raw
Quoted 5 lines · Philippe Gerum

There's a fourth one (ipipe/x86.c) added by the arch-dependent patch, but yes, I agree that this could sound rather overkill to have this support in its own dir, especially a top-level one. The files under ipipe/ can be built as a loadable module, hence the current layout. Would you see this belonging to, e.g., the driver tree instead?

How about this instead:

Arch-indepedent parts:
----------------------
include/linux/ipipe.h

kernel/ipipe/Kconfig      (formerly ipipe/Kconfig)
kernel/ipipe/Makefile     (formerly ipipe/Makefile)
kernel/ipipe/core.c       (formerly kernel/ipipe.c)
kernel/ipipe/generic.c    (formerly ipipe/generi.c)

Arch-dependent parts:
---------------------
include/asm-i386/ipipe.h

arch/i386/kernel/ipipe-core.c (formerly arch/i386/kernel/ipipe.c) arch/i386/kernel/ipipe-root.c (formerly ipipe/x86.c)

Seems to me that the above makes more sense. Albeit you would have parts of the module in kernel/ipipe/* and the rest in arch/*/kernel/ipipe*.

Karim

Signature · 3 lines
Author, Speaker, Developer, Consultant
Pushing Embedded and Real-Time Linux Systems Beyond the Limits
http://www.opersys.com || [email protected] || 1-866-677-4546
#4 lore raw
Quoted 21 lines · Karim Yaghmour
Quoted 2 lines · Philippe Gerum

There's a fourth one (ipipe/x86.c) added by the arch-dependent patch, but yes, I agree that this could sound rather overkill to have this support in its own dir, especially a top-level one. The files under ipipe/ can be built as a loadable module, hence the current layout. Would you see this belonging to, e.g., the driver tree instead?

How about this instead:

Arch-indepedent parts:
----------------------
include/linux/ipipe.h

kernel/ipipe/Kconfig      (formerly ipipe/Kconfig)
kernel/ipipe/Makefile     (formerly ipipe/Makefile)
kernel/ipipe/core.c       (formerly kernel/ipipe.c)
kernel/ipipe/generic.c    (formerly ipipe/generi.c)

Arch-dependent parts:
---------------------
include/asm-i386/ipipe.h

Quoted 6 lines

arch/i386/kernel/ipipe-core.c (formerly arch/i386/kernel/ipipe.c) arch/i386/kernel/ipipe-root.c (formerly ipipe/x86.c)

Seems to me that the above makes more sense. Albeit you would have parts of the module in kernel/ipipe/* and the rest in arch/*/kernel/ipipe*.

I'm pondering now if having the i-pipe buildable as a module is still relevant, like it was during the early Adeos times. This was mainly used to reduce the compile-debug-reboot cycle, so that we could just unload the module for testing some non-critical Adeos features which were not related to the interrupt pipeline. This becomes clearly irrelevant in the i-pipe case (any bug in the i-pipe would very likely make the box go south anyway). Additionally, dealing with a dynamically loadable i-pipe adds a small but permanent overhead for testing if the pipeline is enabled during internal operations.

Any objection to make the pipeline a static-only feature?

Signature · 1 line
Philippe.
#5 lore raw
Quoted 1 line · Philippe Gerum

Any objection to make the pipeline a static-only feature?

FWIW, we conducted our tests with the I-pipe loaded as a module. Though we didn't publish that particular result as part of our earlier posting, we found that the price for having it loaded, but unused, versus not having it loaded at all made virtually no difference on overall system overhead. Such results would seem to indicate that having it as a loadable module has no specific advantage. Note, though, that we didn't do the test on all configs, just the "plain" one.

Of course the issue would be much easier to decide if you could provide a brief explanation as to what the difference is, in terms of execution path, between having it compilled as a module and not loaded, versus having it built-in and unused.

Karim

Signature · 3 lines
Author, Speaker, Developer, Consultant
Pushing Embedded and Real-Time Linux Systems Beyond the Limits
http://www.opersys.com || [email protected] || 1-866-677-4546
#6 lore raw
Quoted 14 lines · Karim Yaghmour
Quoted 1 line · Philippe Gerum

Any objection to make the pipeline a static-only feature?

FWIW, we conducted our tests with the I-pipe loaded as a module. Though we didn't publish that particular result as part of our earlier posting, we found that the price for having it loaded, but unused, versus not having it loaded at all made virtually no difference on overall system overhead. Such results would seem to indicate that having it as a loadable module has no specific advantage. Note, though, that we didn't do the test on all configs, just the "plain" one.

Quoted 4 lines

Of course the issue would be much easier to decide if you could provide a brief explanation as to what the difference is, in terms of execution path, between having it compilled as a module and not loaded, versus having it built-in and unused.

Having it built statically but unused by any other domain but Linux is basically like having local_irq_disable() and friends as out-of-line code, still with real hw masking, but with all interrupts going through the I-pipe's interrupt handler before being dispatched to the regular Linux handler.

OTOH, having the I-pipe as an unloaded module leaves the original interrupt path untouched (at least on x86), but requires a boolean check into each stall/unstall/test operations, and a few more (~4) in the interrupt path just to make sure that we are operating in real or virtual (i.e. pipelined) mode, IOW to check if the pipelining engine is engaged or not, and further decide if we should use the CPU or I-pipe masking ops. The other solution would have been to play the function pointer game in order to reach the pipelined/non-pipelined operations depending on the box being i-piped or not, but I was unsure of the impact on performances.

Signature · 1 line
Philippe.
#7 lore raw
In reply to Pavel Machek
Quoted 7 lines · Pavel Machek

Hi!

Quoted 3 lines
 linux-2.6.12-rc6-ipipe-0.5/ipipe/Kconfig         |   12
 linux-2.6.12-rc6-ipipe-0.5/ipipe/Makefile        |    9
 linux-2.6.12-rc6-ipipe-0.5/ipipe/generic.c       |  265 ++++++++++++

Top-level directory for 3 files seems a bit excessive to me...

I'm thinking it might make more sense to make this 2 patches against kernel/Kconfig and kernel/Makefile, and rename the .c to kernel/ipipe.c, and stick the arch-dependent chunk down in arch/<whatever>/kernel/

Unless somebody has a better idea?