[RFC PATCH 2/4] powerpc 2.6.16-rt17: to boot on powerpc w/ RT

Tsutomu OWA tsutomu.owa at toshiba.co.jp
Fri Aug 11 12:02:15 EST 2006


  To boot on powermac and cell.

---
with PREEMPT_RT
BUG: using smp_processor_id() in preemptible [00000000] code: init/1
caller is .hpte_update+0x4c/0x250
Call Trace:
[C000000001467850] [C00000000000F250] .show_stack+0x68/0x1b4
(unreliable)
[C000000001467900] [C00000000014C4A4] .debug_smp_processor_id+0xc4/0xf4
[C000000001467990] [C00000000002BEC0] .hpte_update+0x4c/0x250
[C000000001467A40] [C00000000008C670] .do_wp_page+0x474/0x618
[C000000001467B10] [C00000000008DC30] .__handle_mm_fault+0xd50/0xe68
[C000000001467C20] [C000000000029EFC] .do_page_fault+0x48c/0x674
[C000000001467E30] [C000000000004760] .handle_page_fault+0x20/0x54

o to enable drivers.
  powermac/low_i2c.c:
    struct semaphore -> struct compat_semaphore
    spinlock_t -> raw_spinlock_t
  drivers/net/sungem.c: transmit_tx_frame(). try_spinlock_irqsave()
  make spinlock_t to raw_spinlock_t for mpic and native_tlbie_lock.
  make struct semaphore to struct compat_semaphore for kw2_i2c.

* to boot on cell
  o port systemsim bogus disk and console.  (not included in this patch)
with PREEMPT_RT
BUG: swapper:0 task might have lost a preemption check!
Call Trace:
[C0000000002FFC40] [C00000000000F250] .show_stack+0x68/0x1b4
(unreliable)
[C0000000002FFCF0] [C0000000000425F8]
.preempt_enable_no_resched+0x68/0x80
[C0000000002FFD70] [C000000000032EC0] .cbe_idle+0x168/0x184
[C0000000002FFE00] [C000000000018DD0] .cpu_idle+0x4c/0x60
[C0000000002FFE70] [C000000000009290] .rest_init+0x60/0x78
[C0000000002FFEF0] [C0000000002CE890] .start_kernel+0x310/0x330
[C0000000002FFF90] [C000000000008574] .start_here_common+0x88/0x114

--
BUG: using smp_processor_id() in preemptible [00000000] code: init/1
caller is .hpte_update+0x4c/0x250
Call Trace:
[C000000001467850] [C00000000000F250] .show_stack+0x68/0x1b4
(unreliable)
[C000000001467900] [C00000000014C4A4] .debug_smp_processor_id+0xc4/0xf4
[C000000001467990] [C00000000002BEC0] .hpte_update+0x4c/0x250
[C000000001467A40] [C00000000008C670] .do_wp_page+0x474/0x618
[C000000001467B10] [C00000000008DC30] .__handle_mm_fault+0xd50/0xe68
[C000000001467C20] [C000000000029EFC] .do_page_fault+0x48c/0x674
[C000000001467E30] [C000000000004760] .handle_page_fault+0x20/0x54
-- owa

diff -rup -x CVS 2.6.16-rt17/arch/powerpc/mm/hash_native_64.c rt-powerpc/arch/powerpc/mm/hash_native_64.c
--- 2.6.16-rt17/arch/powerpc/mm/hash_native_64.c	2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/arch/powerpc/mm/hash_native_64.c	2006-07-12 14:38:24.000000000 +0900
@@ -35,7 +35,10 @@
 
 #define HPTE_LOCK_BIT 3
 
-static DEFINE_SPINLOCK(native_tlbie_lock);
+/*
+ * to avoid "BUG: scheduling while atomic at native_flush_hash_range.
+ */
+static DEFINE_RAW_SPINLOCK(native_tlbie_lock);
 
 static inline void __tlbie(unsigned long va, unsigned int psize)
 {
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/mm/tlb_64.c rt-powerpc/arch/powerpc/mm/tlb_64.c
--- 2.6.16-rt17/arch/powerpc/mm/tlb_64.c	2006-04-26 18:24:28.000000000 +0900
+++ rt-powerpc/arch/powerpc/mm/tlb_64.c	2006-07-12 13:47:32.000000000 +0900
@@ -95,9 +95,15 @@ static void pte_free_submit(struct pte_f
 
 void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
 {
+#ifndef CONFIG_PREEMPT_RT
 	/* This is safe since tlb_gather_mmu has disabled preemption */
         cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
 	struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
+#else
+        cpumask_t local_cpumask = cpumask_of_cpu(raw_smp_processor_id());
+	struct pte_freelist_batch **batchp = &get_cpu_var(pte_freelist_cur);
+	put_cpu_var(pte_freelist_cur);
+#endif /* !CONFIG_PREEMPT_RT */
 
 	if (atomic_read(&tlb->mm->mm_users) < 2 ||
 	    cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/platforms/cell/pervasive.c rt-powerpc/arch/powerpc/platforms/cell/pervasive.c
--- 2.6.16-rt17/arch/powerpc/platforms/cell/pervasive.c	2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/arch/powerpc/platforms/cell/pervasive.c	2006-07-12 13:48:09.000000000 +0900
@@ -136,8 +136,8 @@ static void cbe_idle(void)
 		 */
 		ppc64_runlatch_on();
 
-		preempt_enable_no_resched();
-		schedule();
+		__preempt_enable_no_resched();
+		__schedule();
 		preempt_disable();
 	}
 }
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/platforms/powermac/low_i2c.c rt-powerpc/arch/powerpc/platforms/powermac/low_i2c.c
--- 2.6.16-rt17/arch/powerpc/platforms/powermac/low_i2c.c	2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/arch/powerpc/platforms/powermac/low_i2c.c	2006-07-12 13:49:09.000000000 +0900
@@ -85,7 +85,7 @@ struct pmac_i2c_bus
 	void			*hostdata;
 	int			channel;	/* some hosts have multiple */
 	int			mode;		/* current mode */
-	struct semaphore	sem;
+	struct compat_semaphore	sem;
 	int			opened;
 	int			polled;		/* open mode */
 	struct platform_device	*platform_dev;
@@ -105,7 +105,7 @@ static LIST_HEAD(pmac_i2c_busses);
 
 struct pmac_i2c_host_kw
 {
-	struct semaphore	mutex;		/* Access mutex for use by
+	struct compat_semaphore	mutex;		/* Access mutex for use by
 						 * i2c-keywest */
 	void __iomem		*base;		/* register base address */
 	int			bsteps;		/* register stepping */
@@ -119,6 +119,9 @@ struct pmac_i2c_host_kw
 	int			result;
 	struct completion	complete;
 	spinlock_t		lock;
+		/* "BUG: scheduling while at atomic" at del_timer() called
+		 * from kw_i2c_irq() if raw_spinlock_t.
+		 */
 	struct timer_list	timeout_timer;
 };
 
diff -rup -x CVS 2.6.16-rt17/arch/powerpc/sysdev/mpic.c rt-powerpc/arch/powerpc/sysdev/mpic.c
--- 2.6.16-rt17/arch/powerpc/sysdev/mpic.c	2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/arch/powerpc/sysdev/mpic.c	2006-07-11 16:19:06.000000000 +0900
@@ -45,7 +45,7 @@
 
 static struct mpic *mpics;
 static struct mpic *mpic_primary;
-static DEFINE_SPINLOCK(mpic_lock);
+static DEFINE_RAW_SPINLOCK(mpic_lock);
 
 #ifdef CONFIG_PPC32	/* XXX for now */
 #ifdef CONFIG_IRQ_ALL_CPUS
@@ -1009,13 +1009,13 @@ void mpic_request_ipis(void)
 	printk("requesting IPIs ... \n");
 
 	/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
-	request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT,
+	request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT | SA_NODELAY,
 		    "IPI0 (call function)", mpic);
-	request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT,
+	request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT | SA_NODELAY,
 		   "IPI1 (reschedule)", mpic);
-	request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT,
+	request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT | SA_NODELAY,
 		   "IPI2 (unused)", mpic);
-	request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT,
+	request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT | SA_NODELAY,
 		   "IPI3 (debugger break)", mpic);
 
 	printk("IPIs requested... \n");
diff -rup -x CVS 2.6.16-rt17/drivers/ide/ide-io.c rt-powerpc/drivers/ide/ide-io.c
--- 2.6.16-rt17/drivers/ide/ide-io.c	2006-04-26 18:24:28.000000000 +0900
+++ rt-powerpc/drivers/ide/ide-io.c	2006-07-12 13:50:47.000000000 +0900
@@ -1560,8 +1560,10 @@ irqreturn_t ide_intr (int irq, void *dev
 	del_timer(&hwgroup->timer);
 	spin_unlock(&ide_lock);
 
+#if !defined(CONFIG_PREEMPT_HARDIRQS) || !defined(CONFIG_PPC_PMAC64)
 	if (drive->unmask)
 		local_irq_enable_nort();
+#endif /* !(CONFIG_PREEMPT_HARDIRQS && CONFIG_PPC_PMAC64) */
 	/* service this interrupt, may set handler for next interrupt */
 	startstop = handler(drive);
 	spin_lock_irq(&ide_lock);
diff -rup -x CVS 2.6.16-rt17/drivers/ide/ide-probe.c rt-powerpc/drivers/ide/ide-probe.c
--- 2.6.16-rt17/drivers/ide/ide-probe.c	2006-04-26 18:24:28.000000000 +0900
+++ rt-powerpc/drivers/ide/ide-probe.c	2006-07-12 14:07:23.000000000 +0900
@@ -51,6 +51,7 @@
 #include <linux/spinlock.h>
 #include <linux/kmod.h>
 #include <linux/pci.h>
+#include <linux/irq.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -1088,6 +1089,10 @@ static int init_irq (ide_hwif_t *hwif)
 		sa = SA_SHIRQ;
 #endif /* __mc68000__ || CONFIG_APUS */
 
+#if defined(CONFIG_PREEMPT_HARDIRQS) && defined(CONFIG_PPC_PMAC64)
+		sa |= SA_NODELAY | SA_INTERRUPT;
+#endif /* (CONFIG_PREEMPT_HARDIRQS && CONFIG_PPC_PMAC64) */
+
 		if (IDE_CHIPSET_IS_PCI(hwif->chipset)) {
 			sa = SA_SHIRQ;
 #ifndef CONFIG_IDEPCI_SHARE_IRQ
diff -rup -x CVS 2.6.16-rt17/drivers/net/sungem.c rt-powerpc/drivers/net/sungem.c
--- 2.6.16-rt17/drivers/net/sungem.c	2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/drivers/net/sungem.c	2006-07-11 17:07:43.000000000 +0900
@@ -1036,10 +1036,8 @@ static int gem_start_xmit(struct sk_buff
 			(csum_stuff_off << 21));
 	}
 
-	local_irq_save(flags);
-	if (!spin_trylock(&gp->tx_lock)) {
+	if (!spin_trylock_irqsave(&gp->tx_lock, flags)) {
 		/* Tell upper layer to requeue */
-		local_irq_restore(flags);
 		return NETDEV_TX_LOCKED;
 	}
 	/* We raced with gem_do_stop() */
diff -rup -x CVS 2.6.16-rt17/include/asm-powerpc/mpic.h rt-powerpc/include/asm-powerpc/mpic.h
--- 2.6.16-rt17/include/asm-powerpc/mpic.h	2006-03-20 14:53:29.000000000 +0900
+++ rt-powerpc/include/asm-powerpc/mpic.h	2006-05-19 20:48:49.000000000 +0900
@@ -160,7 +160,7 @@ struct mpic
 #ifdef CONFIG_MPIC_BROKEN_U3
 	/* The fixup table */
 	struct mpic_irq_fixup	*fixups;
-	spinlock_t		fixup_lock;
+	raw_spinlock_t		fixup_lock;
 #endif
 
 	/* The various ioremap'ed bases */
diff -rup -x CVS 2.6.16-rt17/kernel/latency.c rt-powerpc/kernel/latency.c
--- 2.6.16-rt17/kernel/latency.c	2006-04-26 18:24:29.000000000 +0900
+++ rt-powerpc/kernel/latency.c	2006-07-12 13:57:31.000000000 +0900
@@ -1787,7 +1787,12 @@ void notrace add_preempt_count(unsigned 
 #endif
 
 	preempt_count() += val;
+
 #ifdef CONFIG_PREEMPT_TRACE
+#if 1 /* FIXME: somehow current is NULL. why? */
+	if (!current) 
+		return;
+#endif
 	




More information about the Linuxppc-dev mailing list