From f8bd93575c5ab2412a4c3f2307923fb6802517ce Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Sat, 14 Sep 2024 18:15:23 +0800 Subject: [PATCH] sched/wqueue: Fix unexpected dq entry status When we do not drop notifier from g_notifier_pending, we need an isolated dq entry for this queue, otherwise the queued work_s's dq entry may be modified by the work queue and breaks the chain of g_notifier_pending. Signed-off-by: Zhe Weng --- sched/wqueue/kwork_notifier.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sched/wqueue/kwork_notifier.c b/sched/wqueue/kwork_notifier.c index 2136b41f82..37bb6d16f1 100644 --- a/sched/wqueue/kwork_notifier.c +++ b/sched/wqueue/kwork_notifier.c @@ -53,10 +53,9 @@ struct work_notifier_entry_s { - /* This must appear at the beginning of the structure. A reference to - * the struct work_notifier_entry_s instance must be cast-compatible with - * struct dq_entry_s. - */ + struct dq_entry_s entry; + + /* The work structure */ struct work_s work; /* Used for scheduling the work */ @@ -170,11 +169,11 @@ static void work_notifier_worker(FAR void *arg) /* Remove the notification from the pending list */ - dq_rem((FAR dq_entry_t *)notifier, &g_notifier_pending); + dq_rem(¬ifier->entry, &g_notifier_pending); /* Put the notification to the free list */ - dq_addlast((FAR dq_entry_t *)notifier, &g_notifier_free); + dq_addlast(¬ifier->entry, &g_notifier_free); leave_critical_section(flags); } @@ -259,7 +258,7 @@ int work_notifier_setup(FAR struct work_notifier_s *info) * notifications executed in a saner order? */ - dq_addlast((FAR dq_entry_t *)notifier, &g_notifier_pending); + dq_addlast(¬ifier->entry, &g_notifier_pending); ret = notifier->key; leave_critical_section(flags); @@ -308,11 +307,11 @@ void work_notifier_teardown(int key) { /* Remove the notification from the pending list */ - dq_rem((FAR dq_entry_t *)notifier, &g_notifier_pending); + dq_rem(¬ifier->entry, &g_notifier_pending); /* Put the notification to the free list */ - dq_addlast((FAR dq_entry_t *)notifier, &g_notifier_free); + dq_addlast(¬ifier->entry, &g_notifier_free); } }