Skip to content
  • Andriy Gapon's avatar
    add support for marking interrupt handlers as suspended · 82a5a275
    Andriy Gapon authored
    The goal of this change is to fix a problem with PCI shared interrupts
    during suspend and resume.
    
    I have observed a couple of variations of the following scenario.
    Devices A and B are on the same PCI bus and share the same interrupt.
    Device A's driver is suspended first and the device is powered down.
    Device B generates an interrupt. Interrupt handlers of both drivers are
    called. Device A's interrupt handler accesses registers of the powered
    down device and gets back bogus values (I assume all 0xff). That data is
    interpreted as interrupt status bits, etc. So, the interrupt handler
    gets confused and may produce some noise or enter an infinite loop, etc.
    
    This change affects only PCI devices.  The pci(4) bus driver marks a
    child's interrupt handler as suspended after the child's suspend method
    is called and before the device is powered down.  This is done only for
    traditional PCI interrupts, because only they can be shared.
    
    At the moment the change is only for x86.
    
    Notable changes in core subsystems / interfaces:
    - BUS_SUSPEND_INTR and BUS_RESUME_INTR methods are added to bus
      interface along with convenience functions bus_suspend_intr and
      bus_resume_intr;
    - rman_set_irq_cookie and rman_get_irq_cookie functions are added to
      provide a way to associate an interrupt resource with an interrupt
      cookie;
    - intr_event_suspend_handler and intr_event_resume_handler functions
      are added to the MI interrupt handler interface.
    
    I added two new interrupt handler flags, IH_SUSP and IH_CHANGED, to
    implement the new intr_event functions.  IH_SUSP marks a suspended
    interrupt handler.  IH_CHANGED is used to implement a barrier that
    ensures that a change to the interrupt handler's state is visible
    to future interrupts.
    While there, I fixed some whitespace issues in comments and changed a
    couple of logically boolean variables to be bool.
    
    MFC after:	1 month (maybe)
    Differential Revision: https://reviews.freebsd.org/D15755
    82a5a275