]> www.infradead.org Git - users/willy/xarray.git/commitdiff
fastrpc: Convert ctxt_idr to XArray
authorMatthew Wilcox <willy@infradead.org>
Fri, 15 Mar 2019 12:50:56 +0000 (08:50 -0400)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:19 +0000 (21:38 -0400)
Signed-off-by: Matthew Wilcox <willy@infradead.org>
drivers/misc/fastrpc.c

index 98603e235cf04a1625eca271deb68e73b36efef3..9df14ee16e612bccbdf45998eb97bd1193b0fc98 100644 (file)
@@ -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;