From: Matthew Wilcox Date: Fri, 15 Mar 2019 12:50:56 +0000 (-0400) Subject: fastrpc: Convert ctxt_idr to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=48de4d9caf929e7d7ff66b47a46386ffa54e81dd;p=users%2Fwilly%2Fxarray.git fastrpc: Convert ctxt_idr to XArray Signed-off-by: Matthew Wilcox --- diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 98603e235cf0..9df14ee16e61 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -153,8 +153,8 @@ struct fastrpc_invoke_ctx { int pid; int tgid; u32 sc; + unsigned int ctxid; u32 *crc; - u64 ctxid; u64 msg_sz; struct kref refcount; struct list_head node; /* list of ctxs */ @@ -183,7 +183,8 @@ struct fastrpc_channel_ctx { struct rpmsg_device *rpdev; struct fastrpc_session_ctx session[FASTRPC_MAX_SESSIONS]; spinlock_t lock; - struct idr ctx_idr; + unsigned int ctxt_nextid; + struct xarray ctxts; struct list_head users; struct miscdevice miscdev; }; @@ -306,9 +307,7 @@ static void fastrpc_context_free(struct kref *ref) if (ctx->buf) fastrpc_buf_free(ctx->buf); - spin_lock_irqsave(&cctx->lock, flags); - idr_remove(&cctx->ctx_idr, ctx->ctxid >> 4); - spin_unlock_irqrestore(&cctx->lock, flags); + xa_erase(&cctx->ctxts, ctx->ctxid); kfree(ctx->maps); kfree(ctx->olaps); @@ -425,26 +424,21 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( ctx->tgid = user->tgid; ctx->cctx = cctx; init_completion(&ctx->work); + kref_init(&ctx->refcount); INIT_WORK(&ctx->put_work, fastrpc_context_put_wq); spin_lock(&user->lock); list_add_tail(&ctx->node, &user->pending); spin_unlock(&user->lock); - spin_lock_irqsave(&cctx->lock, flags); - ret = idr_alloc_cyclic(&cctx->ctx_idr, ctx, 1, - FASTRPC_CTX_MAX, GFP_ATOMIC); - if (ret < 0) { - spin_unlock_irqrestore(&cctx->lock, flags); - goto err_idr; - } - ctx->ctxid = ret << 4; - spin_unlock_irqrestore(&cctx->lock, flags); - - kref_init(&ctx->refcount); + ret = xa_alloc_cyclic(&cctx->ctxts, &ctx->ctxid, ctx, + XA_LIMIT(0, FASTRPC_CTX_MAX - 1), &cctx->ctxt_nextid, + GFP_KERNEL); + if (ret < 0) + goto err_id; return ctx; -err_idr: +err_id: spin_lock(&user->lock); list_del(&ctx->node); spin_unlock(&user->lock); @@ -864,7 +858,7 @@ static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, if (kernel) msg->pid = 0; - msg->ctx = ctx->ctxid | fl->pd; + msg->ctx = (ctx->ctxid << 4) | fl->pd; msg->handle = handle; msg->sc = ctx->sc; msg->addr = ctx->buf ? ctx->buf->phys : 0; @@ -1429,7 +1423,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32)); INIT_LIST_HEAD(&data->users); spin_lock_init(&data->lock); - idr_init(&data->ctx_idr); + xa_init_flags(&data->ctxts, XA_FLAGS_ALLOC1); data->domain_id = domain_id; data->rpdev = rpdev; @@ -1468,7 +1462,6 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev); struct fastrpc_invoke_rsp *rsp = data; struct fastrpc_invoke_ctx *ctx; - unsigned long flags; unsigned long ctxid; if (len < sizeof(*rsp)) @@ -1476,10 +1469,7 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, ctxid = ((rsp->ctx & FASTRPC_CTXID_MASK) >> 4); - spin_lock_irqsave(&cctx->lock, flags); - ctx = idr_find(&cctx->ctx_idr, ctxid); - spin_unlock_irqrestore(&cctx->lock, flags); - + ctx = xa_load(&cctx->ctxts, ctxid); if (!ctx) { dev_err(&rpdev->dev, "No context ID matches response\n"); return -ENOENT;