summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx5/mr.c
diff options
context:
space:
mode:
authorMoshe Lazer <moshel@mellanox.com>2013-09-11 15:35:23 +0200
committerRoland Dreier <roland@purestorage.com>2013-10-10 18:23:55 +0200
commit3c4619114cb6760d2c97fd562ea96d2c8786b56a (patch)
tree35b284517c269572ab2c7b7ab2317e6f777d0da3 /drivers/infiniband/hw/mlx5/mr.c
parentIB/mlx5: Fix send work queue size calculation (diff)
downloadlinux-3c4619114cb6760d2c97fd562ea96d2c8786b56a.tar.xz
linux-3c4619114cb6760d2c97fd562ea96d2c8786b56a.zip
IB/mlx5: Flush cache workqueue before destroying it
Destroying the workqueue without flushing it first can lead to a case in which the kernel tries to push a delayed work to the workqueue which does not exist anymore. Signed-off-by: Moshe Lazer <moshel@mellanox.com> Signed-off-by: Eli Cohen <eli@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/mlx5/mr.c')
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index bd41df95b6f0..e86dbbdb3836 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -415,6 +415,7 @@ static void clean_keys(struct mlx5_ib_dev *dev, int c)
int size;
int err;
+ cancel_delayed_work(&ent->dwork);
while (1) {
spin_lock(&ent->lock);
if (list_empty(&ent->head)) {
@@ -540,13 +541,15 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev)
int i;
dev->cache.stopped = 1;
- destroy_workqueue(dev->cache.wq);
+ flush_workqueue(dev->cache.wq);
mlx5_mr_cache_debugfs_cleanup(dev);
for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++)
clean_keys(dev, i);
+ destroy_workqueue(dev->cache.wq);
+
return 0;
}