diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index dbf95799e..62c68f23f 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -621,9 +621,10 @@ func assignCPU(allowed sched.CPUSet, tid ThreadID) (cpu int32) { n := int(tid) % int(allowed.NumCPUs()) // ... then pick the nth CPU in allowed. allowed.ForEachCPU(func(c uint) { - if n--; n == 0 { + if n == 0 { cpu = int32(c) } + n-- }) return cpu } diff --git a/pkg/sentry/kernel/task_test.go b/pkg/sentry/kernel/task_test.go index cfcde9a7a..5579b56d5 100644 --- a/pkg/sentry/kernel/task_test.go +++ b/pkg/sentry/kernel/task_test.go @@ -29,35 +29,41 @@ func TestTaskCPU(t *testing.T) { { mask: []byte{0xff}, tid: 1, - cpu: 0, + cpu: 1, }, { mask: []byte{0xff}, tid: 10, - cpu: 1, + cpu: 2, }, { // more than 8 cpus. mask: []byte{0xff, 0xff}, tid: 10, - cpu: 9, + cpu: 10, }, { // missing the first cpu. mask: []byte{0xfe}, tid: 1, - cpu: 1, + cpu: 2, }, { mask: []byte{0xfe}, tid: 10, - cpu: 3, + cpu: 4, }, { // missing the fifth cpu. mask: []byte{0xef}, tid: 10, - cpu: 2, + cpu: 3, + }, + { + // only the fifth cpu. + mask: []byte{0x10}, + tid: 10, + cpu: 4, }, } { assigned := assignCPU(test.mask, test.tid) diff --git a/test/syscalls/linux/getcpu.cc b/test/syscalls/linux/getcpu.cc index f4d94bd6a..2b228bff8 100644 --- a/test/syscalls/linux/getcpu.cc +++ b/test/syscalls/linux/getcpu.cc @@ -34,6 +34,19 @@ TEST(GetcpuTest, IsValidCpuStress) { } } +TEST(GetcpuTest, IsValidCpu) { + const int num_cpus = NumCPUs(); + for (int i = 0; i < num_cpus; i++) { + cpu_set_t set = {}; + int cpu; + CPU_SET(i, &set); + ASSERT_THAT(sched_setaffinity(getpid(), sizeof(set), &set), + SyscallSucceeds()); + ASSERT_THAT(cpu = sched_getcpu(), SyscallSucceeds()); + ASSERT_EQ(cpu, i); + } +} + } // namespace } // namespace testing