diff options
author | Moshe Lazer <moshel@mellanox.com> | 2013-09-11 16:35:23 +0300 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-10-10 09:23:55 -0700 |
commit | 3c4619114cb6760d2c97fd562ea96d2c8786b56a (patch) | |
tree | 35b284517c269572ab2c7b7ab2317e6f777d0da3 /drivers/infiniband | |
parent | b125a54bfd7734a44253d2f2909a3c609768c1ec (diff) |
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')
-rw-r--r-- | drivers/infiniband/hw/mlx5/mr.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index bd41df95b6f..e86dbbdb383 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; } |