aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@nvidia.com>2020-08-18 15:05:23 +0300
committerJason Gunthorpe <jgg@nvidia.com>2020-08-27 08:38:16 -0300
commit26c15dec490c3a65f4eba6704c6648c299adb7a6 (patch)
treeba5c6ab32a6711bbf49afc7c1fb18bee8982c648 /drivers/infiniband/core
parentRDMA/ucma: Add missing locking around rdma_leave_multicast() (diff)
downloadlinux-dev-26c15dec490c3a65f4eba6704c6648c299adb7a6.tar.xz
linux-dev-26c15dec490c3a65f4eba6704c6648c299adb7a6.zip
RDMA/ucma: Change backlog into an atomic
There is no reason to grab the file->mut just to do this inc/dec work. Use an atomic. Link: https://lore.kernel.org/r/20200818120526.702120-12-leon@kernel.org Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/ucma.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index ad78b05de656..8be8ff14ab62 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -88,7 +88,7 @@ struct ucma_context {
struct completion comp;
refcount_t ref;
int events_reported;
- int backlog;
+ atomic_t backlog;
struct ucma_file *file;
struct rdma_cm_id *cm_id;
@@ -348,12 +348,11 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id,
uevent->resp.ece.attr_mod = event->ece.attr_mod;
if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) {
- if (!ctx->backlog) {
+ if (!atomic_add_unless(&ctx->backlog, -1, 0)) {
ret = -ENOMEM;
kfree(uevent);
goto out;
}
- ctx->backlog--;
} else if (!ctx->uid || ctx->cm_id != cm_id) {
/*
* We ignore events for new connections until userspace has set
@@ -432,7 +431,7 @@ static ssize_t ucma_get_event(struct ucma_file *file, const char __user *inbuf,
}
if (ctx) {
- uevent->ctx->backlog++;
+ atomic_inc(&uevent->ctx->backlog);
uevent->cm_id->context = ctx;
ucma_finish_ctx(ctx);
}
@@ -1136,10 +1135,12 @@ static ssize_t ucma_listen(struct ucma_file *file, const char __user *inbuf,
if (IS_ERR(ctx))
return PTR_ERR(ctx);
- ctx->backlog = cmd.backlog > 0 && cmd.backlog < max_backlog ?
- cmd.backlog : max_backlog;
+ if (cmd.backlog <= 0 || cmd.backlog > max_backlog)
+ cmd.backlog = max_backlog;
+ atomic_set(&ctx->backlog, cmd.backlog);
+
mutex_lock(&ctx->mutex);
- ret = rdma_listen(ctx->cm_id, ctx->backlog);
+ ret = rdma_listen(ctx->cm_id, cmd.backlog);
mutex_unlock(&ctx->mutex);
ucma_put_ctx(ctx);
return ret;