From 63daf69e1783f04f741398b678540e6723675264 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Thu, 22 May 2025 20:32:23 +0800 Subject: [PATCH] Fix incorrect types in `sys_getcpu` --- kernel/src/syscall/getcpu.rs | 29 ++++++++++++++++------------ test/apps/getcpu/getcpu.c | 37 ++++++++++++++++++++---------------- test/apps/scripts/process.sh | 1 + 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/kernel/src/syscall/getcpu.rs b/kernel/src/syscall/getcpu.rs index da285391..fd499d1b 100644 --- a/kernel/src/syscall/getcpu.rs +++ b/kernel/src/syscall/getcpu.rs @@ -1,27 +1,32 @@ // SPDX-License-Identifier: MPL-2.0 -use ostd::{cpu::PinCurrentCpu, task::disable_preempt}; +use ostd::cpu::CpuId; use super::SyscallReturn; use crate::prelude::*; pub fn sys_getcpu(cpu: Vaddr, node: Vaddr, _tcache: Vaddr, ctx: &Context) -> Result { - // The third argument tcache is unused after Linux 2.6.24 so we ignore it - let preempt_guard = disable_preempt(); - let cpuid = preempt_guard.current_cpu(); - drop(preempt_guard); + // The third argument `tcache` is unused since Linux 2.6.24, so we ignore it. + + // The system call itself is inherently racy, so using `current_racy` here should be fine. + let current_cpu = CpuId::current_racy().as_usize() as u32; + // TODO: Support NUMA. + let current_node = 0u32; + debug!( - "getcpu: cpuid = {}, total_cpus = {}", - cpuid.as_usize(), - ostd::cpu::num_cpus() + "[sys_getcpu]: cpu = {} (total {}), node = {}", + current_cpu, + ostd::cpu::num_cpus(), + current_node, ); - // Since cpu and node can be NULL, we need to check them before writing + + // `cpu` and `node` can be NULL, so we need to check before writing. if cpu != 0 { - ctx.user_space() - .write_val::(cpu, &cpuid.as_usize())?; + ctx.user_space().write_val(cpu, ¤t_cpu)?; } if node != 0 { - ctx.user_space().write_val::(node, &0)?; // TODO: NUMA is not supported + ctx.user_space().write_val(node, ¤t_node)?; } + Ok(SyscallReturn::Return(0)) } diff --git a/test/apps/getcpu/getcpu.c b/test/apps/getcpu/getcpu.c index 0944f59b..86f9c458 100644 --- a/test/apps/getcpu/getcpu.c +++ b/test/apps/getcpu/getcpu.c @@ -1,24 +1,29 @@ // SPDX-License-Identifier: MPL-2.0 -#define _GNU_SOURCE -#include -#include -#include +#include "../network/test.h" + #include +#include -int main() +FN_TEST(getcpu) { - unsigned int cpu, node; + struct int_pair { + unsigned int first; + unsigned int second; + }; - // Directly test the getcpu syscall because glibc's getcpu() may not - // use the getcpu syscall to retrieve CPU info - long ret = syscall(SYS_getcpu, &cpu, &node, NULL); - if (ret != 0) { - perror("syscall getcpu"); - exit(EXIT_FAILURE); - } + struct int_pair cpu = { .first = 0xdeadbeef, .second = 0xbeefdead }; + struct int_pair node = { .first = 0xbeefdead, .second = 0xdeadbeef }; - printf("getcpu syscall: cpu = %u, node = %u\n", cpu, node); + // Use `syscall()` here because `getcpu()` from glibc may not use + // the system call to retrieve CPU information. + TEST_SUCC(syscall(SYS_getcpu, NULL, NULL)); - return 0; -} \ No newline at end of file + // Our CI has a maximum of 4 CPUs, and NUMA support is not yet + // available. Update these conditions if we have more than 4 CPUs + // or if NUMA support is added. + TEST_RES(syscall(SYS_getcpu, &cpu, &node), + cpu.first < 4 && cpu.second == 0xbeefdead && node.first == 0 && + node.second == 0xdeadbeef); +} +END_TEST() diff --git a/test/apps/scripts/process.sh b/test/apps/scripts/process.sh index 1cb30771..235a18df 100755 --- a/test/apps/scripts/process.sh +++ b/test/apps/scripts/process.sh @@ -21,6 +21,7 @@ exit/exit_procfs eventfd2/eventfd2 fork/fork fork_c/fork +getcpu/getcpu getpid/getpid hello_pie/hello hello_world/hello_world