Skip to content

Commit aba0e90

Browse files
mosheshemesh2kuba-moo
authored andcommitted
devlink: Hold devlink lock on health reporter dump get
Devlink health dump get callback should take devlink lock as any other devlink callback. Otherwise, since devlink_mutex was removed, this callback is not protected from a race of the reporter being destroyed while handling the callback. Add devlink lock to the callback and to any call for devlink_health_do_dump(). This should be safe as non of the drivers dump callback implementation takes devlink lock. As devlink lock is added to any callback of dump, the reporter dump_lock is now redundant and can be removed. Fixes: d3efc2a ("net: devlink: remove devlink_mutex") Signed-off-by: Moshe Shemesh <moshe@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Link: https://lore.kernel.org/r/1696510216-189379-1-git-send-email-moshe@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent c4d4919 commit aba0e90

1 file changed

Lines changed: 16 additions & 14 deletions

File tree

net/devlink/health.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ struct devlink_health_reporter {
5858
struct devlink *devlink;
5959
struct devlink_port *devlink_port;
6060
struct devlink_fmsg *dump_fmsg;
61-
struct mutex dump_lock; /* lock parallel read/write from dump buffers */
6261
u64 graceful_period;
6362
bool auto_recover;
6463
bool auto_dump;
@@ -125,7 +124,6 @@ __devlink_health_reporter_create(struct devlink *devlink,
125124
reporter->graceful_period = graceful_period;
126125
reporter->auto_recover = !!ops->recover;
127126
reporter->auto_dump = !!ops->dump;
128-
mutex_init(&reporter->dump_lock);
129127
return reporter;
130128
}
131129

@@ -226,7 +224,6 @@ EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
226224
static void
227225
devlink_health_reporter_free(struct devlink_health_reporter *reporter)
228226
{
229-
mutex_destroy(&reporter->dump_lock);
230227
if (reporter->dump_fmsg)
231228
devlink_fmsg_free(reporter->dump_fmsg);
232229
kfree(reporter);
@@ -625,10 +622,10 @@ int devlink_health_report(struct devlink_health_reporter *reporter,
625622
}
626623

627624
if (reporter->auto_dump) {
628-
mutex_lock(&reporter->dump_lock);
625+
devl_lock(devlink);
629626
/* store current dump of current error, for later analysis */
630627
devlink_health_do_dump(reporter, priv_ctx, NULL);
631-
mutex_unlock(&reporter->dump_lock);
628+
devl_unlock(devlink);
632629
}
633630

634631
if (!reporter->auto_recover)
@@ -1262,7 +1259,7 @@ int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
12621259
}
12631260

12641261
static struct devlink_health_reporter *
1265-
devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
1262+
devlink_health_reporter_get_from_cb_lock(struct netlink_callback *cb)
12661263
{
12671264
const struct genl_info *info = genl_info_dump(cb);
12681265
struct devlink_health_reporter *reporter;
@@ -1272,10 +1269,12 @@ devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
12721269
devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
12731270
if (IS_ERR(devlink))
12741271
return NULL;
1275-
devl_unlock(devlink);
12761272

12771273
reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
1278-
devlink_put(devlink);
1274+
if (!reporter) {
1275+
devl_unlock(devlink);
1276+
devlink_put(devlink);
1277+
}
12791278
return reporter;
12801279
}
12811280

@@ -1284,16 +1283,20 @@ int devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
12841283
{
12851284
struct devlink_nl_dump_state *state = devlink_dump_state(cb);
12861285
struct devlink_health_reporter *reporter;
1286+
struct devlink *devlink;
12871287
int err;
12881288

1289-
reporter = devlink_health_reporter_get_from_cb(cb);
1289+
reporter = devlink_health_reporter_get_from_cb_lock(cb);
12901290
if (!reporter)
12911291
return -EINVAL;
12921292

1293-
if (!reporter->ops->dump)
1293+
devlink = reporter->devlink;
1294+
if (!reporter->ops->dump) {
1295+
devl_unlock(devlink);
1296+
devlink_put(devlink);
12941297
return -EOPNOTSUPP;
1298+
}
12951299

1296-
mutex_lock(&reporter->dump_lock);
12971300
if (!state->idx) {
12981301
err = devlink_health_do_dump(reporter, NULL, cb->extack);
12991302
if (err)
@@ -1309,7 +1312,8 @@ int devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
13091312
err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
13101313
DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
13111314
unlock:
1312-
mutex_unlock(&reporter->dump_lock);
1315+
devl_unlock(devlink);
1316+
devlink_put(devlink);
13131317
return err;
13141318
}
13151319

@@ -1326,9 +1330,7 @@ int devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
13261330
if (!reporter->ops->dump)
13271331
return -EOPNOTSUPP;
13281332

1329-
mutex_lock(&reporter->dump_lock);
13301333
devlink_health_dump_clear(reporter);
1331-
mutex_unlock(&reporter->dump_lock);
13321334
return 0;
13331335
}
13341336

0 commit comments

Comments
 (0)