aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoshe Lazer <moshel@mellanox.com>2013-09-11 09:35:23 -0400
committerRoland Dreier <roland@purestorage.com>2013-10-10 12:23:55 -0400
commit3c4619114cb6760d2c97fd562ea96d2c8786b56a (patch)
tree35b284517c269572ab2c7b7ab2317e6f777d0da3
parentb125a54bfd7734a44253d2f2909a3c609768c1ec (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>
-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)
415 int size; 415 int size;
416 int err; 416 int err;
417 417
418 cancel_delayed_work(&ent->dwork);
418 while (1) { 419 while (1) {
419 spin_lock(&ent->lock); 420 spin_lock(&ent->lock);
420 if (list_empty(&ent->head)) { 421 if (list_empty(&ent->head)) {
@@ -540,13 +541,15 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev)
540 int i; 541 int i;
541 542
542 dev->cache.stopped = 1; 543 dev->cache.stopped = 1;
543 destroy_workqueue(dev->cache.wq); 544 flush_workqueue(dev->cache.wq);
544 545
545 mlx5_mr_cache_debugfs_cleanup(dev); 546 mlx5_mr_cache_debugfs_cleanup(dev);
546 547
547 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) 548 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++)
548 clean_keys(dev, i); 549 clean_keys(dev, i);
549 550
551 destroy_workqueue(dev->cache.wq);
552
550 return 0; 553 return 0;
551} 554}
552 555