sched: handle sched lock in interrupt
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
This commit is contained in:
parent
755bef6c56
commit
5e2d205e1b
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/nuttx.h>
|
#include <nuttx/nuttx.h>
|
||||||
#include <nuttx/queue.h>
|
#include <nuttx/queue.h>
|
||||||
@ -61,6 +62,7 @@ struct smp_call_data_s
|
|||||||
|
|
||||||
static sq_queue_t g_smp_call_queue[CONFIG_SMP_NCPUS];
|
static sq_queue_t g_smp_call_queue[CONFIG_SMP_NCPUS];
|
||||||
static struct smp_call_data_s g_smp_call_data;
|
static struct smp_call_data_s g_smp_call_data;
|
||||||
|
static spinlock_t g_smp_call_lock;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@ -86,9 +88,9 @@ static void nxsched_smp_call_add(int cpu,
|
|||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_smp_call_lock);
|
||||||
sq_addlast(&call_data->node[cpu], &g_smp_call_queue[cpu]);
|
sq_addlast(&call_data->node[cpu], &g_smp_call_queue[cpu]);
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_smp_call_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -119,7 +121,7 @@ int nxsched_smp_call_handler(int irq, FAR void *context,
|
|||||||
FAR sq_entry_t *next;
|
FAR sq_entry_t *next;
|
||||||
int cpu = this_cpu();
|
int cpu = this_cpu();
|
||||||
|
|
||||||
irqstate_t flags = enter_critical_section();
|
irqstate_t flags = spin_lock_irqsave(&g_smp_call_lock);
|
||||||
|
|
||||||
call_queue = &g_smp_call_queue[cpu];
|
call_queue = &g_smp_call_queue[cpu];
|
||||||
|
|
||||||
@ -132,11 +134,11 @@ int nxsched_smp_call_handler(int irq, FAR void *context,
|
|||||||
|
|
||||||
sq_rem(&call_data->node[cpu], call_queue);
|
sq_rem(&call_data->node[cpu], call_queue);
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_smp_call_lock, flags);
|
||||||
|
|
||||||
ret = call_data->func(call_data->arg);
|
ret = call_data->func(call_data->arg);
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_smp_call_lock);
|
||||||
if (spin_is_locked(&call_data->lock))
|
if (spin_is_locked(&call_data->lock))
|
||||||
{
|
{
|
||||||
if (--call_data->refcount == 0)
|
if (--call_data->refcount == 0)
|
||||||
@ -157,7 +159,7 @@ int nxsched_smp_call_handler(int irq, FAR void *context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
up_cpu_paused_restore();
|
up_cpu_paused_restore();
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_smp_call_lock, flags);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,13 +221,20 @@ int nxsched_smp_call(cpu_set_t cpuset, nxsched_smp_call_t func,
|
|||||||
};
|
};
|
||||||
|
|
||||||
FAR struct smp_call_data_s *call_data;
|
FAR struct smp_call_data_s *call_data;
|
||||||
int remote_cpus = 0;
|
int remote_cpus;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Cannot wait in interrupt context. */
|
||||||
|
|
||||||
|
DEBUGASSERT(!(wait && up_interrupt_context()));
|
||||||
|
|
||||||
/* Prevent reschedule on another processor */
|
/* Prevent reschedule on another processor */
|
||||||
|
|
||||||
|
if (!up_interrupt_context())
|
||||||
|
{
|
||||||
sched_lock();
|
sched_lock();
|
||||||
|
}
|
||||||
|
|
||||||
if (CPU_ISSET(this_cpu(), &cpuset))
|
if (CPU_ISSET(this_cpu(), &cpuset))
|
||||||
{
|
{
|
||||||
@ -293,6 +302,10 @@ int nxsched_smp_call(cpu_set_t cpuset, nxsched_smp_call_t func,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (!up_interrupt_context())
|
||||||
|
{
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user