Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65edd0e7 authored by Daniel Jurgens's avatar Daniel Jurgens Committed by Doug Ledford
Browse files

IB/mlx5: Only synchronize RCU once when removing mkeys



Instead synchronizing RCU in a loop when removing mkeys in a batch do it
once at the end before freeing them. The result is only waiting for one
RCU grace period instead of many serially.

Signed-off-by: default avatarDaniel Jurgens <danielj@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 72f7cc09
Loading
Loading
Loading
Loading
+28 −16
Original line number Diff line number Diff line
@@ -220,25 +220,31 @@ static void remove_keys(struct mlx5_ib_dev *dev, int c, int num)
{
	struct mlx5_mr_cache *cache = &dev->cache;
	struct mlx5_cache_ent *ent = &cache->ent[c];
	struct mlx5_ib_mr *tmp_mr;
	struct mlx5_ib_mr *mr;
	int err;
	LIST_HEAD(del_list);
	int i;

	for (i = 0; i < num; i++) {
		spin_lock_irq(&ent->lock);
		if (list_empty(&ent->head)) {
			spin_unlock_irq(&ent->lock);
			return;
			break;
		}
		mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list);
		list_del(&mr->list);
		list_move(&mr->list, &del_list);
		ent->cur--;
		ent->size--;
		spin_unlock_irq(&ent->lock);
		err = destroy_mkey(dev, mr);
		if (err)
			mlx5_ib_warn(dev, "failed destroy mkey\n");
		else
		mlx5_core_destroy_mkey(dev->mdev, &mr->mmkey);
	}

#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
	synchronize_srcu(&dev->mr_srcu);
#endif

	list_for_each_entry_safe(mr, tmp_mr, &del_list, list) {
		list_del(&mr->list);
		kfree(mr);
	}
}
@@ -562,25 +568,31 @@ static void clean_keys(struct mlx5_ib_dev *dev, int c)
{
	struct mlx5_mr_cache *cache = &dev->cache;
	struct mlx5_cache_ent *ent = &cache->ent[c];
	struct mlx5_ib_mr *tmp_mr;
	struct mlx5_ib_mr *mr;
	int err;
	LIST_HEAD(del_list);

	cancel_delayed_work(&ent->dwork);
	while (1) {
		spin_lock_irq(&ent->lock);
		if (list_empty(&ent->head)) {
			spin_unlock_irq(&ent->lock);
			return;
			break;
		}
		mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list);
		list_del(&mr->list);
		list_move(&mr->list, &del_list);
		ent->cur--;
		ent->size--;
		spin_unlock_irq(&ent->lock);
		err = destroy_mkey(dev, mr);
		if (err)
			mlx5_ib_warn(dev, "failed destroy mkey\n");
		else
		mlx5_core_destroy_mkey(dev->mdev, &mr->mmkey);
	}

#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
	synchronize_srcu(&dev->mr_srcu);
#endif

	list_for_each_entry_safe(mr, tmp_mr, &del_list, list) {
		list_del(&mr->list);
		kfree(mr);
	}
}