smp: 64 processors, and say how many there are

NCPU was 16, under what a desktop has today. 64 costs 48 more TSS
I/O bitmaps and scheduler stacks, about 800 KB of BSS. Past 254 the
APIC would need x2APIC mode, which is a separate change.

With more than 16 there were two other ceilings. sched_getaffinity
wrote "CPU 0" and returned 0, and musl clears every byte past the
count returned -- so the mask came back empty and nproc, make -j and
sysconf(_SC_NPROCESSORS_ONLN) all said 1, on any machine. It returns
the mask of processors that started, and its size, now. And /proc
rendered every file into 2 KB, which /proc/cpuinfo ran out of at the
eighteenth processor without a word; /proc/pci, /proc/interrupts and
/proc/mounts were each one bigger machine from the same cut. There is
one 64 KB buffer for it now behind a sleeplock, since there is no
allocator for contiguous pages, and the generators that write raw
are given the real capacity instead of a constant.

Checked under QEMU with -smp 24: nproc 24, /proc/cpuinfo whole.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-23 13:50:08 +02:00
commit c1af31f75a
5 changed files with 69 additions and 36 deletions

View file

@ -360,16 +360,27 @@ addr_t sys_setgroups(void) { return 0; }
addr_t sys_sched_yield(void) { return 0; }
// Every processor that started, since nothing here pins a process anywhere.
//
// This wrote "CPU 0" and returned 0 -- and the return value is the number of
// bytes of mask the kernel wrote, which musl uses to clear the rest. Zero
// meant all of it, so the mask came back empty and nproc, make -j and every
// thread pool sized from sysconf(_SC_NPROCESSORS_ONLN) saw one processor.
addr_t sys_sched_getaffinity(void)
{
int pid, cpusetsize;
addr_t maskp;
uchar m[(NCPU + 63) / 64 * 8];
argint(0, &pid); argint(1, &cpusetsize); argaddr(2, &maskp);
if (maskp && cpusetsize > 0) {
char *m = (char*)user_ptr(maskp, (uint64)cpusetsize);
if (m) { memset(m, 0, cpusetsize); m[0] = 1; } // CPU 0 only
}
return 0;
if (cpusetsize < (int)sizeof m || (cpusetsize & 7))
return -EINVAL;
memset(m, 0, sizeof m);
for (int i = 0; i < ncpu && i < NCPU; i++)
if (cpus[i].started)
m[i / 8] |= 1 << (i % 8);
if (copy_to_user(maskp, m, sizeof m) < 0)
return -EFAULT;
return sizeof m;
}
addr_t sys_sched_setaffinity(void) { return 0; }