Skip to contentSkip to conversation

Preemptible kernel for SH

PATCH In review Robert Love 2 participants 5 messages Dec 2, 2001 – Dec 5, 2001 SuperH

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Preemptible kernel for SH

The attached is the fully preemptible linux kernel patch, for the SH arch. This work is thanks to Jeremy Siegel of MontaVista.

You will need an SH-patched kernel tree, available from
http://sf.net/projects/linuxsh -- the CVS module "linux" has a drop-in replacement for 2.4.16.

You will need the base preempt-kernel patch, available from ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel

Feedback is desired.

Robert Love

arch/sh/config.in +2 -0
diff -urN linuxsh-2.4.14/arch/sh/config.in pass1/arch/sh/config.in
@@ -124,6 +124,8 @@
    hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
    hex 'Physical memory size' CONFIG_MEMORY_SIZE 00400000
 fi
+# Preemptible kernel feature
+bool 'Preemptible Kernel' CONFIG_PREEMPT
 endmenu
 
 if [ "$CONFIG_SH_HP690" = "y" ]; then
arch/sh/kernel/entry.S +97 -7

150 lines not on this page · raw message

arch/sh/kernel/irq.c +21 -0
diff -urN linuxsh-2.4.14/arch/sh/kernel/irq.c pass1/arch/sh/kernel/irq.c
@@ -229,6 +229,16 @@
 	struct irqaction * action;
 	unsigned int status;
 
+#ifdef CONFIG_PREEMPT
+	/*
+	 * At this point we're now about to actually call handlers,
+	 * and interrupts might get reenabled during them... bump
+	 * preempt_count to prevent any preemption while the handler
+	 * called here is pending...
+	 */
+	current->preempt_count += 1;
+#endif /* CONFIG_PREEMPT */
+
 	/* Get IRQ number */
 	asm volatile("stc	r2_bank, %0\n\t"
 		     "shlr2	%0\n\t"
@@ -298,8 +308,19 @@
 	desc->handler->end(irq);
 	spin_unlock(&desc->lock);
 
+
 	if (softirq_pending(cpu))
 		do_softirq();
+
+#ifdef CONFIG_PREEMPT
+	/*
+	 * We're done with the handlers, interrupts should be
+	 * currently disabled; decrement preempt_count now so
+	 * as we return preemption may be allowed...
+	 */
+	current->preempt_count -= 1;
+#endif /* CONFIG_PREEMPT */
+
 	return 1;
 }
 
include/asm-sh/hardirq.h +2 -0
diff -urN linuxsh-2.4.14/include/asm-sh/hardirq.h pass1/include/asm-sh/hardirq.h
@@ -34,6 +34,8 @@
 
 #define synchronize_irq()	barrier()
 
+#define release_irqlock(cpu)	do { } while (0)
+
 #else
 
 #error Super-H SMP is not available
include/asm-sh/mmu_context.h +4 -0
diff -urN linuxsh-2.4.14/include/asm-sh/mmu_context.h pass1/include/asm-sh/mmu_context.h
@@ -166,6 +166,10 @@
 				 struct mm_struct *next,
 				 struct task_struct *tsk, unsigned int cpu)
 {
+#ifdef CONFIG_PREEMPT
+	if (preempt_is_disabled() == 0)
+		BUG();
+#endif
 	if (prev != next) {
 		unsigned long __pgdir = (unsigned long)next->pgd;
 
include/asm-sh/smplock.h +79 -6

94 lines not on this page · raw message

include/asm-sh/softirq.h +3 -0
diff -urN linuxsh-2.4.14/include/asm-sh/softirq.h pass1/include/asm-sh/softirq.h
@@ -6,6 +6,7 @@
 
 #define local_bh_disable()			\
 do {						\
+	preempt_disable();			\
 	local_bh_count(smp_processor_id())++;	\
 	barrier();				\
 } while (0)
@@ -14,6 +15,7 @@
 do {						\
 	barrier();				\
 	local_bh_count(smp_processor_id())--;	\
+	preempt_enable();			\
 } while (0)
 
 #define local_bh_enable()				\
@@ -22,6 +24,7 @@
 	if (!--local_bh_count(smp_processor_id())	\
 	    && softirq_pending(smp_processor_id())) {	\
 		do_softirq();				\
+	preempt_enable();				\
 	}						\
 } while (0)
 
#1 lore raw

ftp://ftp.kernel.org/pub/linux/kernel/people/rml/sh/sh-update-rml-2.4.16-1.patch

I went ahead and diffed 2.4.16 against the SH tree. Thus you can patch 2.4.16 directly without checking into CVS. Hopefully this might encourage some testers.

ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel/v2.4/preempt-kernel-rml-2.4.16-1.patch

ftp://ftp.kernel.org/pub/linux/kernel/people/rml/sh/preempt-kernel-sh-2.4.16-1.patch

The above is links to the preempt-kernel patch and the arch-sh specific work.

Users need to patch 2.4.16 with the three patches above and enable CONFIG_PREEMPT to create the preemptible kernel for SH.

Robert Love

#2 lore raw
In reply to Robert Love

Just FYI... the preemptible kernel depends on non-preemptible critical regions denoted by spinlock calls (see Robert Love's excellent summary in Documentation/preempt-locking.txt). Many common drivers are assumed to have correct locking for SMP operation, but non-SMP drivers may not. I've only run the PreK SH kernel on the Solution Engine w/Ethernet and serial, but I did not yet check to see if additional locks might be required in drivers/char/sh-sci.c or drivers/net/stnic.c, which are specific to SH platforms and thus not SMP-safe otherwise.

--Jeremy

Quoted 13 lines · Robert Love

The attached is the fully preemptible linux kernel patch, for the SH arch. This work is thanks to Jeremy Siegel of MontaVista.

You will need an SH-patched kernel tree, available from
http://sf.net/projects/linuxsh -- the CVS module "linux" has a drop-in replacement for 2.4.16.

You will need the base preempt-kernel patch, available from ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel

Feedback is desired.

Robert Love

#3 lore raw
Quoted 8 lines · Jeremy Siegel

Just FYI... the preemptible kernel depends on non-preemptible critical regions denoted by spinlock calls (see Robert Love's excellent summary in Documentation/preempt-locking.txt). Many common drivers are assumed to have correct locking for SMP operation, but non-SMP drivers may not. I've only run the PreK SH kernel on the Solution Engine w/Ethernet and serial, but I did not yet check to see if additional locks might be required in drivers/char/sh-sci.c or drivers/net/stnic.c, which are specific to SH platforms and thus not SMP-safe otherwise.

Ahh, good point. Similar situation occured on ARM when it went preemptive. Thankfully, Russel King and company try to properly lock things even if they are no ops.

Coding under a preemptive kernel means more than what Documentation/preempt-locking.txt implies ... you have to protect data regions as if you are operating under SMP.

It is good practice, anyhow.

This means you can include linux/spinlock.h and use the locking constructs as needed. Under a normal UP kernel, they will compile away. Under a preemptive kernel, they will provide the needed reentrancy protection. If there ever is a an SMP SH kernel (or something like it) the kernel will be ready for the future.

Robert Love

#4 lore raw
In reply to Robert Love

Users of gcc-3.x will need the attached patch _for gcc_ to compile an SH kernel patched with preempt-kernel. This is _not_ our fault, it is a gcc bug and is now merged into CVS and should be part of gcc-3.1.

gcc-2.9x compiles without problem. It is only 3.x versions that suffer the bug.

Robert Love

P.S. Also of note: yes this works on Sega Dreamcast. You can have a fully preemptible Dreamcast. Impress your friends. Or something.

gcc/alias.c +9 -0
@@ -1041,6 +1041,9 @@
   /* Some RTL can be compared without a recursive examination.  */
   switch (code)
     {
+    case VALUE:
+     return CSELIB_VAL_PTR (x) == CSELIB_VAL_PTR (y);
+
     case REG:
       return REGNO (x) == REGNO (y);
 
@@ -1109,6 +1112,12 @@
 	  if (rtx_equal_for_memref_p (XEXP (x, i), XEXP (y, i)) == 0)
 	    return 0;
 	  break;
+
+	  /* This can happen for asm operands.  */
+	case 's':
+	  if (strcmp (XSTR (x, i), XSTR (y, i)))
+	    return 0;
+	break;
 
 	/* This can happen for an asm which clobbers memory.  */
 	case '0':