scheduler/dynamic: add bpftrace script
This will allow runtime observation of the dynamic scheduler in a release build. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I7436b5dbcaa0df1529f828ef75f4e9335a092893 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9672 Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
parent
31a1b193a2
commit
4c5774fd6f
@ -40,6 +40,7 @@
|
||||
#include "spdk/thread.h"
|
||||
#include "spdk_internal/event.h"
|
||||
#include "spdk/scheduler.h"
|
||||
#include "spdk_internal/usdt.h"
|
||||
|
||||
static uint32_t g_main_lcore;
|
||||
|
||||
@ -102,6 +103,8 @@ _move_thread(struct spdk_scheduler_thread_info *thread_info, uint32_t dst_core)
|
||||
uint8_t busy_pct = _busy_pct(src->busy, src->idle);
|
||||
uint64_t tsc;
|
||||
|
||||
SPDK_DTRACE_PROBE2(dynsched_move, thread_info, dst_core);
|
||||
|
||||
if (src == dst) {
|
||||
/* Don't modify stats if thread is already on that core. */
|
||||
return;
|
||||
@ -315,10 +318,13 @@ balance(struct spdk_scheduler_core_info *cores_info, uint32_t cores_count)
|
||||
int rc;
|
||||
bool busy_threads_present = false;
|
||||
|
||||
SPDK_DTRACE_PROBE1(dynsched_balance, cores_count);
|
||||
|
||||
SPDK_ENV_FOREACH_CORE(i) {
|
||||
g_cores[i].thread_count = cores_info[i].threads_count;
|
||||
g_cores[i].busy = cores_info[i].current_busy_tsc;
|
||||
g_cores[i].idle = cores_info[i].current_idle_tsc;
|
||||
SPDK_DTRACE_PROBE2(dynsched_core_info, i, &cores_info[i]);
|
||||
}
|
||||
main_core = &g_cores[g_main_lcore];
|
||||
|
||||
|
62
scripts/bpf/sched.bt
Normal file
62
scripts/bpf/sched.bt
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
struct spdk_thread_stats {
|
||||
uint64_t busy_tsc;
|
||||
uint64_t idle_tsc;
|
||||
};
|
||||
|
||||
struct spdk_scheduler_thread_info {
|
||||
uint32_t lcore;
|
||||
uint64_t thread_id;
|
||||
/* Defining these as a 1-element array here allows us to
|
||||
* create local variables for these members when accessing
|
||||
* them which improves readability.
|
||||
*/
|
||||
struct spdk_thread_stats total_stats[1];
|
||||
struct spdk_thread_stats current_stats[1];
|
||||
};
|
||||
|
||||
struct spdk_scheduler_core_info {
|
||||
uint64_t total_idle_tsc;
|
||||
uint64_t total_busy_tsc;
|
||||
uint64_t current_idle_tsc;
|
||||
uint64_t current_busy_tsc;
|
||||
uint32_t lcore;
|
||||
uint32_t threads_count;
|
||||
bool interrupt_mode;
|
||||
struct spdk_scheduler_thread_info *thread_infos;
|
||||
};
|
||||
|
||||
usdt:__EXE__:dynsched_move {
|
||||
$info = (struct spdk_scheduler_thread_info *)arg1;
|
||||
$stats = (struct spdk_thread_stats *)$info->current_stats;
|
||||
if ($stats->busy_tsc > 0) {
|
||||
$thread_pct = $stats->busy_tsc * 100 / ($stats->busy_tsc + $stats->idle_tsc);
|
||||
$core_pct = $stats->busy_tsc * 100 / (@cores_busy_tsc[$info->lcore] + @cores_idle_tsc[$info->lcore]);
|
||||
} else {
|
||||
$thread_pct = 0;
|
||||
$core_pct = 0;
|
||||
}
|
||||
printf("td:%2d old:%2d new:%2d td_busy:%2d% core_busy:%2d%\n",
|
||||
$info->thread_id, $info->lcore, arg2, $thread_pct, $core_pct);
|
||||
}
|
||||
|
||||
usdt:__EXE__:dynsched_balance {
|
||||
printf("\n");
|
||||
clear(@cores_busy_tsc);
|
||||
clear(@cores_idle_tsc);
|
||||
printf("Starting balance across %d cores\n", arg1);
|
||||
}
|
||||
|
||||
usdt:__EXE__:dynsched_core_info {
|
||||
$info = (struct spdk_scheduler_core_info *)arg2;
|
||||
$busy = $info->current_busy_tsc;
|
||||
$idle = $info->current_idle_tsc;
|
||||
if ($busy > 0) {
|
||||
$pct = $busy * 100 / ($busy + $idle);
|
||||
} else {
|
||||
$pct = 0;
|
||||
}
|
||||
printf("core:%2d busy:%10d idle:%10d pct:%2d% td_count:%2d\n", arg1, $busy, $idle, $pct, $info->threads_count);
|
||||
@cores_busy_tsc[arg1] = $busy;
|
||||
@cores_idle_tsc[arg1] = $idle;
|
||||
}
|
Loading…
Reference in New Issue
Block a user