lkml.org 
[lkml]   [2013]   [Feb]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 38/77] IB/core: convert to idr_alloc()
    Date
    Convert to the much saner new idr interface.

    Only compile tested.

    v2: Mike triggered WARN_ON() in idr_preload() because send_mad(),
    which may be used from non-process context, was calling
    idr_preload() unconditionally. Preload iff @gfp_mask has
    __GFP_WAIT.

    Signed-off-by: Tejun Heo <tj@kernel.org>
    Reviewed-by: Sean Hefty <sean.hefty@intel.com>
    Reported-by: "Marciniszyn, Mike" <mike.marciniszyn@intel.com>
    Cc: Roland Dreier <roland@kernel.org>
    Cc: Sean Hefty <sean.hefty@intel.com>
    Cc: Hal Rosenstock <hal.rosenstock@gmail.com>
    Cc: linux-rdma@vger.kernel.org
    ---
    drivers/infiniband/core/cm.c | 22 +++++++++++-----------
    drivers/infiniband/core/cma.c | 24 +++++++-----------------
    drivers/infiniband/core/sa_query.c | 18 ++++++++++--------
    drivers/infiniband/core/ucm.c | 16 ++++------------
    drivers/infiniband/core/ucma.c | 32 ++++++++------------------------
    drivers/infiniband/core/uverbs_cmd.c | 17 ++++++++---------
    6 files changed, 48 insertions(+), 81 deletions(-)

    diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
    index 394fea2..98281fe 100644
    --- a/drivers/infiniband/core/cm.c
    +++ b/drivers/infiniband/core/cm.c
    @@ -382,20 +382,21 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
    static int cm_alloc_id(struct cm_id_private *cm_id_priv)
    {
    unsigned long flags;
    - int ret, id;
    + int id;
    static int next_id;

    - do {
    - spin_lock_irqsave(&cm.lock, flags);
    - ret = idr_get_new_above(&cm.local_id_table, cm_id_priv,
    - next_id, &id);
    - if (!ret)
    - next_id = ((unsigned) id + 1) & MAX_IDR_MASK;
    - spin_unlock_irqrestore(&cm.lock, flags);
    - } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) );
    + idr_preload(GFP_KERNEL);
    + spin_lock_irqsave(&cm.lock, flags);
    +
    + id = idr_alloc(&cm.local_id_table, cm_id_priv, next_id, 0, GFP_NOWAIT);
    + if (id >= 0)
    + next_id = ((unsigned) id + 1) & MAX_IDR_MASK;
    +
    + spin_unlock_irqrestore(&cm.lock, flags);
    + idr_preload_end();

    cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand;
    - return ret;
    + return id < 0 ? id : 0;
    }

    static void cm_free_id(__be32 local_id)
    @@ -3844,7 +3845,6 @@ static int __init ib_cm_init(void)
    cm.remote_sidr_table = RB_ROOT;
    idr_init(&cm.local_id_table);
    get_random_bytes(&cm.random_id_operand, sizeof cm.random_id_operand);
    - idr_pre_get(&cm.local_id_table, GFP_KERNEL);
    INIT_LIST_HEAD(&cm.timewait_list);

    ret = class_register(&cm_class);
    diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
    index d789eea..c32eeaa 100644
    --- a/drivers/infiniband/core/cma.c
    +++ b/drivers/infiniband/core/cma.c
    @@ -2143,33 +2143,23 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
    unsigned short snum)
    {
    struct rdma_bind_list *bind_list;
    - int port, ret;
    + int ret;

    bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL);
    if (!bind_list)
    return -ENOMEM;

    - do {
    - ret = idr_get_new_above(ps, bind_list, snum, &port);
    - } while ((ret == -EAGAIN) && idr_pre_get(ps, GFP_KERNEL));
    -
    - if (ret)
    - goto err1;
    -
    - if (port != snum) {
    - ret = -EADDRNOTAVAIL;
    - goto err2;
    - }
    + ret = idr_alloc(ps, bind_list, snum, snum + 1, GFP_KERNEL);
    + if (ret < 0)
    + goto err;

    bind_list->ps = ps;
    - bind_list->port = (unsigned short) port;
    + bind_list->port = (unsigned short)ret;
    cma_bind_port(bind_list, id_priv);
    return 0;
    -err2:
    - idr_remove(ps, port);
    -err1:
    +err:
    kfree(bind_list);
    - return ret;
    + return ret == -ENOSPC ? -EADDRNOTAVAIL : ret;
    }

    static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv)
    diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
    index a8905ab..934f45e 100644
    --- a/drivers/infiniband/core/sa_query.c
    +++ b/drivers/infiniband/core/sa_query.c
    @@ -611,19 +611,21 @@ static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)

    static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
    {
    + bool preload = gfp_mask & __GFP_WAIT;
    unsigned long flags;
    int ret, id;

    -retry:
    - if (!idr_pre_get(&query_idr, gfp_mask))
    - return -ENOMEM;
    + if (preload)
    + idr_preload(gfp_mask);
    spin_lock_irqsave(&idr_lock, flags);
    - ret = idr_get_new(&query_idr, query, &id);
    +
    + id = idr_alloc(&query_idr, query, 0, 0, GFP_NOWAIT);
    +
    spin_unlock_irqrestore(&idr_lock, flags);
    - if (ret == -EAGAIN)
    - goto retry;
    - if (ret)
    - return ret;
    + if (preload)
    + idr_preload_end();
    + if (id < 0)
    + return id;

    query->mad_buf->timeout_ms = timeout_ms;
    query->mad_buf->context[0] = query;
    diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
    index 49b15ac..f2f6393 100644
    --- a/drivers/infiniband/core/ucm.c
    +++ b/drivers/infiniband/core/ucm.c
    @@ -176,7 +176,6 @@ static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx)
    static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
    {
    struct ib_ucm_context *ctx;
    - int result;

    ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
    if (!ctx)
    @@ -187,17 +186,10 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
    ctx->file = file;
    INIT_LIST_HEAD(&ctx->events);

    - do {
    - result = idr_pre_get(&ctx_id_table, GFP_KERNEL);
    - if (!result)
    - goto error;
    -
    - mutex_lock(&ctx_id_mutex);
    - result = idr_get_new(&ctx_id_table, ctx, &ctx->id);
    - mutex_unlock(&ctx_id_mutex);
    - } while (result == -EAGAIN);
    -
    - if (result)
    + mutex_lock(&ctx_id_mutex);
    + ctx->id = idr_alloc(&ctx_id_table, ctx, 0, 0, GFP_KERNEL);
    + mutex_unlock(&ctx_id_mutex);
    + if (ctx->id < 0)
    goto error;

    list_add_tail(&ctx->file_list, &file->ctxs);
    diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
    index 2709ff5..5ca44cd 100644
    --- a/drivers/infiniband/core/ucma.c
    +++ b/drivers/infiniband/core/ucma.c
    @@ -145,7 +145,6 @@ static void ucma_put_ctx(struct ucma_context *ctx)
    static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
    {
    struct ucma_context *ctx;
    - int ret;

    ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
    if (!ctx)
    @@ -156,17 +155,10 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
    INIT_LIST_HEAD(&ctx->mc_list);
    ctx->file = file;

    - do {
    - ret = idr_pre_get(&ctx_idr, GFP_KERNEL);
    - if (!ret)
    - goto error;
    -
    - mutex_lock(&mut);
    - ret = idr_get_new(&ctx_idr, ctx, &ctx->id);
    - mutex_unlock(&mut);
    - } while (ret == -EAGAIN);
    -
    - if (ret)
    + mutex_lock(&mut);
    + ctx->id = idr_alloc(&ctx_idr, ctx, 0, 0, GFP_KERNEL);
    + mutex_unlock(&mut);
    + if (ctx->id < 0)
    goto error;

    list_add_tail(&ctx->list, &file->ctx_list);
    @@ -180,23 +172,15 @@ error:
    static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
    {
    struct ucma_multicast *mc;
    - int ret;

    mc = kzalloc(sizeof(*mc), GFP_KERNEL);
    if (!mc)
    return NULL;

    - do {
    - ret = idr_pre_get(&multicast_idr, GFP_KERNEL);
    - if (!ret)
    - goto error;
    -
    - mutex_lock(&mut);
    - ret = idr_get_new(&multicast_idr, mc, &mc->id);
    - mutex_unlock(&mut);
    - } while (ret == -EAGAIN);
    -
    - if (ret)
    + mutex_lock(&mut);
    + mc->id = idr_alloc(&multicast_idr, mc, 0, 0, GFP_KERNEL);
    + mutex_unlock(&mut);
    + if (mc->id < 0)
    goto error;

    mc->ctx = ctx;
    diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
    index 0cb0007..83bc309 100644
    --- a/drivers/infiniband/core/uverbs_cmd.c
    +++ b/drivers/infiniband/core/uverbs_cmd.c
    @@ -124,18 +124,17 @@ static int idr_add_uobj(struct idr *idr, struct ib_uobject *uobj)
    {
    int ret;

    -retry:
    - if (!idr_pre_get(idr, GFP_KERNEL))
    - return -ENOMEM;
    -
    + idr_preload(GFP_KERNEL);
    spin_lock(&ib_uverbs_idr_lock);
    - ret = idr_get_new(idr, uobj, &uobj->id);
    - spin_unlock(&ib_uverbs_idr_lock);

    - if (ret == -EAGAIN)
    - goto retry;
    + ret = idr_alloc(idr, uobj, 0, 0, GFP_NOWAIT);
    + if (ret >= 0)
    + uobj->id = ret;

    - return ret;
    + spin_unlock(&ib_uverbs_idr_lock);
    + idr_preload_end();
    +
    + return ret < 0 ? ret : 0;
    }

    void idr_remove_uobj(struct idr *idr, struct ib_uobject *uobj)
    --
    1.8.1


    \
     
     \ /
      Last update: 2013-02-06 23:24    [W:4.268 / U:1.448 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site