Re: 2.1.99(pre3)

Dominik Weis (weis@dom.hws.edu)
Wed, 29 Apr 1998 15:02:57 -0400 (EDT)


On Wed, 29 Apr 1998, MOLNAR Ingo wrote:

>
> Hi Dominik,
>
> > I don't get 2.1.99(pre3) to boot. It stops with adding the swap space. The
> > last output that I get is:
> > Adding Swap: 130748K Swap-space (priority -1)
> >
> > I had no problems with 2.1.98. I used EGCS 1.0.2 to compile it(binutils
> > 2.9.0.3). My system is a dual PII (Tyan Mainboard), IDE harddisk and
> > CDROM.
>
> could you try io-apic-patch-2.1.99-pre3-B (attached), does it help?
>
> Ingo
The patch fix my problem.

Dominik

> --- linux/arch/i386/kernel/irq.c.orig Tue May 5 05:18:11 1998
> +++ linux/arch/i386/kernel/irq.c Tue May 5 06:20:25 1998
> @@ -66,9 +66,16 @@
> #define cached_21 ((cached_irq_mask | io_apic_irqs) & 0xff)
> #define cached_A1 (((cached_irq_mask | io_apic_irqs) >> 8) & 0xff)
>
> +/*
> + * on SMP this protects the IRQ controller hardware (8259A, IO-APIC, etc.)
> + * against parallel access from several CPUS. But we protect data structures
> + * too, these data structures can be understood as part of a 'generic IRQ
> + * controller'. All operations within this lock have a predictable latency,
> + * which does not depend on other locks.
> + */
> spinlock_t irq_controller_lock;
>
> -static unsigned int irq_events [NR_IRQS] = { -1, };
> +static unsigned int irqs_pending [NR_IRQS] = { -1, };
> static int disabled_irq [NR_IRQS] = { 0, };
>
> /*
> @@ -724,15 +731,20 @@
> */
> static inline void trigger_pending_irqs(unsigned int irq)
> {
> - if (irq_events[irq] && !ipi_pending[irq]) {
> + if (irqs_pending[irq] && !ipi_pending[irq]) {
> ipi_pending[irq] = 1;
> + /*
> + * there are no cross-CPU races, as we always send the
> + * IPI to the same CPU, and we hold the irq spinlock
> + */
> send_IPI(APIC_DEST_SELF, IO_APIC_VECTOR(irq));
> }
> }
>
> void enable_ioapic_irq (unsigned int irq)
> {
> - disabled_irq[irq] = 0;
> + if (disabled_irq[irq])
> + disabled_irq[irq]--;
> trigger_pending_irqs(irq);
> }
>
> @@ -741,26 +753,29 @@
> */
> static void disable_ioapic_irq(unsigned int irq)
> {
> - disabled_irq[irq] = 1;
> + disabled_irq[irq]++;
> }
>
> static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
> {
> - spin_lock(&irq_controller_lock);
> -
> - /* Ack the irq inside the lock! */
> + /*
> + * We ack the irq in the local APIC outside the lock
> + * since nobody is supposed to access this APIC now
> + */
> ack_APIC_irq();
> +
> + spin_lock(&irq_controller_lock);
> ipi_pending[irq] = 0;
>
> /* If the irq is disabled, just set a flag and return */
> if (disabled_irq[irq]) {
> - irq_events[irq] = 1;
> + irqs_pending[irq] = 1;
> spin_unlock(&irq_controller_lock);
> return;
> }
>
> - disabled_irq[irq] = 1;
> - irq_events[irq] = 0;
> + disabled_irq[irq]++;
> + irqs_pending[irq] = 0;
> hardirq_enter(cpu);
> spin_unlock(&irq_controller_lock);
>
> @@ -772,9 +787,9 @@
> handle_IRQ_event(irq, regs);
>
> spin_lock(&irq_controller_lock);
> - pending = irq_events[irq];
> - irq_events[irq] = 0;
> - disabled_irq[irq] = pending;
> + pending = irqs_pending[irq];
> + irqs_pending[irq] = 0;
> + disabled_irq[irq] -= 1-pending; /* pending == {0|1} */
> spin_unlock(&irq_controller_lock);
>
> if (!pending)
> @@ -818,14 +833,8 @@
> * SMP cross-CPU interrupts have their own specific
> * handlers).
> *
> - * the biggest change on SMP is the fact that we no more mask
> - * interrupts in hardware, please believe me, this is unavoidable,
> - * the hardware is largely message-oriented, i tried to force our
> - * state-driven irq handling scheme onto the IO-APIC, but no avail.
> - *
> - * so we soft-disable interrupts via 'event counters', the first 'incl'
> - * will do the IRQ handling. This also has the nice side effect of increased
> - * overlapping ... i saw no driver problem so far.
> + * the biggest change on SMP is that we no more mask interrupts in
> + * hardware. (we could mask them in the IO-APIC, but we dont do it).
> */
> asmlinkage void do_IRQ(struct pt_regs regs)
> {
> @@ -1070,7 +1079,7 @@
> outb(LATCH >> 8 , 0x40); /* MSB */
>
> for (i=0; i<NR_IRQS; i++) {
> - irq_events[i] = 0;
> + irqs_pending[i] = 0;
> disabled_irq[i] = 0;
> }
> /*
> --- linux/arch/i386/kernel/io_apic.c.orig Tue Apr 21 22:39:49 1998
> +++ linux/arch/i386/kernel/io_apic.c Tue May 5 06:24:23 1998
> @@ -361,6 +361,21 @@
> }
> }
>
> + /*
> + * There are broken mptables which register ISA+high-active+level IRQs,
> + * these are illegal and are converted here to ISA+high-active+edge
> + * IRQ sources. Careful, ISA+low-active+level is another broken entry
> + * type, it represents PCI IRQs 'embedded into an ISA bus', they have
> + * to be accepted. Yes, ugh.
> + */
> + if ( (mp_bus_id_to_type[bus] == MP_BUS_ISA) &&
> + (entry.polarity == 0) /* active-high */ &&
> + (entry.trigger == 1) /* level */ )
> + {
> + printk("broken BIOS, changing pin %d to edge\n", i);
> + entry.trigger = 0;
> + }
> +
> io_apic_write(0x10+2*i, *(((int *)&entry)+0));
> io_apic_write(0x11+2*i, *(((int *)&entry)+1));
> }
>
>

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu