aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx5/devx.c
diff options
context:
space:
mode:
authorYishai Hadas <yishaih@mellanox.com>2019-01-22 08:29:59 +0200
committerJason Gunthorpe <jgg@mellanox.com>2019-01-29 13:33:00 -0700
commiteaebaf77e7cb22fc371b7843370c903f1dd0fc3d (patch)
tree1d89f542a474201ce4eaccc9430186ddd4d9ceb3 /drivers/infiniband/hw/mlx5/devx.c
parentIB/mlx5: Implement the file ops of DEVX async command FD (diff)
downloadlinux-dev-eaebaf77e7cb22fc371b7843370c903f1dd0fc3d.tar.xz
linux-dev-eaebaf77e7cb22fc371b7843370c903f1dd0fc3d.zip
IB/mlx5: Implement DEVX hot unplug for async command FD
Implement DEVX hot unplug for the async command FD. This is done by managing a list of the inflight commands and wait until all launched work is completed as part of devx_hot_unplug_async_cmd_event_file. Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers/infiniband/hw/mlx5/devx.c')
-rw-r--r--drivers/infiniband/hw/mlx5/devx.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c
index 234e413c7ab8..84ef296857ef 100644
--- a/drivers/infiniband/hw/mlx5/devx.c
+++ b/drivers/infiniband/hw/mlx5/devx.c
@@ -1184,6 +1184,7 @@ struct devx_async_event_queue {
wait_queue_head_t poll_wait;
struct list_head event_list;
atomic_t bytes_in_use;
+ u8 is_destroyed:1;
};
struct devx_async_cmd_event_file {
@@ -1198,6 +1199,7 @@ static void devx_init_event_queue(struct devx_async_event_queue *ev_queue)
INIT_LIST_HEAD(&ev_queue->event_list);
init_waitqueue_head(&ev_queue->poll_wait);
atomic_set(&ev_queue->bytes_in_use, 0);
+ ev_queue->is_destroyed = 0;
}
static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_ASYNC_CMD_FD_ALLOC)(
@@ -1488,9 +1490,15 @@ static ssize_t devx_async_cmd_event_read(struct file *filp, char __user *buf,
if (wait_event_interruptible(
ev_queue->poll_wait,
- !list_empty(&ev_queue->event_list))) {
+ (!list_empty(&ev_queue->event_list) ||
+ ev_queue->is_destroyed))) {
return -ERESTARTSYS;
}
+
+ if (list_empty(&ev_queue->event_list) &&
+ ev_queue->is_destroyed)
+ return -EIO;
+
spin_lock_irq(&ev_queue->lock);
}
@@ -1544,7 +1552,9 @@ static __poll_t devx_async_cmd_event_poll(struct file *filp,
poll_wait(filp, &ev_queue->poll_wait, wait);
spin_lock_irq(&ev_queue->lock);
- if (!list_empty(&ev_queue->event_list))
+ if (ev_queue->is_destroyed)
+ pollflags = EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
+ else if (!list_empty(&ev_queue->event_list))
pollflags = EPOLLIN | EPOLLRDNORM;
spin_unlock_irq(&ev_queue->lock);
@@ -1565,6 +1575,14 @@ static int devx_hot_unplug_async_cmd_event_file(struct ib_uobject *uobj,
struct devx_async_cmd_event_file *comp_ev_file =
container_of(uobj, struct devx_async_cmd_event_file,
uobj);
+ struct devx_async_event_queue *ev_queue = &comp_ev_file->ev_queue;
+
+ spin_lock_irq(&ev_queue->lock);
+ ev_queue->is_destroyed = 1;
+ spin_unlock_irq(&ev_queue->lock);
+
+ if (why == RDMA_REMOVE_DRIVER_REMOVE)
+ wake_up_interruptible(&ev_queue->poll_wait);
mlx5_cmd_cleanup_async_ctx(&comp_ev_file->async_ctx);
return 0;