IB/mlx5: Flush cache workqueue before destroying it
authorMoshe Lazer <moshel@mellanox.com>
Wed, 11 Sep 2013 13:35:23 +0000 (16:35 +0300)
committerRoland Dreier <roland@purestorage.com>
Thu, 10 Oct 2013 16:23:55 +0000 (09:23 -0700)
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>
drivers/infiniband/hw/mlx5/mr.c

index bd41df95b6f0214deb445ab228be8d157373074f..e86dbbdb38369f445b10768cc62230415f5773ee 100644 (file)
@@ -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;
 }