git: c56e586f0f02 - main - scmi: Fix race on timed out transmissions

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Thu, 23 Jan 2025 17:27:30 UTC
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=c56e586f0f029fec4a0fee844f83ff62da20e4b6

commit c56e586f0f029fec4a0fee844f83ff62da20e4b6
Author:     Cristian Marussi <cristian.marussi@arm.com>
AuthorDate: 2025-01-23 12:46:38 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2025-01-23 17:26:26 +0000

    scmi: Fix race on timed out transmissions
    
    When a waited-for outstanding request is determined to have timed out,
    mark such request immediately as such, so as to avoid any possible race on
    the IRQ path with code path evaluating that same timed out condition.
    
    Tested on:      Arm Morello Board
    Reviewed by:    andrew
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D47419
    Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
 sys/dev/firmware/arm/scmi.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/sys/dev/firmware/arm/scmi.c b/sys/dev/firmware/arm/scmi.c
index c2585d8d9637..37496136c828 100644
--- a/sys/dev/firmware/arm/scmi.c
+++ b/sys/dev/firmware/arm/scmi.c
@@ -545,6 +545,7 @@ scmi_wait_for_response(struct scmi_softc *sc, struct scmi_req *req, void **out)
 		 */
 		mtx_lock_spin(&req->mtx);
 		needs_drop = (ret == 0) && !req->done;
+		req->timed_out = ret != 0;
 		mtx_unlock_spin(&req->mtx);
 		if (needs_drop)
 			scmi_req_drop_inflight(sc, req);
@@ -560,6 +561,7 @@ scmi_wait_for_response(struct scmi_softc *sc, struct scmi_req *req, void **out)
 		mtx_lock_spin(&req->mtx);
 		if (ret != 0 && req->done)
 			ret = 0;
+		req->timed_out = ret != 0;
 		mtx_unlock_spin(&req->mtx);
 	}
 
@@ -569,9 +571,6 @@ scmi_wait_for_response(struct scmi_softc *sc, struct scmi_req *req, void **out)
 			ret = req->msg.payld[0];
 		*out = &req->msg.payld[SCMI_MSG_HDR_SIZE];
 	} else {
-		mtx_lock_spin(&req->mtx);
-		req->timed_out = true;
-		mtx_unlock_spin(&req->mtx);
 		device_printf(sc->dev,
 		    "Request for token 0x%X timed-out.\n", req->token);
 	}