Skip to content

Commit 94ddc14

Browse files
committed
Merge tag 'scmi-fixes-6.15' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes
Arm SCMI fixes for v6.15 Couple of fixes addressing issues with timeout in the polling path and device reference count imbalance detected by kmemleak. 1. The change fixes a timeout issue in the polling path of SCMI transactions where false positives could occur if the polling thread was pre-empted, causing it to appear as though a timeout occurred when it hadn't. The fix ensures that the polling result is verified before reporting a timeout, accounting for potential pre-emption or out-of-order replies. 2. It also corrects a device reference count imbalance caused by device_find_child() during device destruction, which prevented proper cleanup and triggered memory leaks detected by KMemleak. * tag 'scmi-fixes-6.15' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: firmware: arm_scmi: Fix timeout checks on polling path firmware: arm_scmi: Balance device refcount when destroying devices
2 parents 9c32cda + c23c03b commit 94ddc14

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

drivers/firmware/arm_scmi/bus.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,9 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent,
255255
if (!dev)
256256
return NULL;
257257

258+
/* Drop the refcnt bumped implicitly by device_find_child */
259+
put_device(dev);
260+
258261
return to_scmi_dev(dev);
259262
}
260263

drivers/firmware/arm_scmi/driver.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,7 +1248,8 @@ static void xfer_put(const struct scmi_protocol_handle *ph,
12481248
}
12491249

12501250
static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
1251-
struct scmi_xfer *xfer, ktime_t stop)
1251+
struct scmi_xfer *xfer, ktime_t stop,
1252+
bool *ooo)
12521253
{
12531254
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
12541255

@@ -1257,7 +1258,7 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
12571258
* in case of out-of-order receptions of delayed responses
12581259
*/
12591260
return info->desc->ops->poll_done(cinfo, xfer) ||
1260-
try_wait_for_completion(&xfer->done) ||
1261+
(*ooo = try_wait_for_completion(&xfer->done)) ||
12611262
ktime_after(ktime_get(), stop);
12621263
}
12631264

@@ -1274,15 +1275,17 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
12741275
* itself to support synchronous commands replies.
12751276
*/
12761277
if (!desc->sync_cmds_completed_on_ret) {
1278+
bool ooo = false;
1279+
12771280
/*
12781281
* Poll on xfer using transport provided .poll_done();
12791282
* assumes no completion interrupt was available.
12801283
*/
12811284
ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
12821285

1283-
spin_until_cond(scmi_xfer_done_no_timeout(cinfo,
1284-
xfer, stop));
1285-
if (ktime_after(ktime_get(), stop)) {
1286+
spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer,
1287+
stop, &ooo));
1288+
if (!ooo && !info->desc->ops->poll_done(cinfo, xfer)) {
12861289
dev_err(dev,
12871290
"timed out in resp(caller: %pS) - polling\n",
12881291
(void *)_RET_IP_);

0 commit comments

Comments
 (0)