1. 17 4月, 2008 4 次提交
  2. 30 1月, 2008 7 次提交
  3. 25 1月, 2008 1 次提交
  4. 19 12月, 2007 1 次提交
    • I
      x86: fix "Kernel panic - not syncing: IO-APIC + timer doesn't work!" · 4aae0702
      Ingo Molnar 提交于
      this is the tale of a full day spent debugging an ancient but elusive bug.
      
      after booting up thousands of random .config kernels, i finally happened
      to generate a .config that produced the following rare bootup failure
      on 32-bit x86:
      
      | ..TIMER: vector=0x31 apic1=0 pin1=2 apic2=-1 pin2=-1
      | ..MP-BIOS bug: 8254 timer not connected to IO-APIC
      | ...trying to set up timer (IRQ0) through the 8259A ...  failed.
      | ...trying to set up timer as Virtual Wire IRQ... failed.
      | ...trying to set up timer as ExtINT IRQ... failed :(.
      | Kernel panic - not syncing: IO-APIC + timer doesn't work!  Boot with apic=debug
      | and send a report.  Then try booting with the 'noapic' option
      
      this bug has been reported many times during the years, but it was never
      reproduced nor fixed.
      
      the bug that i hit was extremely sensitive to .config details.
      
      First i did a .config-bisection - suspecting some .config detail.
      That led to CONFIG_X86_MCE: enabling X86_MCE magically made the bug disappear
      and the system would boot up just fine.
      
      Debugging my way through the MCE code ended up identifying two unlikely
      candidates: the thing that made a real difference to the hang was that
      X86_MCE did two printks:
      
       Intel machine check architecture supported.
       Intel machine check reporting enabled on CPU#1.
      
      Adding the same printks to a !CONFIG_X86_MCE kernel made the bug go away!
      
      this left timing as the main suspect: i experimented with adding various
      udelay()s to the arch/x86/kernel/io_apic_32.c:check_timer() function, and
      the race window turned out to be narrower than 30 microseconds (!).
      
      That made debugging especially funny, debugging without having printk
      ability before the bug hits is ... interesting ;-)
      
      eventually i started suspecting IRQ activities - those are pretty much the
      only thing that happen this early during bootup and have the timescale of
      a few dozen microseconds. Also, check_timer() changes the IRQ hardware
      in various creative ways, so the main candidate became IRQ0 interaction.
      
      i've added a counter to track timer irqs (on which core they arrived, at
      what exact time, etc.) and found that no timer IRQ would arrive after the
      bug condition hits - even if we re-enable IRQ0 and re-initialize the i8259A,
      but that we'd get a small number of timer irqs right around the time when we
      call the check_timer() function.
      
      Eventually i got the following backtrace triggered from debug code in the
      timer interrupt:
      
      ...trying to set up timer as Virtual Wire IRQ... failed.
      ...trying to set up timer as ExtINT IRQ...
      Pid: 1, comm: swapper Not tainted (2.6.24-rc5 #57)
      EIP: 0060:[<c044d57e>] EFLAGS: 00000246 CPU: 0
      EIP is at _spin_unlock_irqrestore+0x5/0x1c
      EAX: c0634178 EBX: 00000000 ECX: c4947d63 EDX: 00000246
      ESI: 00000002 EDI: 00010031 EBP: c04e0f2e ESP: f7c41df4
       DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
       CR0: 8005003b CR2: ffe04000 CR3: 00630000 CR4: 000006d0
       DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
       DR6: ffff0ff0 DR7: 00000400
        [<c05f5784>] setup_IO_APIC+0x9c3/0xc5c
      
      the spin_unlock() was called from init_8259A(). Wait ... we have an IRQ0
      entry while we are in the middle of setting up the local APIC, the i8259A
      and the PIT??
      
      That is certainly not how it's supposed to work! check_timer() was supposed
      to be called with irqs turned off - but this eroded away sometime in the
      past. This code would still work most of the time because this code runs
      very quickly, but just the right timing conditions are present and IRQ0
      hits in this small, ~30 usecs window, timer irqs stop and the system does
      not boot up. Also, given how early this is during bootup, the hang is
      very deterministic - but it would only occur on certain machines (and
      certain configs).
      
      The fix was quite simple: disable/restore interrupts properly in this
      function. With that in place the test-system now boots up just fine.
      
      (64-bit x86 io_apic_64.c had the same bug.)
      
      Phew! One down, only 1500 other kernel bugs are left ;-)
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      4aae0702
  5. 20 11月, 2007 1 次提交
  6. 22 10月, 2007 1 次提交
  7. 20 10月, 2007 1 次提交
  8. 18 10月, 2007 2 次提交
  9. 11 10月, 2007 2 次提交
  10. 21 8月, 2007 1 次提交
    • L
      ACPI: boot correctly with "nosmp" or "maxcpus=0" · 61ec7567
      Len Brown 提交于
      In MPS mode, "nosmp" and "maxcpus=0" boot a UP kernel with IOAPIC disabled.
      However, in ACPI mode, these parameters didn't completely disable
      the IO APIC initialization code and boot failed.
      
      init/main.c:
      	Disable the IO_APIC if "nosmp" or "maxcpus=0"
      	undefine disable_ioapic_setup() when it doesn't apply.
      
      i386:
      	delete ioapic_setup(), it was a duplicate of parse_noapic()
      	delete undefinition of disable_ioapic_setup()
      
      x86_64:
      	rename disable_ioapic_setup() to parse_noapic() to match i386
      	define disable_ioapic_setup() in header to match i386
      
      http://bugzilla.kernel.org/show_bug.cgi?id=1641Acked-by: NAndi Kleen <ak@suse.de>
      Signed-off-by: NLen Brown <len.brown@intel.com>
      61ec7567
  11. 13 8月, 2007 1 次提交
  12. 22 7月, 2007 1 次提交
    • E
      x86_64: check remote IRR bit before migrating level triggered irq · ef3e28c5
      Eric W. Biederman 提交于
      On x86_64 kernel, level triggered irq migration gets initiated in the
      context of that interrupt(after executing the irq handler) and following
      steps are followed to do the irq migration.
      
      1. mask IOAPIC RTE entry;     // write to IOAPIC RTE
      2. EOI;                       // processor EOI write
      3. reprogram IOAPIC RTE entry // write to IOAPIC RTE with new destination and
                                    // and interrupt vector due to per cpu vector
                                    // allocation.
      4. unmask IOAPIC RTE entry;   // write to IOAPIC RTE
      
      Because of the per cpu vector allocation in x86_64 kernels, when the irq
      migrates to a different cpu, new vector(corresponding to the new cpu) will
      get allocated.
      
      An EOI write to local APIC has a side effect of generating an EOI write for
      level trigger interrupts (normally this is a broadcast to all IOAPICs).
      The EOI broadcast generated as a side effect of EOI write to processor may
      be delayed while the other IOAPIC writes (step 3 and 4) can go through.
      
      Normally, the EOI generated by local APIC for level trigger interrupt
      contains vector number.  The IOAPIC will take this vector number and search
      the IOAPIC RTE entries for an entry with matching vector number and clear
      the remote IRR bit (indicate EOI).  However, if the vector number is
      changed (as in step 3) the IOAPIC will not find the RTE entry when the EOI
      is received later.  This will cause the remote IRR to get stuck causing the
      interrupt hang (no more interrupt from this RTE).
      
      Current x86_64 kernel assumes that remote IRR bit is cleared by the time
      IOAPIC RTE is reprogrammed.  Fix this assumption by checking for remote IRR
      bit and if it still set, delay the irq migration to the next interrupt
      arrival event(hopefully, next time remote IRR bit will get cleared before
      the IOAPIC RTE is reprogrammed).
      
      Initial analysis and patch from Nanhai.
      
      Clean up patch from Suresh.
      
      Rewritten to be less intrusive, and to contain a big fat comment by Eric.
      
      [akpm@linux-foundation.org: fix comments]
      Acked-by: NIngo Molnar <mingo@elte.hu>
      Cc: Nanhai Zou <nanhai.zou@intel.com>
      Acked-by: NSuresh Siddha <suresh.b.siddha@intel.com>
      Cc: Asit Mallick <asit.k.mallick@intel.com>
      Cc: Keith Packard <keith.packard@intel.com>
      Signed-off-by: NEric W. Biederman <ebiederm@xmission.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NAndi Kleen <ak@suse.de>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      ef3e28c5
  13. 27 6月, 2007 1 次提交
  14. 09 5月, 2007 2 次提交
  15. 03 5月, 2007 3 次提交
  16. 05 3月, 2007 1 次提交
  17. 01 3月, 2007 1 次提交
    • E
      [PATCH] x86_64/i386 irq: Fix !CONFIG_SMP compilation · 2ff7354f
      Eric W. Biederman 提交于
      When removing set_native_irq I missed the fact that it was
      called in a couple of places that were compiled even when
      SMP support is disabled.  And since the irq_desc[].affinity
      field only exists in SMP things broke.
      
      Thanks to Simon Arlott <simon@arlott.org> for spotting this.
      
      There are a couple of ways to fix this but the simplest one
      is to just remove the assignments.  The affinity field is only
      used to display a value to the user, and nothing on either i386
      or x86_64 reads it or depends on it being any particlua value,
      so skipping the assignment is safe.  The assignment that
      is being removed is just for the initial affinity value before
      the user explicitly sets it.  The irq_desc array initializes
      this field to CPU_MASK_ALL so the field is initialized to
      a reasonable value in the SMP case without being set.
      Signed-off-by: NEric W. Biederman <ebiederm@xmission.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      2ff7354f
  18. 27 2月, 2007 9 次提交