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: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
1515a1b899
commit
5502e8712c
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user