Commit afcafe07 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Jason Gunthorpe

ucma: Convert ctx_idr to XArray

Signed-off-by: default avatarMatthew Wilcox <willy@infradead.org>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 4dfd5321
...@@ -81,7 +81,7 @@ struct ucma_file { ...@@ -81,7 +81,7 @@ struct ucma_file {
}; };
struct ucma_context { struct ucma_context {
int id; u32 id;
struct completion comp; struct completion comp;
atomic_t ref; atomic_t ref;
int events_reported; int events_reported;
...@@ -94,7 +94,7 @@ struct ucma_context { ...@@ -94,7 +94,7 @@ struct ucma_context {
struct list_head list; struct list_head list;
struct list_head mc_list; struct list_head mc_list;
/* mark that device is in process of destroying the internal HW /* mark that device is in process of destroying the internal HW
* resources, protected by the global mut * resources, protected by the ctx_table lock
*/ */
int closing; int closing;
/* sync between removal event and id destroy, protected by file mut */ /* sync between removal event and id destroy, protected by file mut */
...@@ -122,8 +122,7 @@ struct ucma_event { ...@@ -122,8 +122,7 @@ struct ucma_event {
struct work_struct close_work; struct work_struct close_work;
}; };
static DEFINE_MUTEX(mut); static DEFINE_XARRAY_ALLOC(ctx_table);
static DEFINE_IDR(ctx_idr);
static DEFINE_XARRAY_ALLOC(multicast_table); static DEFINE_XARRAY_ALLOC(multicast_table);
static const struct file_operations ucma_fops; static const struct file_operations ucma_fops;
...@@ -133,7 +132,7 @@ static inline struct ucma_context *_ucma_find_context(int id, ...@@ -133,7 +132,7 @@ static inline struct ucma_context *_ucma_find_context(int id,
{ {
struct ucma_context *ctx; struct ucma_context *ctx;
ctx = idr_find(&ctx_idr, id); ctx = xa_load(&ctx_table, id);
if (!ctx) if (!ctx)
ctx = ERR_PTR(-ENOENT); ctx = ERR_PTR(-ENOENT);
else if (ctx->file != file || !ctx->cm_id) else if (ctx->file != file || !ctx->cm_id)
...@@ -145,7 +144,7 @@ static struct ucma_context *ucma_get_ctx(struct ucma_file *file, int id) ...@@ -145,7 +144,7 @@ static struct ucma_context *ucma_get_ctx(struct ucma_file *file, int id)
{ {
struct ucma_context *ctx; struct ucma_context *ctx;
mutex_lock(&mut); xa_lock(&ctx_table);
ctx = _ucma_find_context(id, file); ctx = _ucma_find_context(id, file);
if (!IS_ERR(ctx)) { if (!IS_ERR(ctx)) {
if (ctx->closing) if (ctx->closing)
...@@ -153,7 +152,7 @@ static struct ucma_context *ucma_get_ctx(struct ucma_file *file, int id) ...@@ -153,7 +152,7 @@ static struct ucma_context *ucma_get_ctx(struct ucma_file *file, int id)
else else
atomic_inc(&ctx->ref); atomic_inc(&ctx->ref);
} }
mutex_unlock(&mut); xa_unlock(&ctx_table);
return ctx; return ctx;
} }
...@@ -216,10 +215,7 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file) ...@@ -216,10 +215,7 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
INIT_LIST_HEAD(&ctx->mc_list); INIT_LIST_HEAD(&ctx->mc_list);
ctx->file = file; ctx->file = file;
mutex_lock(&mut); if (xa_alloc(&ctx_table, &ctx->id, ctx, xa_limit_32b, GFP_KERNEL))
ctx->id = idr_alloc(&ctx_idr, ctx, 0, 0, GFP_KERNEL);
mutex_unlock(&mut);
if (ctx->id < 0)
goto error; goto error;
list_add_tail(&ctx->list, &file->ctx_list); list_add_tail(&ctx->list, &file->ctx_list);
...@@ -316,9 +312,9 @@ static void ucma_removal_event_handler(struct rdma_cm_id *cm_id) ...@@ -316,9 +312,9 @@ static void ucma_removal_event_handler(struct rdma_cm_id *cm_id)
* handled separately below. * handled separately below.
*/ */
if (ctx->cm_id == cm_id) { if (ctx->cm_id == cm_id) {
mutex_lock(&mut); xa_lock(&ctx_table);
ctx->closing = 1; ctx->closing = 1;
mutex_unlock(&mut); xa_unlock(&ctx_table);
queue_work(ctx->file->close_wq, &ctx->close_work); queue_work(ctx->file->close_wq, &ctx->close_work);
return; return;
} }
...@@ -520,9 +516,7 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, ...@@ -520,9 +516,7 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
err2: err2:
rdma_destroy_id(cm_id); rdma_destroy_id(cm_id);
err1: err1:
mutex_lock(&mut); xa_erase(&ctx_table, ctx->id);
idr_remove(&ctx_idr, ctx->id);
mutex_unlock(&mut);
mutex_lock(&file->mut); mutex_lock(&file->mut);
list_del(&ctx->list); list_del(&ctx->list);
mutex_unlock(&file->mut); mutex_unlock(&file->mut);
...@@ -534,13 +528,13 @@ static void ucma_cleanup_multicast(struct ucma_context *ctx) ...@@ -534,13 +528,13 @@ static void ucma_cleanup_multicast(struct ucma_context *ctx)
{ {
struct ucma_multicast *mc, *tmp; struct ucma_multicast *mc, *tmp;
mutex_lock(&mut); mutex_lock(&ctx->file->mut);
list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) { list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) {
list_del(&mc->list); list_del(&mc->list);
xa_erase(&multicast_table, mc->id); xa_erase(&multicast_table, mc->id);
kfree(mc); kfree(mc);
} }
mutex_unlock(&mut); mutex_unlock(&ctx->file->mut);
} }
static void ucma_cleanup_mc_events(struct ucma_multicast *mc) static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
...@@ -611,11 +605,11 @@ static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf, ...@@ -611,11 +605,11 @@ static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf,
if (copy_from_user(&cmd, inbuf, sizeof(cmd))) if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
return -EFAULT; return -EFAULT;
mutex_lock(&mut); xa_lock(&ctx_table);
ctx = _ucma_find_context(cmd.id, file); ctx = _ucma_find_context(cmd.id, file);
if (!IS_ERR(ctx)) if (!IS_ERR(ctx))
idr_remove(&ctx_idr, ctx->id); __xa_erase(&ctx_table, ctx->id);
mutex_unlock(&mut); xa_unlock(&ctx_table);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return PTR_ERR(ctx); return PTR_ERR(ctx);
...@@ -627,14 +621,14 @@ static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf, ...@@ -627,14 +621,14 @@ static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf,
flush_workqueue(ctx->file->close_wq); flush_workqueue(ctx->file->close_wq);
/* At this point it's guaranteed that there is no inflight /* At this point it's guaranteed that there is no inflight
* closing task */ * closing task */
mutex_lock(&mut); xa_lock(&ctx_table);
if (!ctx->closing) { if (!ctx->closing) {
mutex_unlock(&mut); xa_unlock(&ctx_table);
ucma_put_ctx(ctx); ucma_put_ctx(ctx);
wait_for_completion(&ctx->comp); wait_for_completion(&ctx->comp);
rdma_destroy_id(ctx->cm_id); rdma_destroy_id(ctx->cm_id);
} else { } else {
mutex_unlock(&mut); xa_unlock(&ctx_table);
} }
resp.events_reported = ucma_free_ctx(ctx); resp.events_reported = ucma_free_ctx(ctx);
...@@ -1607,14 +1601,14 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file, ...@@ -1607,14 +1601,14 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
* events being added before existing events. * events being added before existing events.
*/ */
ucma_lock_files(cur_file, new_file); ucma_lock_files(cur_file, new_file);
mutex_lock(&mut); xa_lock(&ctx_table);
list_move_tail(&ctx->list, &new_file->ctx_list); list_move_tail(&ctx->list, &new_file->ctx_list);
ucma_move_events(ctx, new_file); ucma_move_events(ctx, new_file);
ctx->file = new_file; ctx->file = new_file;
resp.events_reported = ctx->events_reported; resp.events_reported = ctx->events_reported;
mutex_unlock(&mut); xa_unlock(&ctx_table);
ucma_unlock_files(cur_file, new_file); ucma_unlock_files(cur_file, new_file);
response: response:
...@@ -1749,18 +1743,15 @@ static int ucma_close(struct inode *inode, struct file *filp) ...@@ -1749,18 +1743,15 @@ static int ucma_close(struct inode *inode, struct file *filp)
ctx->destroying = 1; ctx->destroying = 1;
mutex_unlock(&file->mut); mutex_unlock(&file->mut);
mutex_lock(&mut); xa_erase(&ctx_table, ctx->id);
idr_remove(&ctx_idr, ctx->id);
mutex_unlock(&mut);
flush_workqueue(file->close_wq); flush_workqueue(file->close_wq);
/* At that step once ctx was marked as destroying and workqueue /* At that step once ctx was marked as destroying and workqueue
* was flushed we are safe from any inflights handlers that * was flushed we are safe from any inflights handlers that
* might put other closing task. * might put other closing task.
*/ */
mutex_lock(&mut); xa_lock(&ctx_table);
if (!ctx->closing) { if (!ctx->closing) {
mutex_unlock(&mut); xa_unlock(&ctx_table);
ucma_put_ctx(ctx); ucma_put_ctx(ctx);
wait_for_completion(&ctx->comp); wait_for_completion(&ctx->comp);
/* rdma_destroy_id ensures that no event handlers are /* rdma_destroy_id ensures that no event handlers are
...@@ -1768,7 +1759,7 @@ static int ucma_close(struct inode *inode, struct file *filp) ...@@ -1768,7 +1759,7 @@ static int ucma_close(struct inode *inode, struct file *filp)
*/ */
rdma_destroy_id(ctx->cm_id); rdma_destroy_id(ctx->cm_id);
} else { } else {
mutex_unlock(&mut); xa_unlock(&ctx_table);
} }
ucma_free_ctx(ctx); ucma_free_ctx(ctx);
...@@ -1838,7 +1829,6 @@ static void __exit ucma_cleanup(void) ...@@ -1838,7 +1829,6 @@ static void __exit ucma_cleanup(void)
unregister_net_sysctl_table(ucma_ctl_table_hdr); unregister_net_sysctl_table(ucma_ctl_table_hdr);
device_remove_file(ucma_misc.this_device, &dev_attr_abi_version); device_remove_file(ucma_misc.this_device, &dev_attr_abi_version);
misc_deregister(&ucma_misc); misc_deregister(&ucma_misc);
idr_destroy(&ctx_idr);
} }
module_init(ucma_init); module_init(ucma_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment