1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-12-18 08:22:04 +00:00

kern: add tracing for irq/scheduling

This commit is contained in:
Michael Scire 2020-08-03 18:11:13 -07:00 committed by SciresM
parent 8e5c0a9663
commit f058536b59
6 changed files with 59 additions and 12 deletions

View file

@ -32,10 +32,17 @@ namespace ams::kern {
class KTrace { class KTrace {
public: public:
enum Type { enum Type {
Type_ThreadSwitch = 1,
Type_SvcEntry0 = 3, Type_SvcEntry0 = 3,
Type_SvcEntry1 = 4, Type_SvcEntry1 = 4,
Type_SvcExit0 = 5, Type_SvcExit0 = 5,
Type_SvcExit1 = 6, Type_SvcExit1 = 6,
Type_Interrupt = 7,
Type_ScheduleUpdate = 11,
Type_CoreMigration = 14,
}; };
private: private:
static bool s_is_active; static bool s_is_active;
@ -65,6 +72,18 @@ namespace ams::kern {
} \ } \
}) })
#define MESOSPHERE_KTRACE_PUSH_RECORD(TYPE, ...) \
({ \
if constexpr (::ams::kern::IsKTraceEnabled) { \
if (::ams::kern::KTrace::IsActive()) { \
::ams::kern::KTrace::PushRecord(TYPE, ## __VA_ARGS__); \
} \
} \
})
#define MESOSPHERE_KTRACE_THREAD_SWITCH(NEXT) \
MESOSPHERE_KTRACE_PUSH_RECORD(::ams::kern::KTrace::Type_ThreadSwitch, (NEXT)->GetId())
#define MESOSPHERE_KTRACE_SVC_ENTRY(SVC_ID, PARAM0, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7) \ #define MESOSPHERE_KTRACE_SVC_ENTRY(SVC_ID, PARAM0, PARAM1, PARAM2, PARAM3, PARAM4, PARAM5, PARAM6, PARAM7) \
({ \ ({ \
if constexpr (::ams::kern::IsKTraceEnabled) { \ if constexpr (::ams::kern::IsKTraceEnabled) { \
@ -84,3 +103,12 @@ namespace ams::kern {
} \ } \
} \ } \
}) })
#define MESOSPHERE_KTRACE_INTERRUPT(ID) \
MESOSPHERE_KTRACE_PUSH_RECORD(::ams::kern::KTrace::Type_Interrupt, ID)
#define MESOSPHERE_KTRACE_SCHEDULE_UPDATE(CORE, PREV, NEXT) \
MESOSPHERE_KTRACE_PUSH_RECORD(::ams::kern::KTrace::Type_ScheduleUpdate, CORE, (PREV)->GetId(), (NEXT)->GetId())
#define MESOSPHERE_KTRACE_CORE_MIGRATION(THREAD_ID, PREV, NEXT, REASON) \
MESOSPHERE_KTRACE_PUSH_RECORD(::ams::kern::KTrace::Type_CoreMigration, THREAD_ID, PREV, NEXT, REASON)

View file

@ -111,6 +111,9 @@ namespace ams::kern::arch::arm64 {
const u32 raw_irq = this->interrupt_controller.GetIrq(); const u32 raw_irq = this->interrupt_controller.GetIrq();
const s32 irq = KInterruptController::ConvertRawIrq(raw_irq); const s32 irq = KInterruptController::ConvertRawIrq(raw_irq);
/* Trace the interrupt. */
MESOSPHERE_KTRACE_INTERRUPT(irq);
/* If the IRQ is spurious, we don't need to reschedule. */ /* If the IRQ is spurious, we don't need to reschedule. */
if (irq < 0) { if (irq < 0) {
return false; return false;

View file

@ -86,18 +86,20 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev:
/* If we should, trace the svc entry. */ /* If we should, trace the svc entry. */
#if defined(MESOSPHERE_BUILD_FOR_TRACING) #if defined(MESOSPHERE_BUILD_FOR_TRACING)
sub sp, sp, #0x40 sub sp, sp, #0x50
stp x0, x1, [sp, #(8 * 0)] stp x0, x1, [sp, #(8 * 0)]
stp x2, x3, [sp, #(8 * 2)] stp x2, x3, [sp, #(8 * 2)]
stp x4, x5, [sp, #(8 * 4)] stp x4, x5, [sp, #(8 * 4)]
stp x6, x7, [sp, #(8 * 6)] stp x6, x7, [sp, #(8 * 6)]
str x11, [sp, #(8 * 8)]
mov x0, sp mov x0, sp
bl _ZN3ams4kern3svc13TraceSvcEntryEPKm bl _ZN3ams4kern3svc13TraceSvcEntryEPKm
ldp x0, x1, [sp, #(8 * 0)] ldp x0, x1, [sp, #(8 * 0)]
ldp x2, x3, [sp, #(8 * 2)] ldp x2, x3, [sp, #(8 * 2)]
ldp x4, x5, [sp, #(8 * 4)] ldp x4, x5, [sp, #(8 * 4)]
ldp x6, x7, [sp, #(8 * 6)] ldp x6, x7, [sp, #(8 * 6)]
add sp, sp, #0x40 ldr x11, [sp, #(8 * 8)]
add sp, sp, #0x50
#endif #endif
/* Invoke the SVC handler. */ /* Invoke the SVC handler. */
@ -294,18 +296,20 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev:
/* If we should, trace the svc entry. */ /* If we should, trace the svc entry. */
#if defined(MESOSPHERE_BUILD_FOR_TRACING) #if defined(MESOSPHERE_BUILD_FOR_TRACING)
sub sp, sp, #0x40 sub sp, sp, #0x50
stp x0, x1, [sp, #(8 * 0)] stp x0, x1, [sp, #(8 * 0)]
stp x2, x3, [sp, #(8 * 2)] stp x2, x3, [sp, #(8 * 2)]
stp x4, x5, [sp, #(8 * 4)] stp x4, x5, [sp, #(8 * 4)]
stp x6, x7, [sp, #(8 * 6)] stp x6, x7, [sp, #(8 * 6)]
str x19, [sp, #(8 * 8)]
mov x0, sp mov x0, sp
bl _ZN3ams4kern3svc13TraceSvcEntryEPKm bl _ZN3ams4kern3svc13TraceSvcEntryEPKm
ldp x0, x1, [sp, #(8 * 0)] ldp x0, x1, [sp, #(8 * 0)]
ldp x2, x3, [sp, #(8 * 2)] ldp x2, x3, [sp, #(8 * 2)]
ldp x4, x5, [sp, #(8 * 4)] ldp x4, x5, [sp, #(8 * 4)]
ldp x6, x7, [sp, #(8 * 6)] ldp x6, x7, [sp, #(8 * 6)]
add sp, sp, #0x40 ldr x19, [sp, #(8 * 8)]
add sp, sp, #0x50
#endif #endif
/* Invoke the SVC handler. */ /* Invoke the SVC handler. */

View file

@ -99,6 +99,8 @@ namespace ams::kern {
} }
} }
MESOSPHERE_KTRACE_SCHEDULE_UPDATE(this->core_id, (prev_highest_thread != nullptr ? prev_highest_thread : this->idle_thread), (highest_thread != nullptr ? highest_thread : this->idle_thread));
this->state.highest_priority_thread = highest_thread; this->state.highest_priority_thread = highest_thread;
this->state.needs_scheduling = true; this->state.needs_scheduling = true;
return (1ul << this->core_id); return (1ul << this->core_id);
@ -163,6 +165,7 @@ namespace ams::kern {
/* The suggested thread isn't bound to its core, so we can migrate it! */ /* The suggested thread isn't bound to its core, so we can migrate it! */
suggested->SetActiveCore(core_id); suggested->SetActiveCore(core_id);
priority_queue.ChangeCore(suggested_core, suggested); priority_queue.ChangeCore(suggested_core, suggested);
MESOSPHERE_KTRACE_CORE_MIGRATION(suggested->GetId(), suggested_core, core_id, 1);
top_threads[core_id] = suggested; top_threads[core_id] = suggested;
cores_needing_scheduling |= Kernel::GetScheduler(core_id).UpdateHighestPriorityThread(top_threads[core_id]); cores_needing_scheduling |= Kernel::GetScheduler(core_id).UpdateHighestPriorityThread(top_threads[core_id]);
break; break;
@ -188,6 +191,7 @@ namespace ams::kern {
/* Perform the migration. */ /* Perform the migration. */
suggested->SetActiveCore(core_id); suggested->SetActiveCore(core_id);
priority_queue.ChangeCore(candidate_core, suggested); priority_queue.ChangeCore(candidate_core, suggested);
MESOSPHERE_KTRACE_CORE_MIGRATION(suggested->GetId(), candidate_core, core_id, 2);
top_threads[core_id] = suggested; top_threads[core_id] = suggested;
cores_needing_scheduling |= Kernel::GetScheduler(core_id).UpdateHighestPriorityThread(top_threads[core_id]); cores_needing_scheduling |= Kernel::GetScheduler(core_id).UpdateHighestPriorityThread(top_threads[core_id]);
break; break;
@ -253,6 +257,8 @@ namespace ams::kern {
this->prev_thread = nullptr; this->prev_thread = nullptr;
} }
MESOSPHERE_KTRACE_THREAD_SWITCH(next_thread);
/* Switch the current process, if we're switching processes. */ /* Switch the current process, if we're switching processes. */
if (KProcess *next_process = next_thread->GetOwnerProcess(); next_process != cur_process) { if (KProcess *next_process = next_thread->GetOwnerProcess(); next_process != cur_process) {
/* MESOSPHERE_LOG("!!! PROCESS SWITCH !!! %s -> %s\n", cur_process != nullptr ? cur_process->GetName() : nullptr, next_process != nullptr ? next_process->GetName() : nullptr); */ /* MESOSPHERE_LOG("!!! PROCESS SWITCH !!! %s -> %s\n", cur_process != nullptr ? cur_process->GetName() : nullptr, next_process != nullptr ? next_process->GetName() : nullptr); */
@ -496,6 +502,7 @@ namespace ams::kern {
if (running_on_suggested_core == nullptr || running_on_suggested_core->GetPriority() >= HighestCoreMigrationAllowedPriority) { if (running_on_suggested_core == nullptr || running_on_suggested_core->GetPriority() >= HighestCoreMigrationAllowedPriority) {
suggested->SetActiveCore(core_id); suggested->SetActiveCore(core_id);
priority_queue.ChangeCore(suggested_core, suggested, true); priority_queue.ChangeCore(suggested_core, suggested, true);
MESOSPHERE_KTRACE_CORE_MIGRATION(suggested->GetId(), suggested_core, core_id, 3);
IncrementScheduledCount(suggested); IncrementScheduledCount(suggested);
break; break;
} else { } else {
@ -549,6 +556,7 @@ namespace ams::kern {
/* Migrate the current thread to core -1. */ /* Migrate the current thread to core -1. */
cur_thread.SetActiveCore(-1); cur_thread.SetActiveCore(-1);
priority_queue.ChangeCore(core_id, std::addressof(cur_thread)); priority_queue.ChangeCore(core_id, std::addressof(cur_thread));
MESOSPHERE_KTRACE_CORE_MIGRATION(cur_thread.GetId(), core_id, -1, 4);
IncrementScheduledCount(std::addressof(cur_thread)); IncrementScheduledCount(std::addressof(cur_thread));
/* If there's nothing scheduled, we can try to perform a migration. */ /* If there's nothing scheduled, we can try to perform a migration. */
@ -563,6 +571,7 @@ namespace ams::kern {
if (top_on_suggested_core == nullptr || top_on_suggested_core->GetPriority() >= HighestCoreMigrationAllowedPriority) { if (top_on_suggested_core == nullptr || top_on_suggested_core->GetPriority() >= HighestCoreMigrationAllowedPriority) {
suggested->SetActiveCore(core_id); suggested->SetActiveCore(core_id);
priority_queue.ChangeCore(suggested_core, suggested); priority_queue.ChangeCore(suggested_core, suggested);
MESOSPHERE_KTRACE_CORE_MIGRATION(suggested->GetId(), suggested_core, core_id, 5);
IncrementScheduledCount(suggested); IncrementScheduledCount(suggested);
} }

View file

@ -28,8 +28,11 @@ namespace ams::kern {
void KServerPort::CleanupSessions() { void KServerPort::CleanupSessions() {
/* Ensure our preconditions are met. */ /* Ensure our preconditions are met. */
MESOSPHERE_ASSERT(this->IsLight() || this->session_list.empty()); if (this->IsLight()) {
MESOSPHERE_ASSERT(!this->IsLight() || this->light_session_list.empty()); MESOSPHERE_ASSERT(this->session_list.empty());
} else {
MESOSPHERE_ASSERT(this->light_session_list.empty());
}
/* Cleanup the session list. */ /* Cleanup the session list. */
while (true) { while (true) {