[PATCH 12/14] lib: sbi_sse: add TSA annotations
Carlos López
carlos.lopezr4096 at gmail.com
Wed Jul 29 09:35:39 PDT 2026
Now that the lock relationship between an event and its owner hart is
explicit, add TSA annotations for the SSE handling code. This includes
indicating which fields are protected by a spinlock, as well as
annotating which functions need to run under a spinlock.
Exclude sse_local_init(), which initializes the spinlock to be acquired,
and sse_event_get() / sse_event_put(), which perform conditional locking
that TSA is not able to follow properly.
Signed-off-by: Carlos López <carlos.lopezr4096 at gmail.com>
---
lib/sbi/sbi_sse.c | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/lib/sbi/sbi_sse.c b/lib/sbi/sbi_sse.c
index 9b630430173c..7b4d64b7cc63 100644
--- a/lib/sbi/sbi_sse.c
+++ b/lib/sbi/sbi_sse.c
@@ -108,6 +108,11 @@ struct sbi_sse_event {
/** Per-hart state */
struct sse_hart_state {
+ /**
+ * Lock that protects enabled_event_list
+ */
+ spinlock_t enabled_event_lock;
+
/* Priority sorted list of enabled events (global and local in >=
* ENABLED state). This list is protected by the enabled_event_lock.
*
@@ -124,12 +129,7 @@ struct sse_hart_state {
* this enabled_event_list and thus can only be removed from this
* list upon disable ecall or on complete with ONESHOT flag.
*/
- struct sbi_dlist enabled_event_list;
-
- /**
- * Lock that protects enabled_event_list
- */
- spinlock_t enabled_event_lock;
+ struct sbi_dlist enabled_event_list GUARDED_BY(&enabled_event_lock);
/**
* List of local events allocated at boot time.
@@ -147,16 +147,16 @@ struct sse_hart_state {
* Global events are accessible by all harts
*/
struct sse_global_event {
- /**
- * global event struct
- */
- struct sbi_sse_event event;
-
/**
* Global event lock protecting access from multiple harts from ecall to
* the event.
*/
spinlock_t lock;
+
+ /**
+ * global event struct
+ */
+ struct sbi_sse_event event GUARDED_BY(&lock);
};
struct sse_event_info {
@@ -272,7 +272,8 @@ static void sse_event_set_state(struct sbi_sse_event *e,
e->attrs.status |= new_state;
}
-static int sse_event_get(uint32_t event_id, struct sbi_sse_event **eret)
+static int sse_event_get(uint32_t event_id,
+ struct sbi_sse_event **eret) NO_THREAD_SAFETY_ANALYSIS
{
unsigned int i;
struct sbi_sse_event *e;
@@ -309,7 +310,7 @@ static int sse_event_get(uint32_t event_id, struct sbi_sse_event **eret)
return SBI_EINVAL;
}
-static void sse_event_put(struct sbi_sse_event *e)
+static void sse_event_put(struct sbi_sse_event *e) NO_THREAD_SAFETY_ANALYSIS
{
struct sse_global_event *ge;
@@ -330,6 +331,7 @@ static void sse_event_remove_from_list(struct sbi_sse_event *e)
*/
static void sse_event_add_to_list(struct sse_hart_state *state,
struct sbi_sse_event *e)
+ MUST_HOLD(&state->enabled_event_lock)
{
struct sbi_sse_event *tmp;
@@ -348,6 +350,7 @@ static void sse_event_add_to_list(struct sse_hart_state *state,
*/
static int sse_event_disable(struct sse_hart_state *shs,
struct sbi_sse_event *e)
+ MUST_HOLD(&shs->enabled_event_lock)
{
if (sse_event_state(e) != SBI_SSE_STATE_ENABLED)
return SBI_EINVALID_STATE;
@@ -786,6 +789,7 @@ static int sse_inject_event(uint32_t event_id, unsigned long hartid)
*/
static int sse_event_enable(struct sse_hart_state *shs,
struct sbi_sse_event *e)
+ MUST_HOLD(&shs->enabled_event_lock)
{
if (sse_event_state(e) != SBI_SSE_STATE_REGISTERED)
return SBI_EINVALID_STATE;
@@ -806,6 +810,7 @@ static int sse_event_complete(struct sse_hart_state *shs,
struct sbi_sse_event *e,
struct sbi_trap_regs *regs,
struct sbi_ecall_return *out)
+ MUST_HOLD(&shs->enabled_event_lock)
{
if (sse_event_state(e) != SBI_SSE_STATE_RUNNING)
return SBI_EINVALID_STATE;
@@ -1180,6 +1185,7 @@ static int sse_global_init()
}
static void sse_local_init(struct sse_hart_state *shs)
+ NO_THREAD_SAFETY_ANALYSIS
{
unsigned int ev = 0;
struct sse_event_info *info;
--
2.51.0
More information about the opensbi
mailing list