13 Dec, 2014

1 commit

  • Since the rework of the sparse interrupt code to actually free the
    unused interrupt descriptors there exists a race between the /proc
    interfaces to the irq subsystem and the code which frees the interrupt
    descriptor.

    CPU0 CPU1
    show_interrupts()
    desc = irq_to_desc(X);
    free_desc(desc)
    remove_from_radix_tree();
    kfree(desc);
    raw_spinlock_irq(&desc->lock);

    /proc/interrupts is the only interface which can actively corrupt
    kernel memory via the lock access. /proc/stat can only read from freed
    memory. Extremly hard to trigger, but possible.

    The interfaces in /proc/irq/N/ are not affected by this because the
    removal of the proc file is serialized in procfs against concurrent
    readers/writers. The removal happens before the descriptor is freed.

    For architectures which have CONFIG_SPARSE_IRQ=n this is a non issue
    as the descriptor is never freed. It's merely cleared out with the irq
    descriptor lock held. So any concurrent proc access will either see
    the old correct value or the cleared out ones.

    Protect the lookup and access to the irq descriptor in
    show_interrupts() with the sparse_irq_lock.

    Provide kstat_irqs_usr() which is protecting the lookup and access
    with sparse_irq_lock and switch /proc/stat to use it.

    Document the existing kstat_irqs interfaces so it's clear that the
    caller needs to take care about protection. The users of these
    interfaces are either not affected due to SPARSE_IRQ=n or already
    protected against removal.

    Fixes: 1f5a5b87f78f "genirq: Implement a sane sparse_irq allocator"
    Signed-off-by: Thomas Gleixner
    Cc: stable@vger.kernel.org

    Thomas Gleixner
     

01 Sep, 2014

3 commits

  • Currently we suspend wakeup interrupts by lazy disabling them and
    check later whether the interrupt has fired, but that's not sufficient
    for suspend to idle as there is no way to check that once we
    transitioned into the CPU idle state.

    So we change the mechanism in the following way:

    1) Leave the wakeup interrupts enabled across suspend

    2) Add a check to irq_may_run() which is called at the beginning of
    each flow handler whether the interrupt is an armed wakeup source.

    This check is basically free as it just extends the existing check
    for IRQD_IRQ_INPROGRESS. So no new conditional in the hot path.

    If the IRQD_WAKEUP_ARMED flag is set, then the interrupt is
    disabled, marked as pending/suspended and the pm core is notified
    about the wakeup event.

    Signed-off-by: Thomas Gleixner
    [ rjw: syscore.c and put irq_pm_check_wakeup() into pm.c ]
    Signed-off-by: Rafael J. Wysocki

    Thomas Gleixner
     
  • Account the IRQF_NO_SUSPEND and IRQF_RESUME_EARLY actions on shared
    interrupt lines and yell loudly if there is a mismatch.

    Signed-off-by: Thomas Gleixner
    Signed-off-by: Rafael J. Wysocki

    Thomas Gleixner
     
  • No functional change. Preparatory patch for cleaning up the suspend
    abort functionality. Update the comments while at it.

    Signed-off-by: Thomas Gleixner
    Signed-off-by: Rafael J. Wysocki

    Thomas Gleixner
     

27 May, 2014

1 commit

  • Signed-off-by: Jiang Liu
    Cc: Konrad Rzeszutek Wilk
    Cc: Tony Luck
    Cc: Joerg Roedel
    Cc: Paul Gortmaker
    Cc: Greg Kroah-Hartman
    Cc: Benjamin Herrenschmidt
    Cc: Grant Likely
    Cc: Rafael J. Wysocki
    Cc: Bjorn Helgaas
    Cc: Randy Dunlap
    Cc: Yinghai Lu
    Cc: Jiri Kosina
    Link: http://lkml.kernel.org/r/1401178092-1228-3-git-send-email-jiang.liu@linux.intel.com
    Signed-off-by: Thomas Gleixner

    Jiang Liu
     

16 May, 2014

1 commit


14 Mar, 2014

1 commit

  • The flag is necessary for interrupt chips which require an ACK/EOI
    after the handler has run. In case of threaded handlers this needs to
    happen after the threaded handler has completed before the unmask of
    the interrupt.

    The flag is only unseful in combination with the handle_fasteoi_irq
    flow control handler.

    It can be combined with the flag IRQCHIP_EOI_IF_HANDLED, so the EOI is
    not issued when the interrupt is disabled or in progress.

    Tested-by: Hans de Goede
    Reviewed-by: Hans de Goede
    Cc: linux-arm-kernel@lists.infradead.org
    Cc: linux-sunxi@googlegroups.com
    Cc: Maxime Ripard
    Link: http://lkml.kernel.org/r/1394733834-26839-2-git-send-email-hdegoede@redhat.com
    Signed-off-by: Thomas Gleixner

    Thomas Gleixner
     

05 Mar, 2014

1 commit


20 Feb, 2014

1 commit

  • In course of the sdhci/sdio discussion with Russell about killing the
    sdio kthread hackery we discovered the need to be able to wake an
    interrupt thread from software.

    The rationale for this is, that sdio hardware can lack proper
    interrupt support for certain features. So the driver needs to poll
    the status registers, but at the same time it needs to be woken up by
    an hardware interrupt.

    To be able to get rid of the home brewn kthread construct of sdio we
    need a way to wake an irq thread independent of an actual hardware
    interrupt.

    Provide an irq_wake_thread() function which wakes up the thread which
    is associated to a given dev_id. This allows sdio to invoke the irq
    thread from the hardware irq handler via the IRQ_WAKE_THREAD return
    value and provides a possibility to wake it via a timer for the
    polling scenarios. That allows to simplify the sdio logic
    significantly.

    Signed-off-by: Thomas Gleixner
    Cc: Russell King
    Cc: Chris Ball
    Acked-by: Peter Zijlstra
    Link: http://lkml.kernel.org/r/20140215003823.772565780@linutronix.de

    Thomas Gleixner
     

25 May, 2012

1 commit

  • All invocations of chip->irq_set_affinity() are doing the same return
    value checks. Let them all use a common function.

    [ tglx: removed the silly likely while at it ]

    Signed-off-by: Jiang Liu
    Cc: Jiang Liu
    Cc: Keping Chen
    Link: http://lkml.kernel.org/r/1333120296-13563-3-git-send-email-jiang.liu@huawei.com
    Signed-off-by: Thomas Gleixner

    Jiang Liu
     

13 Mar, 2012

1 commit


10 Mar, 2012

1 commit

  • Currently IRQTF_DIED flag is set when a IRQ thread handler calls do_exit()
    But also PF_EXITING per process flag gets set when a thread exits. This
    fix eliminates the duplicate by using PF_EXITING flag.

    Also, there is a race condition in exit_irq_thread(). In case a thread's
    bit is cleared in desc->threads_oneshot (and the IRQ line gets unmasked),
    but before IRQTF_DIED flag is set, a new interrupt might come in and set
    just cleared bit again, this time forever. This fix throws IRQTF_DIED flag
    away, eliminating the race as a result.

    [ tglx: Test THREAD_EXITING first as suggested by Oleg ]

    Reported-by: Oleg Nesterov
    Signed-off-by: Alexander Gordeev
    Link: http://lkml.kernel.org/r/20120309135958.GD2114@dhcp-26-207.brq.redhat.com
    Signed-off-by: Thomas Gleixner

    Alexander Gordeev
     

15 Feb, 2012

1 commit

  • An interrupt might be pending when irq_startup() is called, but the
    startup code does not invoke the resend logic. In some cases this
    prevents the device from issuing another interrupt which renders the
    device non functional.

    Call the resend function in irq_startup() to keep things going.

    Reported-and-tested-by: Russell King
    Cc: stable@vger.kernel.org
    Signed-off-by: Thomas Gleixner

    Thomas Gleixner
     

13 Jan, 2012

1 commit


03 Oct, 2011

1 commit

  • The ARM GIC interrupt controller offers per CPU interrupts (PPIs),
    which are usually used to connect local timers to each core. Each CPU
    has its own private interface to the GIC, and only sees the PPIs that
    are directly connect to it.

    While these timers are separate devices and have a separate interrupt
    line to a core, they all use the same IRQ number.

    For these devices, request_irq() is not the right API as it assumes
    that an IRQ number is visible by a number of CPUs (through the
    affinity setting), but makes it very awkward to express that an IRQ
    number can be handled by all CPUs, and yet be a different interrupt
    line on each CPU, requiring a different dev_id cookie to be passed
    back to the handler.

    The *_percpu_irq() functions is designed to overcome these
    limitations, by providing a per-cpu dev_id vector:

    int request_percpu_irq(unsigned int irq, irq_handler_t handler,
    const char *devname, void __percpu *percpu_dev_id);
    void free_percpu_irq(unsigned int, void __percpu *);
    int setup_percpu_irq(unsigned int irq, struct irqaction *new);
    void remove_percpu_irq(unsigned int irq, struct irqaction *act);
    void enable_percpu_irq(unsigned int irq);
    void disable_percpu_irq(unsigned int irq);

    The API has a number of limitations:
    - no interrupt sharing
    - no threading
    - common handler across all the CPUs

    Once the interrupt is requested using setup_percpu_irq() or
    request_percpu_irq(), it must be enabled by each core that wishes its
    local interrupt to be delivered.

    Based on an initial patch by Thomas Gleixner.

    Signed-off-by: Marc Zyngier
    Cc: linux-arm-kernel@lists.infradead.org
    Link: http://lkml.kernel.org/r/1316793788-14500-2-git-send-email-marc.zyngier@arm.com
    Signed-off-by: Thomas Gleixner

    Marc Zyngier
     

29 Mar, 2011

1 commit


28 Mar, 2011

1 commit


26 Feb, 2011

1 commit

  • Add a commandline parameter "threadirqs" which forces all interrupts except
    those marked IRQF_NO_THREAD to run threaded. That's mostly a debug option to
    allow retrieving better debug data from crashing interrupt handlers. If
    "threadirqs" is not enabled on the kernel command line, then there is no
    impact in the interrupt hotpath.

    Architecture code needs to select CONFIG_IRQ_FORCED_THREADING after
    marking the interrupts which cant be threaded IRQF_NO_THREAD. All
    interrupts which have IRQF_TIMER set are implict marked
    IRQF_NO_THREAD. Also all PER_CPU interrupts are excluded.

    Forced threading hard interrupts also forces all soft interrupt
    handling into thread context.

    When enabled it might slow down things a bit, but for debugging problems in
    interrupt code it's a reasonable penalty as it does not immediately
    crash and burn the machine when an interrupt handler is buggy.

    Some test results on a Core2Duo machine:

    Cache cold run of:
    # time git grep irq_desc

    non-threaded threaded
    real 1m18.741s 1m19.061s
    user 0m1.874s 0m1.757s
    sys 0m5.843s 0m5.427s

    # iperf -c server
    non-threaded
    [ 3] 0.0-10.0 sec 1.09 GBytes 933 Mbits/sec
    [ 3] 0.0-10.0 sec 1.09 GBytes 934 Mbits/sec
    [ 3] 0.0-10.0 sec 1.09 GBytes 933 Mbits/sec
    threaded
    [ 3] 0.0-10.0 sec 1.09 GBytes 939 Mbits/sec
    [ 3] 0.0-10.0 sec 1.09 GBytes 934 Mbits/sec
    [ 3] 0.0-10.0 sec 1.09 GBytes 937 Mbits/sec

    Signed-off-by: Thomas Gleixner
    Cc: Peter Zijlstra
    LKML-Reference:

    Thomas Gleixner
     

19 Feb, 2011

22 commits