lkml.org 
[lkml]   [2017]   [Jul]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [GIT pull] irq updates for 4.13
    Sebastian,

    On Tue, 11 Jul 2017, Thomas Gleixner wrote:
    > On Tue, 11 Jul 2017, Sebastian Reichel wrote:
    > So this crashes in do_raw_spin_unlock_irqrestore() !?! I just have to
    > wonder how the raw_spin_lock() succeeded. That does not make any sense.

    can you please apply the patch below on top of 4.12? It's a backport
    isolating the resource request changes.

    Thanks,

    tglx

    8<----------------------
    --- a/kernel/irq/manage.c
    +++ b/kernel/irq/manage.c
    @@ -1198,6 +1198,18 @@ static int
    if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)
    new->flags &= ~IRQF_ONESHOT;

    + mutex_lock(&desc->request_mutex);
    + if (!desc->action) {
    + ret = irq_request_resources(desc);
    + if (ret) {
    + pr_err("Failed to request resources for %s (irq %d) on irqchip %s\n",
    + new->name, irq, desc->irq_data.chip->name);
    + goto out_mutex;
    + }
    + }
    +
    + chip_bus_lock(desc);
    +
    /*
    * The following block of code has to be executed atomically
    */
    @@ -1298,13 +1310,6 @@ static int
    }

    if (!shared) {
    - ret = irq_request_resources(desc);
    - if (ret) {
    - pr_err("Failed to request resources for %s (irq %d) on irqchip %s\n",
    - new->name, irq, desc->irq_data.chip->name);
    - goto out_mask;
    - }
    -
    init_waitqueue_head(&desc->wait_for_threads);

    /* Setup the type (level, edge polarity) if configured: */
    @@ -1312,10 +1317,8 @@ static int
    ret = __irq_set_trigger(desc,
    new->flags & IRQF_TRIGGER_MASK);

    - if (ret) {
    - irq_release_resources(desc);
    + if (ret)
    goto out_mask;
    - }
    }

    desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \
    @@ -1373,6 +1376,8 @@ static int
    }

    raw_spin_unlock_irqrestore(&desc->lock, flags);
    + chip_bus_sync_unlock(desc);
    + mutex_unlock(&desc->request_mutex);

    /*
    * Strictly no need to wake it up, but hung_task complains
    @@ -1402,6 +1407,13 @@ static int

    out_mask:
    raw_spin_unlock_irqrestore(&desc->lock, flags);
    + chip_bus_sync_unlock(desc);
    + if (!desc->action)
    + irq_release_resources(desc);
    +
    +out_mutex:
    + mutex_unlock(&desc->request_mutex);
    +
    free_cpumask_var(mask);

    out_thread:
    @@ -1443,9 +1455,7 @@ int setup_irq(unsigned int irq, struct i
    if (retval < 0)
    return retval;

    - chip_bus_lock(desc);
    retval = __setup_irq(irq, desc, act);
    - chip_bus_sync_unlock(desc);

    if (retval)
    irq_chip_pm_put(&desc->irq_data);
    @@ -1469,6 +1479,7 @@ static struct irqaction *__free_irq(unsi
    if (!desc)
    return NULL;

    + mutex_lock(&desc->request_mutex);
    chip_bus_lock(desc);
    raw_spin_lock_irqsave(&desc->lock, flags);

    @@ -1501,7 +1512,6 @@ static struct irqaction *__free_irq(unsi
    if (!desc->action) {
    irq_settings_clr_disable_unlazy(desc);
    irq_shutdown(desc);
    - irq_release_resources(desc);
    }

    #ifdef CONFIG_SMP
    @@ -1543,6 +1553,11 @@ static struct irqaction *__free_irq(unsi
    }
    }

    + if (!desc->action)
    + irq_release_resources(desc);
    +
    + mutex_unlock(&desc->request_mutex);
    +
    irq_chip_pm_put(&desc->irq_data);
    module_put(desc->owner);
    kfree(action->secondary);
    @@ -1699,9 +1714,7 @@ int request_threaded_irq(unsigned int ir
    return retval;
    }

    - chip_bus_lock(desc);
    retval = __setup_irq(irq, desc, action);
    - chip_bus_sync_unlock(desc);

    if (retval) {
    irq_chip_pm_put(&desc->irq_data);
    @@ -1949,9 +1962,7 @@ int setup_percpu_irq(unsigned int irq, s
    if (retval < 0)
    return retval;

    - chip_bus_lock(desc);
    retval = __setup_irq(irq, desc, act);
    - chip_bus_sync_unlock(desc);

    if (retval)
    irq_chip_pm_put(&desc->irq_data);
    @@ -2005,9 +2016,7 @@ int request_percpu_irq(unsigned int irq,
    return retval;
    }

    - chip_bus_lock(desc);
    retval = __setup_irq(irq, desc, action);
    - chip_bus_sync_unlock(desc);

    if (retval) {
    irq_chip_pm_put(&desc->irq_data);
    --- a/include/linux/irqdesc.h
    +++ b/include/linux/irqdesc.h
    @@ -3,6 +3,7 @@

    #include <linux/rcupdate.h>
    #include <linux/kobject.h>
    +#include <linux/mutex.h>

    /*
    * Core internal functions to deal with irq descriptors
    @@ -45,6 +46,7 @@ struct pt_regs;
    * IRQF_FORCE_RESUME set
    * @rcu: rcu head for delayed free
    * @kobj: kobject used to represent this struct in sysfs
    + * @request_mutex: mutex to protect request/free before locking desc->lock
    * @dir: /proc/irq/ procfs entry
    * @name: flow handler name for /proc/interrupts output
    */
    @@ -92,6 +94,7 @@ struct irq_desc {
    struct rcu_head rcu;
    struct kobject kobj;
    #endif
    + struct mutex request_mutex;
    int parent_irq;
    struct module *owner;
    const char *name;
    --- a/kernel/irq/irqdesc.c
    +++ b/kernel/irq/irqdesc.c
    @@ -359,6 +359,7 @@ static struct irq_desc *alloc_desc(int i

    raw_spin_lock_init(&desc->lock);
    lockdep_set_class(&desc->lock, &irq_desc_lock_class);
    + mutex_init(&desc->request_mutex);
    init_rcu_head(&desc->rcu);

    desc_set_defaults(irq, desc, node, affinity, owner);
    \
     
     \ /
      Last update: 2017-07-11 12:53    [W:3.021 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site