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

From: Tsutomu OWA
Date: Thu Aug 10 2006 - 22:00:07 EST



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


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/