Skip to content

Commit 5502e87

Browse files
Jiri Pirkokuba-moo
authored andcommitted
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>
1 parent 1515a1b commit 5502e87

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

net/core/devlink.c

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5894,21 +5894,28 @@ static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
58945894
{
58955895
unsigned long count;
58965896
void *p;
5897+
int err;
58975898

5898-
devl_assert_locked(devlink);
5899-
5899+
xa_lock(&devlink->snapshot_ids);
59005900
p = xa_load(&devlink->snapshot_ids, id);
5901-
if (WARN_ON(!p))
5902-
return -EINVAL;
5901+
if (WARN_ON(!p)) {
5902+
err = -EINVAL;
5903+
goto unlock;
5904+
}
59035905

5904-
if (WARN_ON(!xa_is_value(p)))
5905-
return -EINVAL;
5906+
if (WARN_ON(!xa_is_value(p))) {
5907+
err = -EINVAL;
5908+
goto unlock;
5909+
}
59065910

59075911
count = xa_to_value(p);
59085912
count++;
59095913

5910-
return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5911-
GFP_KERNEL));
5914+
err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5915+
GFP_ATOMIC));
5916+
unlock:
5917+
xa_unlock(&devlink->snapshot_ids);
5918+
return err;
59125919
}
59135920

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

5934-
devl_assert_locked(devlink);
5935-
5941+
xa_lock(&devlink->snapshot_ids);
59365942
p = xa_load(&devlink->snapshot_ids, id);
59375943
if (WARN_ON(!p))
5938-
return;
5944+
goto unlock;
59395945

59405946
if (WARN_ON(!xa_is_value(p)))
5941-
return;
5947+
goto unlock;
59425948

59435949
count = xa_to_value(p);
59445950

59455951
if (count > 1) {
59465952
count--;
5947-
xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5948-
GFP_KERNEL);
5953+
__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5954+
GFP_ATOMIC);
59495955
} else {
59505956
/* If this was the last user, we can erase this id */
5951-
xa_erase(&devlink->snapshot_ids, id);
5957+
__xa_erase(&devlink->snapshot_ids, id);
59525958
}
5959+
unlock:
5960+
xa_unlock(&devlink->snapshot_ids);
59535961
}
59545962

59555963
/**
@@ -5970,13 +5978,17 @@ static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
59705978
*/
59715979
static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
59725980
{
5973-
devl_assert_locked(devlink);
5981+
int err;
59745982

5975-
if (xa_load(&devlink->snapshot_ids, id))
5983+
xa_lock(&devlink->snapshot_ids);
5984+
if (xa_load(&devlink->snapshot_ids, id)) {
5985+
xa_unlock(&devlink->snapshot_ids);
59765986
return -EEXIST;
5977-
5978-
return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
5979-
GFP_KERNEL));
5987+
}
5988+
err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
5989+
GFP_ATOMIC));
5990+
xa_unlock(&devlink->snapshot_ids);
5991+
return err;
59805992
}
59815993

59825994
/**
@@ -5997,8 +6009,6 @@ static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
59976009
*/
59986010
static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
59996011
{
6000-
devl_assert_locked(devlink);
6001-
60026012
return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
60036013
xa_limit_32b, GFP_KERNEL);
60046014
}
@@ -11442,13 +11452,7 @@ EXPORT_SYMBOL_GPL(devlink_region_destroy);
1144211452
*/
1144311453
int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
1144411454
{
11445-
int err;
11446-
11447-
devl_lock(devlink);
11448-
err = __devlink_region_snapshot_id_get(devlink, id);
11449-
devl_unlock(devlink);
11450-
11451-
return err;
11455+
return __devlink_region_snapshot_id_get(devlink, id);
1145211456
}
1145311457
EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
1145411458

@@ -11464,9 +11468,7 @@ EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
1146411468
*/
1146511469
void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
1146611470
{
11467-
devl_lock(devlink);
1146811471
__devlink_snapshot_id_decrement(devlink, id);
11469-
devl_unlock(devlink);
1147011472
}
1147111473
EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
1147211474

0 commit comments

Comments
 (0)