IB/mlx5: Protect against prefetch of invalid MR
[linux-2.6-block.git] / drivers / infiniband / hw / mlx5 / mr.c
index 705a79cd21da06c02a4e453c1d739287f026e7a1..c85f002558843ff50402bf14ba14ede892beb911 100644 (file)
@@ -1339,8 +1339,10 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                }
        }
 
-       if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING))
+       if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) {
                mr->live = 1;
+               atomic_set(&mr->num_pending_prefetch, 0);
+       }
 
        return &mr->ibmr;
 error:
@@ -1576,8 +1578,16 @@ static void dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
        if (is_odp_mr(mr)) {
                struct ib_umem_odp *umem_odp = to_ib_umem_odp(umem);
 
-               /* Prevent new page faults from succeeding */
+               /* Prevent new page faults and
+                * prefetch requests from succeeding
+                */
                mr->live = 0;
+
+               /* dequeue pending prefetch requests for the mr */
+               if (atomic_read(&mr->num_pending_prefetch))
+                       flush_workqueue(system_unbound_wq);
+               WARN_ON(atomic_read(&mr->num_pending_prefetch));
+
                /* Wait for all running page-fault handlers to finish. */
                synchronize_srcu(&dev->mr_srcu);
                /* Destroy all page mappings */