Commit 5502e871 authored by Jiri Pirko's avatar Jiri Pirko Committed by Jakub Kicinski
Browse files

net: devlink: remove region snapshot ID tracking dependency on devlink->lock



After mlx4 driver is converted to do locked reload, functions to get/put
regions snapshot ID may be called from both locked and unlocked context.

So resolve this by removing dependency on devlink->lock for region
snapshot ID tracking by using internal xa_lock() to maintain
shapshot_ids xa_array consistency.

Signed-off-by: default avatarJiri Pirko <jiri@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 1515a1b8
Loading
Loading
Loading
Loading
+33 −31
Original line number Diff line number Diff line
@@ -5894,21 +5894,28 @@ static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
{
	unsigned long count;
	void *p;
	int err;

	devl_assert_locked(devlink);

	xa_lock(&devlink->snapshot_ids);
	p = xa_load(&devlink->snapshot_ids, id);
	if (WARN_ON(!p))
		return -EINVAL;
	if (WARN_ON(!p)) {
		err = -EINVAL;
		goto unlock;
	}

	if (WARN_ON(!xa_is_value(p)))
		return -EINVAL;
	if (WARN_ON(!xa_is_value(p))) {
		err = -EINVAL;
		goto unlock;
	}

	count = xa_to_value(p);
	count++;

	return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
			       GFP_KERNEL));
	err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
				GFP_ATOMIC));
unlock:
	xa_unlock(&devlink->snapshot_ids);
	return err;
}

/**
@@ -5931,25 +5938,26 @@ static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
	unsigned long count;
	void *p;

	devl_assert_locked(devlink);

	xa_lock(&devlink->snapshot_ids);
	p = xa_load(&devlink->snapshot_ids, id);
	if (WARN_ON(!p))
		return;
		goto unlock;

	if (WARN_ON(!xa_is_value(p)))
		return;
		goto unlock;

	count = xa_to_value(p);

	if (count > 1) {
		count--;
		xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
			 GFP_KERNEL);
		__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
			   GFP_ATOMIC);
	} else {
		/* If this was the last user, we can erase this id */
		xa_erase(&devlink->snapshot_ids, id);
		__xa_erase(&devlink->snapshot_ids, id);
	}
unlock:
	xa_unlock(&devlink->snapshot_ids);
}

/**
@@ -5970,13 +5978,17 @@ static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
 */
static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
{
	devl_assert_locked(devlink);
	int err;

	if (xa_load(&devlink->snapshot_ids, id))
	xa_lock(&devlink->snapshot_ids);
	if (xa_load(&devlink->snapshot_ids, id)) {
		xa_unlock(&devlink->snapshot_ids);
		return -EEXIST;

	return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
			       GFP_KERNEL));
	}
	err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
				GFP_ATOMIC));
	xa_unlock(&devlink->snapshot_ids);
	return err;
}

/**
@@ -5997,8 +6009,6 @@ static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
 */
static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
{
	devl_assert_locked(devlink);

	return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
			xa_limit_32b, GFP_KERNEL);
}
@@ -11442,13 +11452,7 @@ EXPORT_SYMBOL_GPL(devlink_region_destroy);
 */
int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
{
	int err;

	devl_lock(devlink);
	err = __devlink_region_snapshot_id_get(devlink, id);
	devl_unlock(devlink);

	return err;
	return __devlink_region_snapshot_id_get(devlink, id);
}
EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);

@@ -11464,9 +11468,7 @@ EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
 */
void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
{
	devl_lock(devlink);
	__devlink_snapshot_id_decrement(devlink, id);
	devl_unlock(devlink);
}
EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);