]> www.infradead.org Git - users/willy/xarray.git/commitdiff
tee: Convert shm IDR to XArray
authorMatthew Wilcox <willy@infradead.org>
Mon, 11 Feb 2019 21:38:45 +0000 (16:38 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:15 +0000 (21:38 -0400)
Also remove the unused shm_list

Signed-off-by: Matthew Wilcox <willy@infradead.org>
drivers/tee/tee_core.c
drivers/tee/tee_private.h
drivers/tee/tee_shm.c
include/linux/tee_drv.h

index 0f16d9ffd8d12ee024a92f9eff1b926fb8819fc4..61bec6c0b505c5779747455a60acce40c42e5dfb 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <linux/cdev.h>
 #include <linux/fs.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/tee_drv.h>
@@ -44,7 +44,6 @@ static struct tee_context *teedev_open(struct tee_device *teedev)
 
        kref_init(&ctx->refcount);
        ctx->teedev = teedev;
-       INIT_LIST_HEAD(&ctx->list_shm);
        rc = teedev->desc->ops->open(ctx);
        if (rc)
                goto err;
@@ -686,7 +685,6 @@ static void tee_release_device(struct device *dev)
        clear_bit(teedev->id, dev_mask);
        spin_unlock(&driver_lock);
        mutex_destroy(&teedev->mutex);
-       idr_destroy(&teedev->idr);
        kfree(teedev);
 }
 
@@ -768,7 +766,7 @@ struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
        teedev->num_users = 1;
        init_completion(&teedev->c_no_users);
        mutex_init(&teedev->mutex);
-       idr_init(&teedev->idr);
+       xa_init_flags(&teedev->shms, XA_FLAGS_ALLOC);
 
        teedev->desc = teedesc;
        teedev->pool = pool;
index f797171f0434f48787bcb50828c3160aafc0cd19..f843f3cabe0e4178e4d25ad1161b46dd57e20169 100644 (file)
@@ -36,8 +36,8 @@ struct tee_shm_pool {
  * @cdev:      embedded cdev
  * @num_users: number of active users of this device
  * @c_no_user: completion used when unregistering the device
- * @mutex:     mutex protecting @num_users and @idr
- * @idr:       register of shared memory object allocated on this device
+ * @mutex:     mutex protecting @num_users
+ * @shms:      register of shared memory object allocated on this device
  * @pool:      shared memory pool
  */
 struct tee_device {
@@ -51,9 +51,9 @@ struct tee_device {
 
        size_t num_users;
        struct completion c_no_users;
-       struct mutex mutex;     /* protects num_users and idr */
+       struct mutex mutex;
 
-       struct idr idr;
+       struct xarray shms;
        struct tee_shm_pool *pool;
 };
 
index 2da026fd12c9eb0872fa708be31a7e61add16f71..c09a0b983845e6d0bf06efaf659a4ae902f3f6f1 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/device.h>
 #include <linux/dma-buf.h>
 #include <linux/fdtable.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/tee_drv.h>
@@ -15,11 +15,7 @@ static void tee_shm_release(struct tee_shm *shm)
 {
        struct tee_device *teedev = shm->teedev;
 
-       mutex_lock(&teedev->mutex);
-       idr_remove(&teedev->idr, shm->id);
-       if (shm->ctx)
-               list_del(&shm->link);
-       mutex_unlock(&teedev->mutex);
+       xa_erase(&teedev->shms, shm->id);
 
        if (shm->flags & TEE_SHM_POOL) {
                struct tee_shm_pool_mgr *poolm;
@@ -151,11 +147,9 @@ static struct tee_shm *__tee_shm_alloc(struct tee_context *ctx,
                goto err_kfree;
        }
 
-       mutex_lock(&teedev->mutex);
-       shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
-       mutex_unlock(&teedev->mutex);
-       if (shm->id < 0) {
-               ret = ERR_PTR(shm->id);
+       rc = xa_alloc(&teedev->shms, &shm->id, shm, xa_limit_32b, GFP_KERNEL);
+       if (rc < 0) {
+               ret = ERR_PTR(rc);
                goto err_pool_free;
        }
 
@@ -174,18 +168,12 @@ static struct tee_shm *__tee_shm_alloc(struct tee_context *ctx,
                }
        }
 
-       if (ctx) {
+       if (ctx)
                teedev_ctx_get(ctx);
-               mutex_lock(&teedev->mutex);
-               list_add_tail(&shm->link, &ctx->list_shm);
-               mutex_unlock(&teedev->mutex);
-       }
 
        return shm;
 err_rem:
-       mutex_lock(&teedev->mutex);
-       idr_remove(&teedev->idr, shm->id);
-       mutex_unlock(&teedev->mutex);
+       xa_erase(&teedev->shms, shm->id);
 err_pool_free:
        poolm->ops->free(poolm, shm);
 err_kfree:
@@ -247,13 +235,12 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
        shm = kzalloc(sizeof(*shm), GFP_KERNEL);
        if (!shm) {
                ret = ERR_PTR(-ENOMEM);
-               goto err;
+               goto err_free;
        }
 
        shm->flags = flags | TEE_SHM_REGISTER;
        shm->teedev = teedev;
        shm->ctx = ctx;
-       shm->id = -1;
        start = rounddown(addr, PAGE_SIZE);
        shm->offset = addr - start;
        shm->size = length;
@@ -261,7 +248,7 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
        shm->pages = kcalloc(num_pages, sizeof(*shm->pages), GFP_KERNEL);
        if (!shm->pages) {
                ret = ERR_PTR(-ENOMEM);
-               goto err;
+               goto err_free;
        }
 
        rc = get_user_pages_fast(start, num_pages, FOLL_WRITE, shm->pages);
@@ -271,23 +258,20 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
                if (rc >= 0)
                        rc = -ENOMEM;
                ret = ERR_PTR(rc);
-               goto err;
+               goto err_pages;
        }
 
-       mutex_lock(&teedev->mutex);
-       shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
-       mutex_unlock(&teedev->mutex);
-
-       if (shm->id < 0) {
-               ret = ERR_PTR(shm->id);
-               goto err;
+       rc = xa_alloc(&teedev->shms, &shm->id, shm, xa_limit_32b, GFP_KERNEL);
+       if (rc < 0) {
+               ret = ERR_PTR(rc);
+               goto err_pages;
        }
 
        rc = teedev->desc->ops->shm_register(ctx, shm, shm->pages,
                                             shm->num_pages, start);
        if (rc) {
                ret = ERR_PTR(rc);
-               goto err;
+               goto err_erase;
        }
 
        if (flags & TEE_SHM_DMA_BUF) {
@@ -302,30 +286,22 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
                if (IS_ERR(shm->dmabuf)) {
                        ret = ERR_CAST(shm->dmabuf);
                        teedev->desc->ops->shm_unregister(ctx, shm);
-                       goto err;
+                       goto err_erase;
                }
        }
 
-       mutex_lock(&teedev->mutex);
-       list_add_tail(&shm->link, &ctx->list_shm);
-       mutex_unlock(&teedev->mutex);
-
        return shm;
-err:
-       if (shm) {
-               size_t n;
 
-               if (shm->id >= 0) {
-                       mutex_lock(&teedev->mutex);
-                       idr_remove(&teedev->idr, shm->id);
-                       mutex_unlock(&teedev->mutex);
-               }
-               if (shm->pages) {
-                       for (n = 0; n < shm->num_pages; n++)
-                               put_page(shm->pages[n]);
-                       kfree(shm->pages);
-               }
+err_erase:
+       xa_erase(&teedev->shms, shm->id);
+err_pages:
+       if (shm->pages) {
+               size_t n;
+               for (n = 0; n < shm->num_pages; n++)
+                       put_page(shm->pages[n]);
+               kfree(shm->pages);
        }
+err_free:
        kfree(shm);
        teedev_ctx_put(ctx);
        tee_device_put(teedev);
@@ -473,13 +449,13 @@ struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id)
                return ERR_PTR(-EINVAL);
 
        teedev = ctx->teedev;
-       mutex_lock(&teedev->mutex);
-       shm = idr_find(&teedev->idr, id);
+       xa_lock(&teedev->shms);
+       shm = xa_load(&teedev->shms, id);
        if (!shm || shm->ctx != ctx)
                shm = ERR_PTR(-EINVAL);
        else if (shm->flags & TEE_SHM_DMA_BUF)
                get_dma_buf(shm->dmabuf);
-       mutex_unlock(&teedev->mutex);
+       xa_unlock(&teedev->shms);
        return shm;
 }
 EXPORT_SYMBOL_GPL(tee_shm_get_from_id);
index 7a03f68fb982d2da35628f2b77ad11eaa9c0d65b..7d6d05de2b3526b57bd14cb6cf9fd8589612f89e 100644 (file)
@@ -7,7 +7,6 @@
 #define __TEE_DRV_H
 
 #include <linux/device.h>
-#include <linux/idr.h>
 #include <linux/kref.h>
 #include <linux/list.h>
 #include <linux/mod_devicetable.h>
@@ -49,7 +48,6 @@ struct tee_shm_pool;
  */
 struct tee_context {
        struct tee_device *teedev;
-       struct list_head list_shm;
        void *data;
        struct kref refcount;
        bool releasing;
@@ -187,7 +185,6 @@ void tee_device_unregister(struct tee_device *teedev);
 struct tee_shm {
        struct tee_device *teedev;
        struct tee_context *ctx;
-       struct list_head link;
        phys_addr_t paddr;
        void *kaddr;
        size_t size;