lkml.org 
[lkml]   [2009]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 2/6] appldata: avoid deadlock with appldata_mem
    From: Gerald Schaefer <gerald.schaefer@de.ibm.com>

    The appldata_ops callbacks are called with a spin_lock held. But the
    appldata_mem callback then calls all_vm_events(), which calls
    get_online_cpus(), which might sleep. This possible deadlock is fixed
    by using a mutex instead of a spin_lock.

    Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
    Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
    ---

    arch/s390/appldata/appldata_base.c | 32 ++++++++++++++++----------------
    arch/s390/appldata/appldata_mem.c | 2 +-
    2 files changed, 17 insertions(+), 17 deletions(-)

    Index: quilt-2.6/arch/s390/appldata/appldata_base.c
    ===================================================================
    --- quilt-2.6.orig/arch/s390/appldata/appldata_base.c
    +++ quilt-2.6/arch/s390/appldata/appldata_base.c
    @@ -98,7 +98,7 @@ static DECLARE_WORK(appldata_work, appld
    /*
    * Ops list
    */
    -static DEFINE_SPINLOCK(appldata_ops_lock);
    +static DEFINE_MUTEX(appldata_ops_mutex);
    static LIST_HEAD(appldata_ops_list);


    @@ -129,14 +129,14 @@ static void appldata_work_fn(struct work

    i = 0;
    get_online_cpus();
    - spin_lock(&appldata_ops_lock);
    + mutex_lock(&appldata_ops_mutex);
    list_for_each(lh, &appldata_ops_list) {
    ops = list_entry(lh, struct appldata_ops, list);
    if (ops->active == 1) {
    ops->callback(ops->data);
    }
    }
    - spin_unlock(&appldata_ops_lock);
    + mutex_unlock(&appldata_ops_mutex);
    put_online_cpus();
    }

    @@ -338,7 +338,7 @@ appldata_generic_handler(ctl_table *ctl,
    struct list_head *lh;

    found = 0;
    - spin_lock(&appldata_ops_lock);
    + mutex_lock(&appldata_ops_mutex);
    list_for_each(lh, &appldata_ops_list) {
    tmp_ops = list_entry(lh, struct appldata_ops, list);
    if (&tmp_ops->ctl_table[2] == ctl) {
    @@ -346,15 +346,15 @@ appldata_generic_handler(ctl_table *ctl,
    }
    }
    if (!found) {
    - spin_unlock(&appldata_ops_lock);
    + mutex_unlock(&appldata_ops_mutex);
    return -ENODEV;
    }
    ops = ctl->data;
    if (!try_module_get(ops->owner)) { // protect this function
    - spin_unlock(&appldata_ops_lock);
    + mutex_unlock(&appldata_ops_mutex);
    return -ENODEV;
    }
    - spin_unlock(&appldata_ops_lock);
    + mutex_unlock(&appldata_ops_mutex);

    if (!*lenp || *ppos) {
    *lenp = 0;
    @@ -378,11 +378,11 @@ appldata_generic_handler(ctl_table *ctl,
    return -EFAULT;
    }

    - spin_lock(&appldata_ops_lock);
    + mutex_lock(&appldata_ops_mutex);
    if ((buf[0] == '1') && (ops->active == 0)) {
    // protect work queue callback
    if (!try_module_get(ops->owner)) {
    - spin_unlock(&appldata_ops_lock);
    + mutex_unlock(&appldata_ops_mutex);
    module_put(ops->owner);
    return -ENODEV;
    }
    @@ -407,7 +407,7 @@ appldata_generic_handler(ctl_table *ctl,
    "failed with rc=%d\n", ops->name, rc);
    module_put(ops->owner);
    }
    - spin_unlock(&appldata_ops_lock);
    + mutex_unlock(&appldata_ops_mutex);
    out:
    *lenp = len;
    *ppos += len;
    @@ -433,9 +433,9 @@ int appldata_register_ops(struct appldat
    if (!ops->ctl_table)
    return -ENOMEM;

    - spin_lock(&appldata_ops_lock);
    + mutex_lock(&appldata_ops_mutex);
    list_add(&ops->list, &appldata_ops_list);
    - spin_unlock(&appldata_ops_lock);
    + mutex_unlock(&appldata_ops_mutex);

    ops->ctl_table[0].procname = appldata_proc_name;
    ops->ctl_table[0].maxlen = 0;
    @@ -452,9 +452,9 @@ int appldata_register_ops(struct appldat
    goto out;
    return 0;
    out:
    - spin_lock(&appldata_ops_lock);
    + mutex_lock(&appldata_ops_mutex);
    list_del(&ops->list);
    - spin_unlock(&appldata_ops_lock);
    + mutex_unlock(&appldata_ops_mutex);
    kfree(ops->ctl_table);
    return -ENOMEM;
    }
    @@ -466,9 +466,9 @@ out:
    */
    void appldata_unregister_ops(struct appldata_ops *ops)
    {
    - spin_lock(&appldata_ops_lock);
    + mutex_lock(&appldata_ops_mutex);
    list_del(&ops->list);
    - spin_unlock(&appldata_ops_lock);
    + mutex_unlock(&appldata_ops_mutex);
    unregister_sysctl_table(ops->sysctl_header);
    kfree(ops->ctl_table);
    }
    Index: quilt-2.6/arch/s390/appldata/appldata_mem.c
    ===================================================================
    --- quilt-2.6.orig/arch/s390/appldata/appldata_mem.c
    +++ quilt-2.6/arch/s390/appldata/appldata_mem.c
    @@ -78,7 +78,7 @@ static void appldata_get_mem_data(void *
    {
    /*
    * don't put large structures on the stack, we are
    - * serialized through the appldata_ops_lock and can use static
    + * serialized through the appldata_ops_mutex and can use static
    */
    static struct sysinfo val;
    unsigned long ev[NR_VM_EVENT_ITEMS];
    --
    blue skies,
    Martin.

    "Reality continues to ruin my life." - Calvin.



    \
     
     \ /
      Last update: 2009-04-23 13:53    [W:0.028 / U:0.268 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site