sched_note: Extend OS instrumentation to include some SMP events.

This commit is contained in:
Gregory Nutt 2016-11-27 17:14:57 -06:00
parent cbf98ae0a0
commit d65be718c2
8 changed files with 176 additions and 3 deletions

View File

@ -44,6 +44,7 @@
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include <nuttx/spinlock.h>
#include <nuttx/sched_note.h>
#include "up_internal.h"
#include "gic.h"
@ -131,6 +132,12 @@ int up_cpu_paused(int cpu)
sched_suspend_scheduler(tcb);
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we are paused */
sched_note_cpu_paused(tcb);
#endif
/* Save the current context at CURRENT_REGS into the TCB at the head
* of the assigned task list for this CPU.
*/
@ -148,6 +155,12 @@ int up_cpu_paused(int cpu)
tcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
sched_note_cpu_resumed(tcb);
#endif
/* Reset scheduler parameters */
sched_resume_scheduler(tcb);
@ -224,6 +237,12 @@ int up_cpu_pause(int cpu)
{
int ret;
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the pause event */
sched_note_cpu_pause(this_task(), cpu);
#endif
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2
@ -287,6 +306,12 @@ int up_cpu_pause(int cpu)
int up_cpu_resume(int cpu)
{
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the resume event */
sched_note_cpu_resume(this_task(), cpu);
#endif
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
/* Release the spinlock. Releasing the spinlock will cause the SGI2

View File

@ -105,9 +105,8 @@ static inline void arm_registerdump(FAR struct tcb_s *tcb)
int arm_start_handler(int irq, FAR void *context)
{
FAR struct tcb_s *tcb;
int cpu = up_cpu_index();
sinfo("CPU%d Started\n", cpu);
sinfo("CPU%d Started\n", this_cpu());
/* Reset scheduler parameters */

View File

@ -44,6 +44,7 @@
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include <nuttx/spinlock.h>
#include <nuttx/sched_note.h>
#include "xtensa.h"
#include "sched/sched.h"
@ -117,6 +118,12 @@ int up_cpu_paused(int cpu)
sched_suspend_scheduler(otcb);
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we are paused */
sched_note_cpu_paused(otcb);
#endif
/* Copy the CURRENT_REGS into the OLD TCB (otcb). The co-processor state
* will be saved as part of the return from xtensa_irq_dispatch().
*/
@ -134,6 +141,12 @@ int up_cpu_paused(int cpu)
ntcb = this_task();
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify that we have resumed */
sched_note_cpu_resumed(ntcb);
#endif
/* Reset scheduler parameters */
sched_resume_scheduler(ntcb);
@ -203,6 +216,12 @@ int up_cpu_pause(int cpu)
{
int ret;
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the pause event */
sched_note_cpu_pause(this_task(), cpu);
#endif
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2
@ -266,6 +285,12 @@ int up_cpu_pause(int cpu)
int up_cpu_resume(int cpu)
{
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the resume event */
sched_note_cpu_resume(this_task(), cpu);
#endif
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
/* Release the spinlock. Releasing the spinlock will cause the SGI2

View File

@ -73,7 +73,7 @@ config DRIVER_NOTE
depends on SCHED_INSTRUMENTATION_BUFFER
---help---
Enable building a serial driver that can be used by an application
to read data from the in-memory, scheduler instrumentatin "note"
to read data from the in-memory, scheduler instrumentation "note"
buffer.
config SYSLOG_INTBUFFER

View File

@ -64,6 +64,13 @@ enum note_type_e
NOTE_STOP,
NOTE_SUSPEND,
NOTE_RESUME
#ifdef CONFIG_SMP
,
NOTE_CPU_PAUSE,
NOTE_CPU_PAUSED,
NOTE_CPU_RESUME,
NOTE_CPU_RESUMED
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
,
NOTE_PREEMPT_LOCK,
@ -122,6 +129,38 @@ struct note_resume_s
struct note_common_s nre_cmn; /* Common note parameters */
};
#ifdef CONFIG_SMP
/* This is the specific form of the NOTE_CPU_PAUSE note */
struct note_cpu_pause_s
{
struct note_common_s ncp_cmn; /* Common note parameters */
uint8_t ncp_target; /* CPU being paused */
};
/* This is the specific form of the NOTE_CPU_PAUSED note */
struct note_cpu_paused_s
{
struct note_common_s ncp_cmn; /* Common note parameters */
};
/* This is the specific form of the NOTE_CPU_RESUME note */
struct note_cpu_resume_s
{
struct note_common_s ncr_cmn; /* Common note parameters */
uint8_t ncr_target; /* CPU being resumed */
};
/* This is the specific form of the NOTE_CPU_RESUMED note */
struct note_cpu_resumed_s
{
struct note_common_s ncr_cmn; /* Common note parameters */
};
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
/* This is the specific form of the NOTE_PREEMPT_LOCK/UNLOCK note */
@ -174,12 +213,28 @@ void sched_note_stop(FAR struct tcb_s *tcb);
void sched_note_suspend(FAR struct tcb_s *tcb);
void sched_note_resume(FAR struct tcb_s *tcb);
#ifdef CONFIG_SMP
void sched_note_cpu_pause(FAR struct tcb_s *tcb, int cpu);
void sched_note_cpu_paused(FAR struct tcb_s *tcb);
void sched_note_cpu_resume(FAR struct tcb_s *tcb, int cpu);
void sched_note_cpu_resumed(FAR struct tcb_s *tcb);
#else
# define sched_note_cpu_pause(t,c)
# define sched_note_cpu_paused(t)
# define sched_note_cpu_resume(t,c)
# define sched_note_cpu_resumed(t)
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
void sched_note_premption(FAR struct tcb_s *tcb, bool locked);
#else
# define sched_note_premption(t,l)
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
void sched_note_csection(FAR struct tcb_s *tcb, bool enter);
#else
# define sched_note_csection(t,e)
#endif
/****************************************************************************
@ -250,6 +305,10 @@ int note_register(void);
# define sched_note_stop(t)
# define sched_note_suspend(t)
# define sched_note_resume(t)
# define sched_note_cpu_pause(t,c)
# define sched_note_cpu_paused(t)
# define sched_note_cpu_resume(t,c)
# define sched_note_cpu_resumed(t)
# define sched_note_premption(t,l)
# define sched_note_csection(t,e)

View File

@ -661,6 +661,14 @@ config SCHED_INSTRUMENTATION
void sched_note_suspend(FAR struct tcb_s *tcb);
void sched_note_resume(FAR struct tcb_s *tcb);
If CONFIG_SMP is enabled, then these additional interfaces are
expected:
void sched_note_cpu_pause(FAR struct tcb_s *tcb, int cpu);
void sched_note_cpu_paused(FAR struct tcb_s *tcb);
void sched_note_cpu_resume(FAR struct tcb_s *tcb, int cpu);
void sched_note_cpu_resumed(FAR struct tcb_s *tcb);
NOTE: These are internal OS interfaces and are called at at very
critical locations in the OS. There is very little that can be
done in these interfaces. For example, normal devices may not be

View File

@ -44,6 +44,7 @@
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/sched_note.h>
#include "sched/sched.h"

View File

@ -369,6 +369,62 @@ void sched_note_resume(FAR struct tcb_s *tcb)
note_add((FAR const uint8_t *)&note, sizeof(struct note_resume_s));
}
#ifdef CONFIG_SMP
void sched_note_cpu_pause(FAR struct tcb_s *tcb, int cpu)
{
struct note_cpu_pause_s note;
/* Format the note */
note_common(tcb, &note.ncp_cmn, sizeof(struct note_cpu_pause_s), NOTE_CPU_PAUSE);
note.ncp_target = (uint8_t)cpu;
/* Add the note to circular buffer */
note_add((FAR const uint8_t *)&note, sizeof(struct note_cpu_pause_s));
}
void sched_note_cpu_paused(FAR struct tcb_s *tcb)
{
struct note_cpu_paused_s note;
/* Format the note */
note_common(tcb, &note.ncp_cmn, sizeof(struct note_cpu_paused_s), NOTE_CPU_PAUSED);
/* Add the note to circular buffer */
note_add((FAR const uint8_t *)&note, sizeof(struct note_cpu_paused_s));
}
void sched_note_cpu_resume(FAR struct tcb_s *tcb, int cpu)
{
struct note_cpu_resume_s note;
/* Format the note */
note_common(tcb, &note.ncr_cmn, sizeof(struct note_cpu_resume_s), NOTE_CPU_RESUME);
note.ncr_target = (uint8_t)cpu;
/* Add the note to circular buffer */
note_add((FAR const uint8_t *)&note, sizeof(struct note_cpu_resume_s));
}
void sched_note_cpu_resumed(FAR struct tcb_s *tcb)
{
struct note_cpu_resumed_s note;
/* Format the note */
note_common(tcb, &note.ncr_cmn, sizeof(struct note_cpu_resumed_s), NOTE_CPU_RESUMED);
/* Add the note to circular buffer */
note_add((FAR const uint8_t *)&note, sizeof(struct note_cpu_resumed_s));
}
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
void sched_note_premption(FAR struct tcb_s *tcb, bool locked)
{