lkml.org 
[lkml]   [2010]   [Jan]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 2/4] MTD: create lockless versions of {get,put}_mtd_device
    From
    Date
    >From 628ad1a6a240d444dbd4d6897181daa096ac6226 Mon Sep 17 00:00:00 2001
    From: Maxim Levitsky <maximlevitsky@gmail.com>
    Date: Fri, 22 Jan 2010 15:00:54 +0200
    Subject: [PATCH 2/4] MTD: create lockless versions of {get,put}_mtd_device
    This will be used to resolve deadlock in block translation layer.

    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
    ---
    drivers/mtd/mtdcore.c | 61 ++++++++++++++++++++++++++++++-----------------
    include/linux/mtd/mtd.h | 3 +-
    2 files changed, 41 insertions(+), 23 deletions(-)
    diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
    index 87ff83f..96b4a05 100644
    --- a/drivers/mtd/mtdcore.c
    +++ b/drivers/mtd/mtdcore.c
    @@ -454,27 +454,38 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
    ret = NULL;
    }

    - if (!ret)
    - goto out_unlock;
    -
    - if (!try_module_get(ret->owner))
    - goto out_unlock;
    -
    - if (ret->get_device) {
    - err = ret->get_device(ret);
    - if (err)
    - goto out_put;
    + if (!ret) {
    + ret = ERR_PTR(err);
    + goto out;
    }

    - ret->usecount++;
    + err = __get_mtd_device(ret);
    + if (err)
    + ret = ERR_PTR(err);
    +out:
    mutex_unlock(&mtd_table_mutex);
    return ret;
    +}

    -out_put:
    - module_put(ret->owner);
    -out_unlock:
    - mutex_unlock(&mtd_table_mutex);
    - return ERR_PTR(err);
    +
    +int __get_mtd_device(struct mtd_info *mtd)
    +{
    + int err;
    +
    + if (!try_module_get(mtd->owner))
    + return -ENODEV;
    +
    + if (mtd->get_device) {
    +
    + err = mtd->get_device(mtd);
    +
    + if (err) {
    + module_put(mtd->owner);
    + return err;
    + }
    + }
    + mtd->usecount++;
    + return 0;
    }

    /**
    @@ -525,18 +536,22 @@ out_unlock:

    void put_mtd_device(struct mtd_info *mtd)
    {
    - int c;
    -
    mutex_lock(&mtd_table_mutex);
    - c = --mtd->usecount;
    - if (mtd->put_device)
    - mtd->put_device(mtd);
    + __put_mtd_device(mtd);
    mutex_unlock(&mtd_table_mutex);
    - BUG_ON(c < 0);

    module_put(mtd->owner);
    }

    +void __put_mtd_device(struct mtd_info *mtd)
    +{
    + --mtd->usecount;
    + BUG_ON(mtd->usecount < 0);
    +
    + if (mtd->put_device)
    + mtd->put_device(mtd);
    +}
    +
    /* default_mtd_writev - default mtd writev method for MTD devices that
    * don't implement their own
    */
    @@ -570,7 +585,9 @@ EXPORT_SYMBOL_GPL(add_mtd_device);
    EXPORT_SYMBOL_GPL(del_mtd_device);
    EXPORT_SYMBOL_GPL(get_mtd_device);
    EXPORT_SYMBOL_GPL(get_mtd_device_nm);
    +EXPORT_SYMBOL_GPL(__get_mtd_device);
    EXPORT_SYMBOL_GPL(put_mtd_device);
    +EXPORT_SYMBOL_GPL(__put_mtd_device);
    EXPORT_SYMBOL_GPL(register_mtd_user);
    EXPORT_SYMBOL_GPL(unregister_mtd_user);
    EXPORT_SYMBOL_GPL(default_mtd_writev);
    diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
    index 0f32a9b..662d747 100644
    --- a/include/linux/mtd/mtd.h
    +++ b/include/linux/mtd/mtd.h
    @@ -290,8 +290,9 @@ extern int add_mtd_device(struct mtd_info *mtd);
    extern int del_mtd_device (struct mtd_info *mtd);

    extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
    +extern int __get_mtd_device(struct mtd_info *mtd);
    +extern void __put_mtd_device(struct mtd_info *mtd);
    extern struct mtd_info *get_mtd_device_nm(const char *name);
    -
    extern void put_mtd_device(struct mtd_info *mtd);


    --
    1.6.3.3




    \
     
     \ /
      Last update: 2010-01-22 16:37    [from the cache]
    ©2003-2014 Jasper Spaans. hosted at Digital Ocean