Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spin_lock_irqsave+sched_lock #14578

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions arch/xtensa/src/esp32/esp32_ble_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -2353,12 +2353,7 @@ static int32_t esp_task_create_pinned_to_core(void *entry,
DEBUGASSERT(task_handle != NULL);

#ifdef CONFIG_SMP
ret = sched_lock();
if (ret)
{
wlerr("Failed to lock scheduler before creating pinned thread\n");
return false;
}
xiaoxiang781216 marked this conversation as resolved.
Show resolved Hide resolved
sched_lock();
#endif

pid = kthread_create(name, prio, stack_depth, entry,
Expand Down Expand Up @@ -2390,12 +2385,7 @@ static int32_t esp_task_create_pinned_to_core(void *entry,
}

#ifdef CONFIG_SMP
ret = sched_unlock();
if (ret)
{
wlerr("Failed to unlock scheduler after creating pinned thread\n");
return false;
}
sched_unlock();
#endif

return pid > 0;
Expand Down
20 changes: 20 additions & 0 deletions include/nuttx/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,19 @@ int irqchain_detach(int irq, xcpt_t isr, FAR void *arg);
****************************************************************************/

#ifdef CONFIG_IRQCOUNT

# if (defined(CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION) && \
CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0) || \
defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION)
irqstate_t enter_critical_section(void) noinstrument_function;
# else
# define enter_critical_section() enter_critical_section_wo_note()
# endif

irqstate_t enter_critical_section_wo_note(void) noinstrument_function;
#else
# define enter_critical_section() up_irq_save()
# define enter_critical_section_wo_note() up_irq_save()
#endif

/****************************************************************************
Expand Down Expand Up @@ -288,9 +298,19 @@ irqstate_t enter_critical_section(void) noinstrument_function;
****************************************************************************/

#ifdef CONFIG_IRQCOUNT

# if (defined(CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION) && \
CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0) || \
defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION)
void leave_critical_section(irqstate_t flags) noinstrument_function;
# else
# define leave_critical_section(f) leave_critical_section_wo_note(f)
# endif

void leave_critical_section_wo_note(irqstate_t flags) noinstrument_function;
#else
# define leave_critical_section(f) up_irq_restore(f)
# define leave_critical_section_wo_note(f) up_irq_restore(f)
#endif

/****************************************************************************
Expand Down
1 change: 1 addition & 0 deletions include/nuttx/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
#define TCB_FLAG_FORCED_CANCEL (1 << 13) /* Bit 13: Pthread cancel is forced */
#define TCB_FLAG_JOIN_COMPLETED (1 << 14) /* Bit 14: Pthread join completed */
#define TCB_FLAG_FREE_TCB (1 << 15) /* Bit 15: Free tcb after exit */
#define TCB_FLAG_PREEMPT_SCHED (1 << 16) /* Bit 15: tcb is PREEMPT_SCHED */

/* Values for struct task_group tg_flags */

Expand Down
22 changes: 18 additions & 4 deletions include/nuttx/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,17 @@ irqstate_t spin_lock_irqsave_wo_note(FAR volatile spinlock_t *lock)
spin_lock_wo_note(lock);
}

sched_lock_wo_note();
xiaoxiang781216 marked this conversation as resolved.
Show resolved Hide resolved
return ret;
}
#else
# define spin_lock_irqsave_wo_note(l) ((void)(l), up_irq_save())
static inline_function
irqstate_t spin_lock_irqsave_wo_note(FAR volatile spinlock_t *lock)
{
irqstate_t flags = up_irq_save();
sched_lock_wo_note();
return flags;
}
#endif

/****************************************************************************
Expand Down Expand Up @@ -527,7 +534,13 @@ irqstate_t spin_lock_irqsave(FAR volatile spinlock_t *lock)
return flags;
}
#else
# define spin_lock_irqsave(l) ((void)(l), up_irq_save())
static inline_function
irqstate_t spin_lock_irqsave(FAR volatile spinlock_t *lock)
{
irqstate_t flags = up_irq_save();
sched_lock_wo_note();
return flags;
}
#endif

/****************************************************************************
Expand Down Expand Up @@ -635,9 +648,10 @@ void spin_unlock_irqrestore_wo_note(FAR volatile spinlock_t *lock,
}

up_irq_restore(flags);
sched_unlock_wo_note();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rwlock need update too

}
#else
# define spin_unlock_irqrestore_wo_note(l, f) ((void)(l), up_irq_restore(f))
# define spin_unlock_irqrestore_wo_note(l, f) ((void)(l), up_irq_restore(f), sched_unlock_wo_note())
#endif

/****************************************************************************
Expand Down Expand Up @@ -683,7 +697,7 @@ void spin_unlock_irqrestore(FAR volatile spinlock_t *lock,
sched_note_spinlock_unlock(lock);
}
#else
# define spin_unlock_irqrestore(l, f) ((void)(l), up_irq_restore(f))
# define spin_unlock_irqrestore(l, f) ((void)(l), up_irq_restore(f), sched_unlock_wo_note())
#endif

#if defined(CONFIG_RW_SPINLOCK)
Expand Down
6 changes: 4 additions & 2 deletions include/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,10 @@ int sched_cpucount(FAR const cpu_set_t *set);

/* Task Switching Interfaces (non-standard) */

int sched_lock(void);
int sched_unlock(void);
void sched_lock_wo_note(void);
void sched_unlock_wo_note(void);
xiaoxiang781216 marked this conversation as resolved.
Show resolved Hide resolved
void sched_lock(void);
void sched_unlock(void);
int sched_lockcount(void);

/* Queries */
Expand Down
2 changes: 2 additions & 0 deletions include/sys/syscall_lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ SYSCALL_LOOKUP(sched_getparam, 2)
SYSCALL_LOOKUP(sched_getscheduler, 1)
SYSCALL_LOOKUP(sched_lock, 0)
SYSCALL_LOOKUP(sched_lockcount, 0)
SYSCALL_LOOKUP(sched_lock_wo_note, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove no trace version from syscall

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sched_lock_wo_note may be called in userspace
image

SYSCALL_LOOKUP(sched_rr_get_interval, 2)
SYSCALL_LOOKUP(sched_setparam, 2)
SYSCALL_LOOKUP(sched_setscheduler, 3)
SYSCALL_LOOKUP(sched_unlock, 0)
SYSCALL_LOOKUP(sched_unlock_wo_note, 0)
SYSCALL_LOOKUP(sched_yield, 0)
SYSCALL_LOOKUP(nxsched_get_stackinfo, 2)

Expand Down
94 changes: 53 additions & 41 deletions sched/irq/irq_csection.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ volatile uint8_t g_cpu_nestcount[CONFIG_SMP_NCPUS];
****************************************************************************/

/****************************************************************************
* Name: enter_critical_section
* Name: enter_critical_section_wo_note
*
* Description:
* Take the CPU IRQ lock and disable interrupts on all CPUs. A thread-
Expand All @@ -90,7 +90,7 @@ volatile uint8_t g_cpu_nestcount[CONFIG_SMP_NCPUS];
****************************************************************************/

#ifdef CONFIG_SMP
irqstate_t enter_critical_section(void)
irqstate_t enter_critical_section_wo_note(void)
{
FAR struct tcb_s *rtcb;
irqstate_t ret;
Expand Down Expand Up @@ -246,15 +246,6 @@ irqstate_t enter_critical_section(void)

cpu_irqlock_set(cpu);
rtcb->irqcount = 1;

/* Note that we have entered the critical section */

#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
nxsched_critmon_csection(rtcb, true, return_address(0));
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
sched_note_csection(rtcb, true);
#endif
}
}

Expand All @@ -265,7 +256,7 @@ irqstate_t enter_critical_section(void)

#else

irqstate_t enter_critical_section(void)
irqstate_t enter_critical_section_wo_note(void)
{
irqstate_t ret;

Expand All @@ -285,10 +276,28 @@ irqstate_t enter_critical_section(void)
*/

DEBUGASSERT(rtcb->irqcount >= 0 && rtcb->irqcount < INT16_MAX);
if (++rtcb->irqcount == 1)
{
/* Note that we have entered the critical section */
rtcb->irqcount++;
}

/* Return interrupt status */

return ret;
}
#endif

#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 ||\
defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION)
irqstate_t enter_critical_section(void)
{
FAR struct tcb_s *rtcb;
irqstate_t flags;
flags = enter_critical_section_wo_note();

if (!up_interrupt_context())
{
rtcb = this_task();
if (rtcb->irqcount == 1)
{
#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
nxsched_critmon_csection(rtcb, true, return_address(0));
#endif
Expand All @@ -298,14 +307,12 @@ irqstate_t enter_critical_section(void)
}
}

/* Return interrupt status */

return ret;
return flags;
}
#endif

/****************************************************************************
* Name: leave_critical_section
* Name: leave_critical_section_wo_note
*
* Description:
* Decrement the IRQ lock count and if it decrements to zero then release
Expand All @@ -314,7 +321,7 @@ irqstate_t enter_critical_section(void)
****************************************************************************/

#ifdef CONFIG_SMP
void leave_critical_section(irqstate_t flags)
void leave_critical_section_wo_note(irqstate_t flags)
{
int cpu;

Expand Down Expand Up @@ -388,14 +395,6 @@ void leave_critical_section(irqstate_t flags)
}
else
{
/* No.. Note that we have left the critical section */

#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
nxsched_critmon_csection(rtcb, false, return_address(0));
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
sched_note_csection(rtcb, false);
#endif
/* Decrement our count on the lock. If all CPUs have
* released, then unlock the spinlock.
*/
Expand All @@ -421,10 +420,8 @@ void leave_critical_section(irqstate_t flags)

up_irq_restore(flags);
}

#else

void leave_critical_section(irqstate_t flags)
void leave_critical_section_wo_note(irqstate_t flags)
{
/* Check if we were called from an interrupt handler and that the tasks
* lists have been initialized.
Expand All @@ -440,22 +437,37 @@ void leave_critical_section(irqstate_t flags)
*/

DEBUGASSERT(rtcb->irqcount > 0);
if (--rtcb->irqcount <= 0)
{
/* Note that we have left the critical section */
--rtcb->irqcount;
}

#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
nxsched_critmon_csection(rtcb, false, return_address(0));
/* Restore the previous interrupt state. */

up_irq_restore(flags);
}
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION

#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 ||\
defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION)
void leave_critical_section(irqstate_t flags)
{
FAR struct tcb_s *rtcb;

if (!up_interrupt_context())
{
rtcb = this_task();
if (rtcb->irqcount == 1)
{
# if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
nxsched_critmon_csection(rtcb, false, return_address(0));
# endif
# ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
sched_note_csection(rtcb, false);
#endif
# endif
}
}

/* Restore the previous interrupt state. */

up_irq_restore(flags);
leave_critical_section_wo_note(flags);
}
#endif

#endif /* CONFIG_IRQCOUNT */
2 changes: 2 additions & 0 deletions sched/sched/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,8 @@ void nxsched_update_critmon(FAR struct tcb_s *tcb);
#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
void nxsched_critmon_preemption(FAR struct tcb_s *tcb, bool state,
FAR void *caller);
#else
# define nxsched_critmon_preemption(t, s, c)
#endif

#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
Expand Down
Loading
Loading