Skip to content

Commit 2290ab4

Browse files
cris-masudeep-holla
authored andcommitted
firmware: arm_scmi: Account for failed debug initialization
When the SCMI debug subsystem fails to initialize, the related debug root will be missing, and the underlying descriptor will be NULL. Handle this fault condition in the SCMI debug helpers that maintain metrics counters. Fixes: 0b3d48c ("firmware: arm_scmi: Track basic SCMI communication debug metrics") Signed-off-by: Cristian Marussi <[email protected]> Message-Id: <[email protected]> Signed-off-by: Sudeep Holla <[email protected]>
1 parent 3a86608 commit 2290ab4

2 files changed

Lines changed: 35 additions & 33 deletions

File tree

drivers/firmware/arm_scmi/common.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,28 @@ enum debug_counters {
309309
SCMI_DEBUG_COUNTERS_LAST
310310
};
311311

312-
static inline void scmi_inc_count(atomic_t *arr, int stat)
312+
/**
313+
* struct scmi_debug_info - Debug common info
314+
* @top_dentry: A reference to the top debugfs dentry
315+
* @name: Name of this SCMI instance
316+
* @type: Type of this SCMI instance
317+
* @is_atomic: Flag to state if the transport of this instance is atomic
318+
* @counters: An array of atomic_c's used for tracking statistics (if enabled)
319+
*/
320+
struct scmi_debug_info {
321+
struct dentry *top_dentry;
322+
const char *name;
323+
const char *type;
324+
bool is_atomic;
325+
atomic_t counters[SCMI_DEBUG_COUNTERS_LAST];
326+
};
327+
328+
static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat)
313329
{
314-
if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS))
315-
atomic_inc(&arr[stat]);
330+
if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) {
331+
if (dbg)
332+
atomic_inc(&dbg->counters[stat]);
333+
}
316334
}
317335

318336
static inline void scmi_dec_count(atomic_t *arr, int stat)

drivers/firmware/arm_scmi/driver.c

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -115,22 +115,6 @@ struct scmi_protocol_instance {
115115

116116
#define ph_to_pi(h) container_of(h, struct scmi_protocol_instance, ph)
117117

118-
/**
119-
* struct scmi_debug_info - Debug common info
120-
* @top_dentry: A reference to the top debugfs dentry
121-
* @name: Name of this SCMI instance
122-
* @type: Type of this SCMI instance
123-
* @is_atomic: Flag to state if the transport of this instance is atomic
124-
* @counters: An array of atomic_c's used for tracking statistics (if enabled)
125-
*/
126-
struct scmi_debug_info {
127-
struct dentry *top_dentry;
128-
const char *name;
129-
const char *type;
130-
bool is_atomic;
131-
atomic_t counters[SCMI_DEBUG_COUNTERS_LAST];
132-
};
133-
134118
/**
135119
* struct scmi_info - Structure representing a SCMI instance
136120
*
@@ -1034,7 +1018,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
10341018
spin_unlock_irqrestore(&minfo->xfer_lock, flags);
10351019

10361020
scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED);
1037-
scmi_inc_count(info->dbg->counters, ERR_MSG_UNEXPECTED);
1021+
scmi_inc_count(info->dbg, ERR_MSG_UNEXPECTED);
10381022

10391023
return xfer;
10401024
}
@@ -1062,7 +1046,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
10621046
msg_type, xfer_id, msg_hdr, xfer->state);
10631047

10641048
scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID);
1065-
scmi_inc_count(info->dbg->counters, ERR_MSG_INVALID);
1049+
scmi_inc_count(info->dbg, ERR_MSG_INVALID);
10661050

10671051
/* On error the refcount incremented above has to be dropped */
10681052
__scmi_xfer_put(minfo, xfer);
@@ -1107,7 +1091,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
11071091
PTR_ERR(xfer));
11081092

11091093
scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM);
1110-
scmi_inc_count(info->dbg->counters, ERR_MSG_NOMEM);
1094+
scmi_inc_count(info->dbg, ERR_MSG_NOMEM);
11111095

11121096
scmi_clear_channel(info, cinfo);
11131097
return;
@@ -1123,7 +1107,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
11231107
trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id,
11241108
xfer->hdr.id, "NOTI", xfer->hdr.seq,
11251109
xfer->hdr.status, xfer->rx.buf, xfer->rx.len);
1126-
scmi_inc_count(info->dbg->counters, NOTIFICATION_OK);
1110+
scmi_inc_count(info->dbg, NOTIFICATION_OK);
11271111

11281112
scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
11291113
xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts);
@@ -1183,10 +1167,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
11831167
if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) {
11841168
scmi_clear_channel(info, cinfo);
11851169
complete(xfer->async_done);
1186-
scmi_inc_count(info->dbg->counters, DELAYED_RESPONSE_OK);
1170+
scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK);
11871171
} else {
11881172
complete(&xfer->done);
1189-
scmi_inc_count(info->dbg->counters, RESPONSE_OK);
1173+
scmi_inc_count(info->dbg, RESPONSE_OK);
11901174
}
11911175

11921176
if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
@@ -1296,7 +1280,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
12961280
"timed out in resp(caller: %pS) - polling\n",
12971281
(void *)_RET_IP_);
12981282
ret = -ETIMEDOUT;
1299-
scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_POLLED_TIMEOUT);
1283+
scmi_inc_count(info->dbg, XFERS_RESPONSE_POLLED_TIMEOUT);
13001284
}
13011285
}
13021286

@@ -1321,7 +1305,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
13211305
"RESP" : "resp",
13221306
xfer->hdr.seq, xfer->hdr.status,
13231307
xfer->rx.buf, xfer->rx.len);
1324-
scmi_inc_count(info->dbg->counters, RESPONSE_POLLED_OK);
1308+
scmi_inc_count(info->dbg, RESPONSE_POLLED_OK);
13251309

13261310
if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
13271311
scmi_raw_message_report(info->raw, xfer,
@@ -1336,7 +1320,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc,
13361320
dev_err(dev, "timed out in resp(caller: %pS)\n",
13371321
(void *)_RET_IP_);
13381322
ret = -ETIMEDOUT;
1339-
scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_TIMEOUT);
1323+
scmi_inc_count(info->dbg, XFERS_RESPONSE_TIMEOUT);
13401324
}
13411325
}
13421326

@@ -1420,13 +1404,13 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
14201404
!is_transport_polling_capable(info->desc)) {
14211405
dev_warn_once(dev,
14221406
"Polling mode is not supported by transport.\n");
1423-
scmi_inc_count(info->dbg->counters, SENT_FAIL_POLLING_UNSUPPORTED);
1407+
scmi_inc_count(info->dbg, SENT_FAIL_POLLING_UNSUPPORTED);
14241408
return -EINVAL;
14251409
}
14261410

14271411
cinfo = idr_find(&info->tx_idr, pi->proto->id);
14281412
if (unlikely(!cinfo)) {
1429-
scmi_inc_count(info->dbg->counters, SENT_FAIL_CHANNEL_NOT_FOUND);
1413+
scmi_inc_count(info->dbg, SENT_FAIL_CHANNEL_NOT_FOUND);
14301414
return -EINVAL;
14311415
}
14321416
/* True ONLY if also supported by transport. */
@@ -1461,19 +1445,19 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
14611445
ret = info->desc->ops->send_message(cinfo, xfer);
14621446
if (ret < 0) {
14631447
dev_dbg(dev, "Failed to send message %d\n", ret);
1464-
scmi_inc_count(info->dbg->counters, SENT_FAIL);
1448+
scmi_inc_count(info->dbg, SENT_FAIL);
14651449
return ret;
14661450
}
14671451

14681452
trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id,
14691453
xfer->hdr.id, "CMND", xfer->hdr.seq,
14701454
xfer->hdr.status, xfer->tx.buf, xfer->tx.len);
1471-
scmi_inc_count(info->dbg->counters, SENT_OK);
1455+
scmi_inc_count(info->dbg, SENT_OK);
14721456

14731457
ret = scmi_wait_for_message_response(cinfo, xfer);
14741458
if (!ret && xfer->hdr.status) {
14751459
ret = scmi_to_linux_errno(xfer->hdr.status);
1476-
scmi_inc_count(info->dbg->counters, ERR_PROTOCOL);
1460+
scmi_inc_count(info->dbg, ERR_PROTOCOL);
14771461
}
14781462

14791463
if (info->desc->ops->mark_txdone)

0 commit comments

Comments
 (0)