diff options
author | Moshe Lazer <moshel@mellanox.com> | 2013-09-11 09:35:23 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-10-10 12:23:55 -0400 |
commit | 3c4619114cb6760d2c97fd562ea96d2c8786b56a (patch) | |
tree | 35b284517c269572ab2c7b7ab2317e6f777d0da3 /drivers/infiniband/hw/mlx5/mr.c | |
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/hw/mlx5/mr.c')
-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 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 | ||