Skip to content
/ linux Public
forked from torvalds/linux

Commit

Permalink
net: devlink: remove region snapshot ID tracking dependency on devlin…
Browse files Browse the repository at this point in the history
…k->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 <[email protected]>
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
Jiri Pirko authored and kuba-moo committed Jul 29, 2022
1 parent 1515a1b commit 5502e87
Showing 1 changed file with 33 additions and 31 deletions.
64 changes: 33 additions & 31 deletions net/core/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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;
}

/**
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down

0 comments on commit 5502e87

Please sign in to comment.