Fix incorrect types in sys_getcpu

This commit is contained in:
Ruihan Li 2025-05-22 20:32:23 +08:00 committed by Jianfeng Jiang
parent 56e9824dd1
commit 63daf69e17
3 changed files with 39 additions and 28 deletions

View File

@ -1,27 +1,32 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use ostd::{cpu::PinCurrentCpu, task::disable_preempt}; use ostd::cpu::CpuId;
use super::SyscallReturn; use super::SyscallReturn;
use crate::prelude::*; use crate::prelude::*;
pub fn sys_getcpu(cpu: Vaddr, node: Vaddr, _tcache: Vaddr, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_getcpu(cpu: Vaddr, node: Vaddr, _tcache: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
// The third argument tcache is unused after Linux 2.6.24 so we ignore it // The third argument `tcache` is unused since Linux 2.6.24, so we ignore it.
let preempt_guard = disable_preempt();
let cpuid = preempt_guard.current_cpu(); // The system call itself is inherently racy, so using `current_racy` here should be fine.
drop(preempt_guard); let current_cpu = CpuId::current_racy().as_usize() as u32;
// TODO: Support NUMA.
let current_node = 0u32;
debug!( debug!(
"getcpu: cpuid = {}, total_cpus = {}", "[sys_getcpu]: cpu = {} (total {}), node = {}",
cpuid.as_usize(), current_cpu,
ostd::cpu::num_cpus() 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 { if cpu != 0 {
ctx.user_space() ctx.user_space().write_val(cpu, &current_cpu)?;
.write_val::<usize>(cpu, &cpuid.as_usize())?;
} }
if node != 0 { if node != 0 {
ctx.user_space().write_val::<usize>(node, &0)?; // TODO: NUMA is not supported ctx.user_space().write_val(node, &current_node)?;
} }
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
} }

View File

@ -1,24 +1,29 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
#define _GNU_SOURCE #include "../network/test.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <unistd.h>
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 struct int_pair cpu = { .first = 0xdeadbeef, .second = 0xbeefdead };
// use the getcpu syscall to retrieve CPU info struct int_pair node = { .first = 0xbeefdead, .second = 0xdeadbeef };
long ret = syscall(SYS_getcpu, &cpu, &node, NULL);
if (ret != 0) { // Use `syscall()` here because `getcpu()` from glibc may not use
perror("syscall getcpu"); // the system call to retrieve CPU information.
exit(EXIT_FAILURE); TEST_SUCC(syscall(SYS_getcpu, NULL, NULL));
}
// Our CI has a maximum of 4 CPUs, and NUMA support is not yet
printf("getcpu syscall: cpu = %u, node = %u\n", cpu, node); // available. Update these conditions if we have more than 4 CPUs
// or if NUMA support is added.
return 0; TEST_RES(syscall(SYS_getcpu, &cpu, &node),
cpu.first < 4 && cpu.second == 0xbeefdead && node.first == 0 &&
node.second == 0xdeadbeef);
} }
END_TEST()

View File

@ -21,6 +21,7 @@ exit/exit_procfs
eventfd2/eventfd2 eventfd2/eventfd2
fork/fork fork/fork
fork_c/fork fork_c/fork
getcpu/getcpu
getpid/getpid getpid/getpid
hello_pie/hello hello_pie/hello
hello_world/hello_world hello_world/hello_world