From: Matthew Wilcox Date: Mon, 11 Feb 2019 21:38:45 +0000 (-0500) Subject: tee: Convert shm IDR to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=73bfe3a893ae06de2111d47dff078c62085c5fb9;p=users%2Fwilly%2Fxarray.git tee: Convert shm IDR to XArray Also remove the unused shm_list Signed-off-by: Matthew Wilcox --- diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 0f16d9ffd8d1..61bec6c0b505 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include @@ -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; diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h index f797171f0434..f843f3cabe0e 100644 --- a/drivers/tee/tee_private.h +++ b/drivers/tee/tee_private.h @@ -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; }; diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 2da026fd12c9..c09a0b983845 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -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); diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index 7a03f68fb982..7d6d05de2b35 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -7,7 +7,6 @@ #define __TEE_DRV_H #include -#include #include #include #include @@ -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;