1. 29 10月, 2017 1 次提交
    • C
      genirq: Document vcpu_info usage for percpu_devid interrupts · 250a53d6
      Christoffer Dall 提交于
      It is currently unclear how to set the VCPU affinity for a percpu_devid
      interrupt , since the Linux irq_data structure describes the state for
      multiple interrupts, one for each physical CPU on the system.  Since
      each such interrupt can be associated with different VCPUs or none at
      all, associating a single VCPU state with such an interrupt does not
      capture the necessary semantics.
      
      The implementers of irq_set_affinity are the Intel and AMD IOMMUs, and
      the ARM GIC irqchip.  The Intel and AMD callers do not appear to use
      percpu_devid interrupts, and the ARM GIC implementation only checks the
      pointer against NULL vs. non-NULL.
      
      Therefore, simply update the function documentation to explain the
      expected use in the context of percpu_devid interrupts, allowing future
      changes or additions to irqchip implementers to do the right thing.
      Signed-off-by: NChristoffer Dall <cdall@linaro.org>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Cc: kvm@vger.kernel.org
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Eric Auger <eric.auger@redhat.com>
      Cc: kvmarm@lists.cs.columbia.edu
      Cc: linux-arm-kernel@lists.infradead.org
      Link: https://lkml.kernel.org/r/1509093281-15225-13-git-send-email-cdall@linaro.org
      250a53d6
  2. 26 9月, 2017 2 次提交
    • T
      genirq: Separate activation and startup · c942cee4
      Thomas Gleixner 提交于
      Activation of an interrupt and startup are currently a combo
      functionlity. That works so far, but upcoming changes require a strict
      separation because the activation can fail in future.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Tested-by: NJuergen Gross <jgross@suse.com>
      Tested-by: NYu Chen <yu.c.chen@intel.com>
      Acked-by: NJuergen Gross <jgross@suse.com>
      Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
      Cc: Tony Luck <tony.luck@intel.com>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Alok Kataria <akataria@vmware.com>
      Cc: Joerg Roedel <joro@8bytes.org>
      Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
      Cc: Steven Rostedt <rostedt@goodmis.org>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Rui Zhang <rui.zhang@intel.com>
      Cc: "K. Y. Srinivasan" <kys@microsoft.com>
      Cc: Arjan van de Ven <arjan@linux.intel.com>
      Cc: Dan Williams <dan.j.williams@intel.com>
      Cc: Len Brown <lenb@kernel.org>
      Link: https://lkml.kernel.org/r/20170913213152.754334077@linutronix.de
      c942cee4
    • T
      genirq/debugfs: Show debug information for all irq descriptors · e0b47794
      Thomas Gleixner 提交于
      Currently the debugfs shows only information about actively used interrupts
      like /proc/irq/ does. That's fine for most cases, but not helpful when
      internals of allocated, but unused interrupt descriptors have to
      debugged. It's also useful to provide information about all descriptors so
      leaks can be debugged in a simpler way.
      
      Move the debugfs registration to the descriptor allocation code.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Tested-by: NJuergen Gross <jgross@suse.com>
      Tested-by: NYu Chen <yu.c.chen@intel.com>
      Acked-by: NJuergen Gross <jgross@suse.com>
      Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
      Cc: Tony Luck <tony.luck@intel.com>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Alok Kataria <akataria@vmware.com>
      Cc: Joerg Roedel <joro@8bytes.org>
      Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
      Cc: Steven Rostedt <rostedt@goodmis.org>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Rui Zhang <rui.zhang@intel.com>
      Cc: "K. Y. Srinivasan" <kys@microsoft.com>
      Cc: Arjan van de Ven <arjan@linux.intel.com>
      Cc: Dan Williams <dan.j.williams@intel.com>
      Cc: Len Brown <lenb@kernel.org>
      Link: https://lkml.kernel.org/r/20170913213152.355525908@linutronix.de
      e0b47794
  3. 25 9月, 2017 1 次提交
  4. 23 8月, 2017 1 次提交
  5. 12 7月, 2017 1 次提交
    • T
      genirq: Keep chip buslock across irq_request/release_resources() · 19d39a38
      Thomas Gleixner 提交于
      Moving the irq_request/release_resources() callbacks out of the spinlocked,
      irq disabled and bus locked region, unearthed an interesting abuse of the
      irq_bus_lock/irq_bus_sync_unlock() callbacks.
      
      The OMAP GPIO driver does merily power management inside of them. The
      irq_request_resources() callback of this GPIO irqchip calls a function
      which reads a GPIO register. That read aborts now because the clock of the
      GPIO block is not magically enabled via the irq_bus_lock() callback.
      
      Move the callbacks under the bus lock again to prevent this. In the
      free_irq() path this requires to drop the bus_lock before calling
      synchronize_irq() and reaquiring it before calling the
      irq_release_resources() callback.
      
      The bus lock can't be held because:
      
         1) The data which has been changed between bus_lock/un_lock is cached in
            the irq chip driver private data and needs to go out to the irq chip
            via the slow bus (usually SPI or I2C) before calling
            synchronize_irq().
      
            That's the reason why this bus_lock/unlock magic exists in the first
            place, as you cannot do SPI/I2C transactions while holding desc->lock
            with interrupts disabled.
      
         2) synchronize_irq() will actually deadlock, if there is a handler on
            flight. These chips use threaded handlers for obvious reasons, as
            they allow to do SPI/I2C communication. When the threaded handler
            returns then bus_lock needs to be taken in irq_finalize_oneshot() as
            we need to talk to the actual irq chip once more. After that the
            threaded handler is marked done, which makes synchronize_irq() return.
      
            So if we hold bus_lock accross the synchronize_irq() call, the
            handler cannot mark itself done because it blocks on the bus
            lock. That in turn makes synchronize_irq() wait forever on the
            threaded handler to complete....
      
      Add the missing unlock of desc->request_mutex in the error path of
      __free_irq() and add a bunch of comments to explain the locking and
      protection rules.
      
      Fixes: 46e48e25 ("genirq: Move irq resource handling out of spinlocked region")
      Reported-and-tested-by: NSebastian Reichel <sebastian.reichel@collabora.co.uk>
      Reported-and-tested-by: NTony Lindgren <tony@atomide.com>
      Reported-by: NPavel Machek <pavel@ucw.cz>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Not-longer-ranted-at-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Cc: Linus Walleij <linus.walleij@linaro.org>
      Cc: Grygorii Strashko <grygorii.strashko@ti.com>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      19d39a38
  6. 07 7月, 2017 1 次提交
    • D
      genirq: Allow to pass the IRQF_TIMER flag with percpu irq request · c80081b9
      Daniel Lezcano 提交于
      The irq timings infrastructure tracks when interrupts occur in order to
      statistically predict te next interrupt event.
      
      There is no point to track timer interrupts and try to predict them because
      the next expiration time is already known. This can be avoided via the
      IRQF_TIMER flag which is passed by timer drivers in request_irq(). It marks
      the interrupt as timer based which alloes to ignore these interrupts in the
      timings code.
      
      Per CPU interrupts which are requested via request_percpu_+irq() have no
      flag argument, so marking per cpu timer interrupts is not possible and they
      get tracked pointlessly.
      
      Add __request_percpu_irq() as a variant of request_percpu_irq() with a
      flags argument and make request_percpu_irq() an inline wrapper passing
      flags = 0.
      
      The flag parameter is restricted to IRQF_TIMER as all other IRQF_ flags
      make no sense for per cpu interrupts.
      
      The next step is to convert all existing users of request_percpu_irq() and
      then remove the wrapper and the underscores.
      
      [ tglx: Massaged changelog ]
      Signed-off-by: NDaniel Lezcano <daniel.lezcano@linaro.org>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: peterz@infradead.org
      Cc: nicolas.pitre@linaro.org
      Cc: vincent.guittot@linaro.org
      Cc: rafael@kernel.org
      Link: http://lkml.kernel.org/r/1499344144-3964-1-git-send-email-daniel.lezcano@linaro.org
      c80081b9
  7. 04 7月, 2017 4 次提交
  8. 24 6月, 2017 1 次提交
    • D
      genirq/timings: Add infrastructure to track the interrupt timings · b2d3d61a
      Daniel Lezcano 提交于
      The interrupt framework gives a lot of information about each interrupt. It
      does not keep track of when those interrupts occur though, which is a
      prerequisite for estimating the next interrupt arrival for power management
      purposes.
      
      Add a mechanism to record the timestamp for each interrupt occurrences in a
      per-CPU circular buffer to help with the prediction of the next occurrence
      using a statistical model.
      
      Each CPU can store up to IRQ_TIMINGS_SIZE events <irq, timestamp>, the
      current value of IRQ_TIMINGS_SIZE is 32.
      
      Each event is encoded into a single u64, where the high 48 bits are used
      for the timestamp and the low 16 bits are for the irq number.
      
      A static key is introduced so when the irq prediction is switched off at
      runtime, the overhead is near to zero.
      
      It results in most of the code in internals.h for inline reasons and a very
      few in the new file timings.c. The latter will contain more in the next patch
      which will provide the statistical model for the next event prediction.
      Signed-off-by: NDaniel Lezcano <daniel.lezcano@linaro.org>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Acked-by: NNicolas Pitre <nicolas.pitre@linaro.org>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Hannes Reinecke <hare@suse.com>
      Cc: Vincent Guittot <vincent.guittot@linaro.org>
      Cc: "Rafael J . Wysocki" <rafael@kernel.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Bjorn Helgaas <bhelgaas@google.com>
      Link: http://lkml.kernel.org/r/1498227072-5980-1-git-send-email-daniel.lezcano@linaro.org
      b2d3d61a
  9. 23 6月, 2017 6 次提交
    • T
      genirq: Add force argument to irq_startup() · 4cde9c6b
      Thomas Gleixner 提交于
      In order to handle managed interrupts gracefully on irq_startup() so they
      won't lose their assigned affinity, it's necessary to allow startups which
      keep the interrupts in managed shutdown state, if none of the assigend CPUs
      is online. This allows drivers to request interrupts w/o the CPUs being
      online, which avoid online/offline churn in drivers.
      
      Add a force argument which can override that decision and let only
      request_irq() and enable_irq() allow the managed shutdown
      handling. enable_irq() is required, because the interrupt might be
      requested with IRQF_NOAUTOEN and enable_irq() invokes irq_startup() which
      would then wreckage the assignment again. All other callers force startup
      and potentially break the assigned affinity.
      
      No functional change as this only adds the function argument.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Michael Ellerman <mpe@ellerman.id.au>
      Cc: Keith Busch <keith.busch@intel.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Christoph Hellwig <hch@lst.de>
      Link: http://lkml.kernel.org/r/20170619235447.112094565@linutronix.de
      4cde9c6b
    • C
      genirq: Move pending helpers to internal.h · 137221df
      Christoph Hellwig 提交于
      So that the affinity code can reuse them.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Michael Ellerman <mpe@ellerman.id.au>
      Cc: Keith Busch <keith.busch@intel.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Link: http://lkml.kernel.org/r/20170619235445.109426284@linutronix.de
      137221df
    • T
      genirq: Move initial affinity setup to irq_startup() · 2e051552
      Thomas Gleixner 提交于
      The startup vs. setaffinity ordering of interrupts depends on the
      IRQF_NOAUTOEN flag. Chained interrupts are not getting any affinity
      assignment at all.
      
      A regular interrupt is started up and then the affinity is set. A
      IRQF_NOAUTOEN marked interrupt is not started up, but the affinity is set
      nevertheless.
      
      Move the affinity setup to startup_irq() so the ordering is always the same
      and chained interrupts get the proper default affinity assigned as well.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Michael Ellerman <mpe@ellerman.id.au>
      Cc: Keith Busch <keith.busch@intel.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Christoph Hellwig <hch@lst.de>
      Link: http://lkml.kernel.org/r/20170619235445.020534783@linutronix.de
      2e051552
    • T
      genirq: Rename setup_affinity() to irq_setup_affinity() · 43564bd9
      Thomas Gleixner 提交于
      Rename it with a proper irq_ prefix and make it available for other files
      in the core code. Preparatory patch for moving the irq affinity setup
      around.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Michael Ellerman <mpe@ellerman.id.au>
      Cc: Keith Busch <keith.busch@intel.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Christoph Hellwig <hch@lst.de>
      Link: http://lkml.kernel.org/r/20170619235444.928501004@linutronix.de
      43564bd9
    • T
      genirq: Remove mask argument from setup_affinity() · cba4235e
      Thomas Gleixner 提交于
      No point to have this alloc/free dance of cpumasks. Provide a static mask
      for setup_affinity() and protect it proper.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Michael Ellerman <mpe@ellerman.id.au>
      Cc: Keith Busch <keith.busch@intel.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Christoph Hellwig <hch@lst.de>
      Link: http://lkml.kernel.org/r/20170619235444.851571573@linutronix.de
      cba4235e
    • T
      genirq/debugfs: Add proper debugfs interface · 087cdfb6
      Thomas Gleixner 提交于
      Debugging (hierarchical) interupt domains is tedious as there is no
      information about the hierarchy and no information about states of
      interrupts in the various domain levels.
      
      Add a debugfs directory 'irq' and subdirectories 'domains' and 'irqs'.
      
      The domains directory contains the domain files. The content is information
      about the domain. If the domain is part of a hierarchy then the parent
      domains are printed as well.
      
      # ls /sys/kernel/debug/irq/domains/
      default     INTEL-IR-2	    INTEL-IR-MSI-2  IO-APIC-IR-2  PCI-MSI
      DMAR-MSI    INTEL-IR-3	    INTEL-IR-MSI-3  IO-APIC-IR-3  unknown-1
      INTEL-IR-0  INTEL-IR-MSI-0  IO-APIC-IR-0    IO-APIC-IR-4  VECTOR
      INTEL-IR-1  INTEL-IR-MSI-1  IO-APIC-IR-1    PCI-HT
      
      # cat /sys/kernel/debug/irq/domains/VECTOR 
      name:   VECTOR
       size:   0
       mapped: 216
       flags:  0x00000041
      
      # cat /sys/kernel/debug/irq/domains/IO-APIC-IR-0 
      name:   IO-APIC-IR-0
       size:   24
       mapped: 19
       flags:  0x00000041
       parent: INTEL-IR-3
          name:   INTEL-IR-3
           size:   65536
           mapped: 167
           flags:  0x00000041
           parent: VECTOR
              name:   VECTOR
               size:   0
               mapped: 216
               flags:  0x00000041
      
      Unfortunately there is no per cpu information about the VECTOR domain (yet).
      
      The irqs directory contains detailed information about mapped interrupts.
      
      # cat /sys/kernel/debug/irq/irqs/3
      handler:  handle_edge_irq
      status:   0x00004000
      istate:   0x00000000
      ddepth:   1
      wdepth:   0
      dstate:   0x01018000
                  IRQD_IRQ_DISABLED
                  IRQD_SINGLE_TARGET
                  IRQD_MOVE_PCNTXT
      node:     0
      affinity: 0-143
      effectiv: 0
      pending:  
      domain:  IO-APIC-IR-0
       hwirq:   0x3
       chip:    IR-IO-APIC
        flags:   0x10
                   IRQCHIP_SKIP_SET_WAKE
       parent:
          domain:  INTEL-IR-3
           hwirq:   0x20000
           chip:    INTEL-IR
            flags:   0x0
           parent:
              domain:  VECTOR
               hwirq:   0x3
               chip:    APIC
                flags:   0x0
      
      This was developed to simplify the debugging of the managed affinity
      changes.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Acked-by: NMarc Zyngier <marc.zyngier@arm.com>
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: Michael Ellerman <mpe@ellerman.id.au>
      Cc: Keith Busch <keith.busch@intel.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Christoph Hellwig <hch@lst.de>
      Link: http://lkml.kernel.org/r/20170619235444.537566163@linutronix.deSigned-off-by: NThomas Gleixner <tglx@linutronix.de>
      087cdfb6
  10. 13 6月, 2017 1 次提交
  11. 04 6月, 2017 2 次提交
  12. 19 4月, 2017 2 次提交
  13. 15 4月, 2017 2 次提交
  14. 02 3月, 2017 2 次提交
  15. 28 2月, 2017 1 次提交
  16. 08 11月, 2016 1 次提交
    • T
      genirq: Use irq type from irqdata instead of irqdesc · 7ee7e87d
      Thomas Gleixner 提交于
      The type flags in the irq descriptor are there for historical reasons and
      only updated via irq_modify_status() or irq_set_type(). Both functions also
      update the type flags in irqdata. __setup_irq() is the only left over user
      of the type flags in the irq descriptor.
      
      If __setup_irq() is called with empty irq type flags, then the type flags
      are retrieved from irqdata. If an interrupt is shared, then the type flags
      are compared with the type flags stored in the irq descriptor. 
      
      On x86 the ioapic does not have a irq_set_type() callback because the type
      is defined in the BIOS tables and cannot be changed. The type is stored in
      irqdata at setup time without updating the type data in the irq
      descriptor. As a result the comparison described above fails.
      
      There is no point in updating the irq descriptor flags because the only
      relevant storage is irqdata. Use the type flags from irqdata for both
      retrieval and comparison in __setup_irq() instead.
      
      Aside of that the print out in case of non matching type flags has the old
      and new type flags arguments flipped. Fix that as well.
      
      For correctness sake the flags stored in the irq descriptor should be
      removed, but this is beyond the scope of this bugfix and will be done in a
      later patch.
      
      Fixes: 4b357dae ("genirq: Look-up trigger type if not specified by caller")
      Reported-and-tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Jon Hunter <jonathanh@nvidia.com>
      Cc: stable@vger.kernel.org
      Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1611072020360.3501@nanosSigned-off-by: NThomas Gleixner <tglx@linutronix.de>
      7ee7e87d
  17. 21 10月, 2016 1 次提交
  18. 06 9月, 2016 1 次提交
  19. 22 8月, 2016 1 次提交
  20. 04 7月, 2016 2 次提交
  21. 13 6月, 2016 3 次提交
    • J
      genirq: Add runtime power management support for IRQ chips · be45beb2
      Jon Hunter 提交于
      Some IRQ chips may be located in a power domain outside of the CPU
      subsystem and hence will require device specific runtime power
      management. In order to support such IRQ chips, add a pointer for a
      device structure to the irq_chip structure, and if this pointer is
      populated by the IRQ chip driver and CONFIG_PM is selected in the kernel
      configuration, then the pm_runtime_get/put APIs for this chip will be
      called when an IRQ is requested/freed, respectively.
      Reviewed-by: NKevin Hilman <khilman@baylibre.com>
      Signed-off-by: NJon Hunter <jonathanh@nvidia.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      be45beb2
    • M
      genirq: Look-up percpu trigger type if not specified by caller · f35ad083
      Marc Zyngier 提交于
      As we now do for non-percpu interrupt, perform a lookup of the
      interrupt trigger if the user doesn't supply one. The difference
      here is that we can only do it at enable time (trigger configuration
      can be per-cpu as well).
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      f35ad083
    • J
      genirq: Look-up trigger type if not specified by caller · 4b357dae
      Jon Hunter 提交于
      For some devices the IRQ trigger type for a device is read from
      firmware, such as device-tree. The IRQ trigger type is typically read
      when the mapping for IRQ is created, which is before the IRQ is
      requested. Hence, the IRQ trigger type is programmed when mapping the
      IRQ and not when requesting the IRQ.
      
      Although this works for most cases, in order to support IRQ chips which
      require runtime power management, which may not be accessible prior
      to requesting the IRQ, it is desirable to look-up the IRQ trigger type
      when it is requested. Therefore, if the IRQ trigger type is not
      specified when __setup_irq() is called, look-up the saved IRQ trigger
      type. This will allow us to defer the programming of the trigger type
      from when the IRQ is mapped to when it is actually requested.
      Signed-off-by: NJon Hunter <jonathanh@nvidia.com>
      Reviewed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      4b357dae
  22. 11 5月, 2016 1 次提交
    • J
      genirq: Ensure IRQ descriptor is valid when setting-up the IRQ · 9b5d585d
      Jon Hunter 提交于
      In the function, setup_irq(), we don't check that the descriptor
      returned from irq_to_desc() is valid before we start using it. For
      example chip_bus_lock() called from setup_irq(), assumes that the
      descriptor pointer is valid and doesn't check before dereferencing it.
      
      In many other functions including setup/free_percpu_irq() we do check
      that the descriptor returned is not NULL and therefore add the same test
      to setup_irq() to ensure the descriptor returned is valid.
      Signed-off-by: NJon Hunter <jonathanh@nvidia.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      9b5d585d
  23. 23 3月, 2016 1 次提交
  24. 09 3月, 2016 1 次提交
    • C
      x86/ACPI/PCI: Recognize that Interrupt Line 255 means "not connected" · e237a551
      Chen Fan 提交于
      Per the x86-specific footnote to PCI spec r3.0, sec 6.2.4, the value 255 in
      the Interrupt Line register means "unknown" or "no connection."
      Previously, when we couldn't derive an IRQ from the _PRT, we fell back to
      using the value from Interrupt Line as an IRQ.  It's questionable whether
      we should do that at all, but the spec clearly suggests we shouldn't do it
      for the value 255 on x86.
      
      Calling request_irq() with IRQ 255 may succeed, but the driver won't
      receive any interrupts.  Or, if IRQ 255 is shared with another device, it
      may succeed, and the driver's ISR will be called at random times when the
      *other* device interrupts.  Or it may fail if another device is using IRQ
      255 with incompatible flags.  What we *want* is for request_irq() to fail
      predictably so the driver can fall back to polling.
      
      On x86, assume 255 in the Interrupt Line means the INTx line is not
      connected.  In that case, set dev->irq to IRQ_NOTCONNECTED so request_irq()
      will fail gracefully with -ENOTCONN.
      
      We found this problem on a system where Secure Boot firmware assigned
      Interrupt Line 255 to an i801_smbus device and another device was already
      using MSI-X IRQ 255.  This was in v3.10, where i801_probe() fails if
      request_irq() fails:
      
        i801_smbus 0000:00:1f.3: enabling device (0140 -> 0143)
        i801_smbus 0000:00:1f.3: can't derive routing for PCI INT C
        i801_smbus 0000:00:1f.3: PCI INT C: no GSI
        genirq: Flags mismatch irq 255. 00000080 (i801_smbus) vs. 00000000 (megasa)
        CPU: 0 PID: 2487 Comm: kworker/0:1 Not tainted 3.10.0-229.el7.x86_64 #1
        Hardware name: FUJITSU PRIMEQUEST 2800E2/D3736, BIOS PRIMEQUEST 2000 Serie5
        Call Trace:
          dump_stack+0x19/0x1b
          __setup_irq+0x54a/0x570
          request_threaded_irq+0xcc/0x170
          i801_probe+0x32f/0x508 [i2c_i801]
          local_pci_probe+0x45/0xa0
        i801_smbus 0000:00:1f.3: Failed to allocate irq 255: -16
        i801_smbus: probe of 0000:00:1f.3 failed with error -16
      
      After aeb8a3d1 ("i2c: i801: Check if interrupts are disabled"),
      i801_probe() will fall back to polling if request_irq() fails.  But we
      still need this patch because request_irq() may succeed or fail depending
      on other devices in the system.  If request_irq() fails, i801_smbus will
      work by falling back to polling, but if it succeeds, i801_smbus won't work
      because it expects interrupts that it may not receive.
      Signed-off-by: NChen Fan <chen.fan.fnst@cn.fujitsu.com>
      Acked-by: NThomas Gleixner <tglx@linutronix.de>
      Acked-by: NBjorn Helgaas <bhelgaas@google.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      e237a551