From d2aece53fabd8f3e6408502e06e57bb03653f621 Mon Sep 17 00:00:00 2001 From: Ville Juven Date: Fri, 10 Jan 2025 15:09:16 +0200 Subject: [PATCH] hrt_ioctl: Fix issue with SMP The interrupt handler needs to take the spinlock as well, as another CPU can be futzing around with the lists when another CPU takes the HRT trap. --- platforms/nuttx/src/px4/common/hrt_ioctl.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/platforms/nuttx/src/px4/common/hrt_ioctl.c b/platforms/nuttx/src/px4/common/hrt_ioctl.c index c5f0618dd34f..9e2c8a6d9f6f 100644 --- a/platforms/nuttx/src/px4/common/hrt_ioctl.c +++ b/platforms/nuttx/src/px4/common/hrt_ioctl.c @@ -143,8 +143,6 @@ static struct usr_hrt_call *dup_entry(const px4_hrt_handle_t handle, struct hrt_ e = (void *)sq_remfirst(&callout_freelist); } - spin_unlock_irqrestore_wo_note(&g_hrt_ioctl_lock, flags); - if (!e) { /* Allocate a new kernel side item for the user call */ @@ -152,7 +150,6 @@ static struct usr_hrt_call *dup_entry(const px4_hrt_handle_t handle, struct hrt_ } if (e) { - /* Store the user side callout function and argument to the user's handle */ entry->callout = callout; entry->arg = arg; @@ -165,15 +162,16 @@ static struct usr_hrt_call *dup_entry(const px4_hrt_handle_t handle, struct hrt_ e->usr_entry = entry; /* Add this to the callout_queue list */ - flags = spin_lock_irqsave_wo_note(&g_hrt_ioctl_lock); + sq_addfirst(&e->list_item, &callout_queue); - spin_unlock_irqrestore_wo_note(&g_hrt_ioctl_lock, flags); } else { PX4_ERR("out of memory"); } + spin_unlock_irqrestore_wo_note(&g_hrt_ioctl_lock, flags); + return e; } @@ -181,6 +179,7 @@ void hrt_usr_call(void *arg) { // This is called from hrt interrupt struct usr_hrt_call *e = (struct usr_hrt_call *)arg; + irqstate_t flags = spin_lock_irqsave_wo_note(&g_hrt_ioctl_lock); // Make sure the event is not already in flight if (!entry_inlist(&callout_inflight, (sq_entry_t *)e)) { @@ -188,6 +187,8 @@ void hrt_usr_call(void *arg) sq_addfirst(&e->list_item, &callout_inflight); px4_sem_post(e->entry.callout_sem); } + + spin_unlock_irqrestore_wo_note(&g_hrt_ioctl_lock, flags); } int hrt_ioctl(unsigned int cmd, unsigned long arg);