From aca3b3602a886b9cc35d4d815e4d65908571abb5 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Fri, 23 Aug 2024 15:56:06 +0800 Subject: [PATCH] shell: modules: kernel: add CPU mask affinity/pinning commands Added commands to access the APIs in the kernel/cpu_mask.c Signed-off-by: Yong Cong Sin Signed-off-by: Yong Cong Sin --- subsys/shell/modules/kernel_service.c | 195 ++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/subsys/shell/modules/kernel_service.c b/subsys/shell/modules/kernel_service.c index 7e23dcfafb2..c7c5f51d9b2 100644 --- a/subsys/shell/modules/kernel_service.c +++ b/subsys/shell/modules/kernel_service.c @@ -349,6 +349,193 @@ static int cmd_kernel_thread_unwind(const struct shell *sh, size_t argc, char ** #endif /* CONFIG_ARCH_STACKWALK */ +#ifdef CONFIG_SCHED_CPU_MASK +static int cmd_kernel_thread_mask_clear(const struct shell *sh, size_t argc, char **argv) +{ + ARG_UNUSED(argc); + + int rc, err = 0; + struct k_thread *thread; + + thread = UINT_TO_POINTER(shell_strtoull(argv[1], 16, &err)); + if (err != 0) { + shell_error(sh, "Unable to parse thread ID %s (err %d)", argv[1], err); + return err; + } + + if (!thread_is_valid(thread)) { + shell_error(sh, "Invalid thread id %p", (void *)thread); + return -EINVAL; + } + + rc = k_thread_cpu_mask_clear(thread); + if (rc != 0) { + shell_error(sh, "Failed - %d", rc); + } else { + shell_print(sh, "%p %s cpu_mask: 0x%x", (void *)thread, thread->name, + thread->base.cpu_mask); + } + + return rc; +} + +static int cmd_kernel_thread_mask_enable_all(const struct shell *sh, size_t argc, char **argv) +{ + ARG_UNUSED(argc); + + int rc, err = 0; + struct k_thread *thread; + + thread = UINT_TO_POINTER(shell_strtoull(argv[1], 16, &err)); + if (err != 0) { + shell_error(sh, "Unable to parse thread ID %s (err %d)", argv[1], err); + return err; + } + + if (!thread_is_valid(thread)) { + shell_error(sh, "Invalid thread id %p", (void *)thread); + return -EINVAL; + } + + rc = k_thread_cpu_mask_enable_all(thread); + if (rc != 0) { + shell_error(sh, "Failed - %d", rc); + } else { + shell_print(sh, "%p %s cpu_mask: 0x%x", (void *)thread, thread->name, + thread->base.cpu_mask); + } + + return rc; +} + +static int cmd_kernel_thread_mask_enable(const struct shell *sh, size_t argc, char **argv) +{ + ARG_UNUSED(argc); + + int rc, cpu, err = 0; + struct k_thread *thread; + + thread = UINT_TO_POINTER(shell_strtoull(argv[1], 16, &err)); + if (err != 0) { + shell_error(sh, "Unable to parse thread ID %s (err %d)", argv[1], err); + return err; + } + + if (!thread_is_valid(thread)) { + shell_error(sh, "Invalid thread id %p", (void *)thread); + return -EINVAL; + } + + cpu = (int)shell_strtol(argv[2], 10, &err); + if (err != 0) { + shell_error(sh, "Unable to parse CPU ID %s (err %d)", argv[2], err); + return err; + } + + rc = k_thread_cpu_mask_enable(thread, cpu); + if (rc != 0) { + shell_error(sh, "Failed - %d", rc); + } else { + shell_print(sh, "%p %s cpu_mask: 0x%x", (void *)thread, thread->name, + thread->base.cpu_mask); + } + + return rc; +} + +static int cmd_kernel_thread_mask_disable(const struct shell *sh, size_t argc, char **argv) +{ + ARG_UNUSED(argc); + + int rc, cpu, err = 0; + struct k_thread *thread; + + thread = UINT_TO_POINTER(shell_strtoull(argv[1], 16, &err)); + if (err != 0) { + shell_error(sh, "Unable to parse thread ID %s (err %d)", argv[1], err); + return err; + } + + if (!thread_is_valid(thread)) { + shell_error(sh, "Invalid thread id %p", (void *)thread); + return -EINVAL; + } + + cpu = (int)shell_strtol(argv[2], 10, &err); + if (err != 0) { + shell_error(sh, "Unable to parse CPU ID %s (err %d)", argv[2], err); + return err; + } + + rc = k_thread_cpu_mask_disable(thread, cpu); + if (rc != 0) { + shell_error(sh, "Failed - %d", rc); + } else { + shell_print(sh, "%p %s cpu_mask: 0x%x", (void *)thread, thread->name, + thread->base.cpu_mask); + } + + return rc; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_kernel_thread_mask, + SHELL_CMD_ARG(clear, NULL, + "Sets all CPU enable masks to zero.\n" + "Usage: kernel thread mask clear ", + cmd_kernel_thread_mask_clear, 2, 0), + SHELL_CMD_ARG(enable_all, NULL, + "Sets all CPU enable masks to one.\n" + "Usage: kernel thread mask enable_all ", + cmd_kernel_thread_mask_enable_all, 2, 0), + SHELL_CMD_ARG(enable, NULL, + "Enable thread to run on specified CPU.\n" + "Usage: kernel thread mask enable ", + cmd_kernel_thread_mask_enable, 3, 0), + SHELL_CMD_ARG(disable, NULL, + "Prevent thread to run on specified CPU.\n" + "Usage: kernel thread mask disable ", + cmd_kernel_thread_mask_disable, 3, 0), + SHELL_SUBCMD_SET_END /* Array terminated. */ +); + +static int cmd_kernel_thread_pin(const struct shell *sh, + size_t argc, char **argv) +{ + ARG_UNUSED(argc); + + int cpu, err = 0; + struct k_thread *thread; + + thread = UINT_TO_POINTER(shell_strtoull(argv[1], 16, &err)); + if (err != 0) { + shell_error(sh, "Unable to parse thread ID %s (err %d)", argv[1], err); + return err; + } + + if (!thread_is_valid(thread)) { + shell_error(sh, "Invalid thread id %p", (void *)thread); + return -EINVAL; + } + + cpu = shell_strtoul(argv[2], 10, &err); + if (err != 0) { + shell_error(sh, "Unable to parse CPU ID %s (err %d)", argv[2], err); + return err; + } + + shell_print(sh, "Pinning %p %s to CPU %d", (void *)thread, thread->name, cpu); + err = k_thread_cpu_pin(thread, cpu); + if (err != 0) { + shell_error(sh, "Failed - %d", err); + } else { + shell_print(sh, "%p %s cpu_mask: 0x%x", (void *)thread, thread->name, + thread->base.cpu_mask); + } + + return err; +} +#endif /* CONFIG_SCHED_CPU_MASK */ + SHELL_STATIC_SUBCMD_SET_CREATE(sub_kernel_thread, #if defined(CONFIG_INIT_STACKS) && defined(CONFIG_THREAD_STACK_INFO) && \ defined(CONFIG_THREAD_MONITOR) @@ -358,6 +545,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_kernel_thread, #if defined(CONFIG_ARCH_STACKWALK) SHELL_CMD_ARG(unwind, NULL, "Unwind a thread.", cmd_kernel_thread_unwind, 1, 1), #endif /* CONFIG_ARCH_STACKWALK */ +#if defined(CONFIG_SCHED_CPU_MASK) + SHELL_CMD_ARG(mask, &sub_kernel_thread_mask, "Configure thread CPU mask affinity.", NULL, 2, + 0), + SHELL_CMD_ARG(pin, NULL, + "Pin thread to a CPU.\n" + "Usage: kernel pin ", + cmd_kernel_thread_pin, 3, 0), +#endif /* CONFIG_SCHED_CPU_MASK */ SHELL_SUBCMD_SET_END /* Array terminated. */ );