1 /*
2 * Copyright (c) 2024 Meta Platforms
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "kernel_shell.h"
8
9 #include <zephyr/kernel.h>
10
cmd_kernel_thread_mask_clear(const struct shell * sh,size_t argc,char ** argv)11 static int cmd_kernel_thread_mask_clear(const struct shell *sh, size_t argc, char **argv)
12 {
13 ARG_UNUSED(argc);
14
15 int rc, err = 0;
16 struct k_thread *thread;
17
18 thread = UINT_TO_POINTER(shell_strtoull(argv[1], 16, &err));
19 if (err != 0) {
20 shell_error(sh, "Unable to parse thread ID %s (err %d)", argv[1], err);
21 return err;
22 }
23
24 if (!z_thread_is_valid(thread)) {
25 shell_error(sh, "Invalid thread id %p", (void *)thread);
26 return -EINVAL;
27 }
28
29 rc = k_thread_cpu_mask_clear(thread);
30 if (rc != 0) {
31 shell_error(sh, "Failed - %d", rc);
32 } else {
33 shell_print(sh, "%p %s cpu_mask: 0x%x", (void *)thread, thread->name,
34 thread->base.cpu_mask);
35 }
36
37 return rc;
38 }
39
cmd_kernel_thread_mask_enable_all(const struct shell * sh,size_t argc,char ** argv)40 static int cmd_kernel_thread_mask_enable_all(const struct shell *sh, size_t argc, char **argv)
41 {
42 ARG_UNUSED(argc);
43
44 int rc, err = 0;
45 struct k_thread *thread;
46
47 thread = UINT_TO_POINTER(shell_strtoull(argv[1], 16, &err));
48 if (err != 0) {
49 shell_error(sh, "Unable to parse thread ID %s (err %d)", argv[1], err);
50 return err;
51 }
52
53 if (!z_thread_is_valid(thread)) {
54 shell_error(sh, "Invalid thread id %p", (void *)thread);
55 return -EINVAL;
56 }
57
58 rc = k_thread_cpu_mask_enable_all(thread);
59 if (rc != 0) {
60 shell_error(sh, "Failed - %d", rc);
61 } else {
62 shell_print(sh, "%p %s cpu_mask: 0x%x", (void *)thread, thread->name,
63 thread->base.cpu_mask);
64 }
65
66 return rc;
67 }
68
cmd_kernel_thread_mask_enable(const struct shell * sh,size_t argc,char ** argv)69 static int cmd_kernel_thread_mask_enable(const struct shell *sh, size_t argc, char **argv)
70 {
71 ARG_UNUSED(argc);
72
73 int rc, cpu, err = 0;
74 struct k_thread *thread;
75
76 thread = UINT_TO_POINTER(shell_strtoull(argv[1], 16, &err));
77 if (err != 0) {
78 shell_error(sh, "Unable to parse thread ID %s (err %d)", argv[1], err);
79 return err;
80 }
81
82 if (!z_thread_is_valid(thread)) {
83 shell_error(sh, "Invalid thread id %p", (void *)thread);
84 return -EINVAL;
85 }
86
87 cpu = (int)shell_strtol(argv[2], 10, &err);
88 if (err != 0) {
89 shell_error(sh, "Unable to parse CPU ID %s (err %d)", argv[2], err);
90 return err;
91 }
92
93 rc = k_thread_cpu_mask_enable(thread, cpu);
94 if (rc != 0) {
95 shell_error(sh, "Failed - %d", rc);
96 } else {
97 shell_print(sh, "%p %s cpu_mask: 0x%x", (void *)thread, thread->name,
98 thread->base.cpu_mask);
99 }
100
101 return rc;
102 }
103
cmd_kernel_thread_mask_disable(const struct shell * sh,size_t argc,char ** argv)104 static int cmd_kernel_thread_mask_disable(const struct shell *sh, size_t argc, char **argv)
105 {
106 ARG_UNUSED(argc);
107
108 int rc, cpu, err = 0;
109 struct k_thread *thread;
110
111 thread = UINT_TO_POINTER(shell_strtoull(argv[1], 16, &err));
112 if (err != 0) {
113 shell_error(sh, "Unable to parse thread ID %s (err %d)", argv[1], err);
114 return err;
115 }
116
117 if (!z_thread_is_valid(thread)) {
118 shell_error(sh, "Invalid thread id %p", (void *)thread);
119 return -EINVAL;
120 }
121
122 cpu = (int)shell_strtol(argv[2], 10, &err);
123 if (err != 0) {
124 shell_error(sh, "Unable to parse CPU ID %s (err %d)", argv[2], err);
125 return err;
126 }
127
128 rc = k_thread_cpu_mask_disable(thread, cpu);
129 if (rc != 0) {
130 shell_error(sh, "Failed - %d", rc);
131 } else {
132 shell_print(sh, "%p %s cpu_mask: 0x%x", (void *)thread, thread->name,
133 thread->base.cpu_mask);
134 }
135
136 return rc;
137 }
138
139 SHELL_STATIC_SUBCMD_SET_CREATE(sub_kernel_thread_mask,
140 SHELL_CMD_ARG(clear, NULL,
141 "Sets all CPU enable masks to zero.\n"
142 "Usage: kernel thread mask clear <thread ID>",
143 cmd_kernel_thread_mask_clear, 2, 0),
144 SHELL_CMD_ARG(enable_all, NULL,
145 "Sets all CPU enable masks to one.\n"
146 "Usage: kernel thread mask enable_all <thread ID>",
147 cmd_kernel_thread_mask_enable_all, 2, 0),
148 SHELL_CMD_ARG(enable, NULL,
149 "Enable thread to run on specified CPU.\n"
150 "Usage: kernel thread mask enable <thread ID> <CPU ID>",
151 cmd_kernel_thread_mask_enable, 3, 0),
152 SHELL_CMD_ARG(disable, NULL,
153 "Prevent thread to run on specified CPU.\n"
154 "Usage: kernel thread mask disable <thread ID> <CPU ID>",
155 cmd_kernel_thread_mask_disable, 3, 0),
156 SHELL_SUBCMD_SET_END /* Array terminated. */
157 );
158
159 KERNEL_THREAD_CMD_ARG_ADD(mask, &sub_kernel_thread_mask, "Configure thread CPU mask affinity.",
160 NULL, 2, 0);
161