Skip to content

Commit 9cc2cb3

Browse files
authored
[spinel] improve RCP crash dump request logic (openthread#13150)
This commit updates the RCP crash dump request logic to provide better debug information while ensuring the recovery process is not interrupted: - `RadioSpinel::HandleRcpUnexpectedReset` now explicitly clears `mWaitingTid` and requests a crash dump if RCP restoration is disabled before proceeding with the abort / exit logic. If RCP restoration is enabled, request for crash dump will be deferred to `RecoverFromRcpFailure`, before resetting the coprocessor. - Updates crash dump requests to use `IgnoreReturnValue` instead. Failing to retrieve a crash dump is not a fatal error and should not halt the initialization or recovery process.
1 parent 54323a2 commit 9cc2cb3

1 file changed

Lines changed: 37 additions & 11 deletions

File tree

src/lib/spinel/radio_spinel.cpp

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ void RadioSpinel::Init(bool aSkipRcpVersionCheck,
157157
if (sSupportsLogCrashDump)
158158
{
159159
LogDebg("RCP supports crash dump logging. Requesting crash dump.");
160-
SuccessOrExit(error = Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
160+
IgnoreReturnValue(Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
161161
}
162162

163163
if (!aSkipRcpVersionCheck)
@@ -1328,14 +1328,17 @@ otError RadioSpinel::Set(spinel_prop_key_t aKey, const char *aFormat, ...)
13281328
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
13291329
do
13301330
{
1331-
RecoverFromRcpFailure();
1331+
if (aKey != SPINEL_PROP_RCP_LOG_CRASH_DUMP)
1332+
{
1333+
RecoverFromRcpFailure();
1334+
}
13321335
#endif
13331336
va_start(mPropertyArgs, aFormat);
13341337
error = RequestWithExpectedCommandV(SPINEL_CMD_PROP_VALUE_IS, SPINEL_CMD_PROP_VALUE_SET, aKey, aFormat,
13351338
mPropertyArgs);
13361339
va_end(mPropertyArgs);
13371340
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
1338-
} while (mRcpFailure != kRcpFailureNone);
1341+
} while (aKey != SPINEL_PROP_RCP_LOG_CRASH_DUMP && mRcpFailure != kRcpFailureNone);
13391342
#endif
13401343

13411344
return error;
@@ -1399,19 +1402,31 @@ otError RadioSpinel::WaitResponse(bool aHandleRcpTimeout)
13991402
if ((end <= now) || (GetSpinelDriver().GetSpinelInterface()->WaitForFrame(end - now) != OT_ERROR_NONE))
14001403
{
14011404
LogWarn("Wait for response timeout");
1402-
if (aHandleRcpTimeout)
1405+
// Skip RCP timeout handling for the non-essential crash dump property
1406+
if (aHandleRcpTimeout && mWaitingKey != SPINEL_PROP_RCP_LOG_CRASH_DUMP)
14031407
{
14041408
HandleRcpTimeout();
14051409
}
14061410
ExitNow(mError = OT_ERROR_RESPONSE_TIMEOUT);
14071411
}
1412+
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
1413+
if (mRcpFailure != kRcpFailureNone)
1414+
{
1415+
ExitNow(mError = OT_ERROR_RESPONSE_TIMEOUT);
1416+
}
1417+
#endif
14081418
} while (mWaitingTid);
14091419

14101420
LogIfFail("Error waiting response", mError);
14111421
// This indicates end of waiting response.
14121422
mWaitingKey = SPINEL_PROP_LAST_STATUS;
14131423

14141424
exit:
1425+
if (mError != OT_ERROR_NONE && mWaitingTid != 0)
1426+
{
1427+
FreeTid(mWaitingTid);
1428+
mWaitingTid = 0;
1429+
}
14151430
return mError;
14161431
}
14171432

@@ -1991,11 +2006,20 @@ void RadioSpinel::HandleRcpUnexpectedReset(spinel_status_t aStatus)
19912006

19922007
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
19932008
mRcpFailure = kRcpFailureUnexpectedReset;
1994-
#elif OPENTHREAD_SPINEL_CONFIG_ABORT_ON_UNEXPECTED_RCP_RESET_ENABLE
2009+
#else
2010+
if (sSupportsLogCrashDump)
2011+
{
2012+
mWaitingTid = 0;
2013+
LogDebg("RCP supports crash dump logging. Requesting crash dump.");
2014+
IgnoreReturnValue(Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
2015+
}
2016+
2017+
#if OPENTHREAD_SPINEL_CONFIG_ABORT_ON_UNEXPECTED_RCP_RESET_ENABLE
19952018
abort();
19962019
#else
19972020
DieNow(OT_EXIT_RADIO_SPINEL_RESET);
19982021
#endif
2022+
#endif
19992023
}
20002024

20012025
void RadioSpinel::HandleRcpTimeout(void)
@@ -2044,6 +2068,14 @@ void RadioSpinel::RecoverFromRcpFailure(void)
20442068
DieNow(OT_EXIT_FAILURE);
20452069
}
20462070

2071+
if (sSupportsLogCrashDump)
2072+
{
2073+
mWaitingTid = 0;
2074+
LogDebg("RCP supports crash dump logging. Requesting crash dump.");
2075+
IgnoreReturnValue(Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
2076+
mRcpFailure = kRcpFailureNone;
2077+
}
2078+
20472079
LogWarn("Trying to recover (%d/%d)", mRcpFailureCount, kMaxFailureCount);
20482080

20492081
mState = kStateDisabled;
@@ -2106,12 +2138,6 @@ void RadioSpinel::RecoverFromRcpFailure(void)
21062138

21072139
--mRcpFailureCount;
21082140

2109-
if (sSupportsLogCrashDump)
2110-
{
2111-
LogDebg("RCP supports crash dump logging. Requesting crash dump.");
2112-
SuccessOrDie(Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
2113-
}
2114-
21152141
LogNote("RCP recovery is done");
21162142

21172143
exit:

0 commit comments

Comments
 (0)