[sys] unix: add CPUSetInterface for variable-size CPU affinity masks

3 views
Skip to first unread message

Kirill Kolyshkin (Gerrit)

unread,
Dec 5, 2025, 9:14:20 PM (11 days ago) Dec 5
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Kirill Kolyshkin has uploaded the change for review

Commit message

unix: add CPUSetInterface for variable-size CPU affinity masks

The existing CPUSet type is a fixed-size array limited to 1024 CPUs,
which makes it problematic to use for large systems (see e.g.
https://github.com/opencontainers/runc/issues/5023).

This change introduces CPUSetInterface in an attempt to allow both
the existing CPUSet as well as the variable-size implementation
(see the following commit) to work functions currently accepting CPUSet.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <nor...@anthropic.com>
Change-Id: I3e96c430f18cbb18edf9ca25418c363aad92d9fe

Change diff

diff --git a/unix/affinity_linux.go b/unix/affinity_linux.go
index 3ea4703..7ef8c95 100644
--- a/unix/affinity_linux.go
+++ b/unix/affinity_linux.go
@@ -13,11 +13,25 @@

const cpuSetSize = _CPU_SETSIZE / _NCPUBITS

+// CPUSetInterface is an interface for CPU affinity masks.
+// It allows both fixed-size and variable-size CPU sets to be used
+// with affinity functions.
+type CPUSetInterface interface {
+ Zero()
+ Fill()
+ Set(cpu int)
+ Clear(cpu int)
+ IsSet(cpu int) bool
+ Count() int
+ Size() int
+ Pointer() unsafe.Pointer
+}
+
// CPUSet represents a CPU affinity mask.
type CPUSet [cpuSetSize]cpuMask

-func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
- _, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
+func schedAffinity(trap uintptr, pid int, set CPUSetInterface) error {
+ _, _, e := RawSyscall(trap, uintptr(pid), uintptr(set.Size()), uintptr(set.Pointer()))
if e != 0 {
return errnoErr(e)
}
@@ -26,13 +40,13 @@

// SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.
// If pid is 0 the calling thread is used.
-func SchedGetaffinity(pid int, set *CPUSet) error {
+func SchedGetaffinity(pid int, set CPUSetInterface) error {
return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
}

// SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.
// If pid is 0 the calling thread is used.
-func SchedSetaffinity(pid int, set *CPUSet) error {
+func SchedSetaffinity(pid int, set CPUSetInterface) error {
return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
}

@@ -91,3 +105,13 @@
}
return c
}
+
+// Size returns the size of the CPU set in bytes.
+func (s *CPUSet) Size() int {
+ return int(unsafe.Sizeof(*s))
+}
+
+// Pointer returns an unsafe.Pointer to the CPU set.
+func (s *CPUSet) Pointer() unsafe.Pointer {
+ return unsafe.Pointer(s)
+}
diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go
index 06c0eea..497d1da 100644
--- a/unix/syscall_linux.go
+++ b/unix/syscall_linux.go
@@ -2644,8 +2644,8 @@
//sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error)
//sys Mseal(b []byte, flags uint) (err error)

-//sys setMemPolicy(mode int, mask *CPUSet, size int) (err error) = SYS_SET_MEMPOLICY
+//sys setMemPolicy(mode int, mask unsafe.Pointer, size int) (err error) = SYS_SET_MEMPOLICY

-func SetMemPolicy(mode int, mask *CPUSet) error {
- return setMemPolicy(mode, mask, _CPU_SETSIZE)
+func SetMemPolicy(mode int, mask CPUSetInterface) error {
+ return setMemPolicy(mode, mask.Pointer(), mask.Size())
}
diff --git a/unix/zsyscall_linux.go b/unix/zsyscall_linux.go
index 8935d10..e378761 100644
--- a/unix/zsyscall_linux.go
+++ b/unix/zsyscall_linux.go
@@ -2241,8 +2241,8 @@

// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT

-func setMemPolicy(mode int, mask *CPUSet, size int) (err error) {
- _, _, e1 := Syscall(SYS_SET_MEMPOLICY, uintptr(mode), uintptr(unsafe.Pointer(mask)), uintptr(size))
+func setMemPolicy(mode int, mask unsafe.Pointer, size int) (err error) {
+ _, _, e1 := Syscall(SYS_SET_MEMPOLICY, uintptr(mode), uintptr(mask), uintptr(size))
if e1 != 0 {
err = errnoErr(e1)
}

Change information

Files:
  • M unix/affinity_linux.go
  • M unix/syscall_linux.go
  • M unix/zsyscall_linux.go
Change size: S
Delta: 3 files changed, 33 insertions(+), 9 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: sys
Gerrit-Branch: master
Gerrit-Change-Id: I3e96c430f18cbb18edf9ca25418c363aad92d9fe
Gerrit-Change-Number: 727540
Gerrit-PatchSet: 1
Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Kirill Kolyshkin (Gerrit)

unread,
Dec 5, 2025, 9:16:04 PM (11 days ago) Dec 5
to goph...@pubsubhelper.golang.org, Tobias Klauser, Michael Pratt, Dmitri Shuralyov, golang-co...@googlegroups.com
Attention needed from Dmitri Shuralyov, Michael Pratt and Tobias Klauser

Kirill Kolyshkin voted Commit-Queue+1

Commit-Queue+1
Open in Gerrit

Related details

Attention is currently required from:
  • Dmitri Shuralyov
  • Michael Pratt
  • Tobias Klauser
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sys
Gerrit-Branch: master
Gerrit-Change-Id: I3e96c430f18cbb18edf9ca25418c363aad92d9fe
Gerrit-Change-Number: 727540
Gerrit-PatchSet: 1
Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
Gerrit-Reviewer: Dmitri Shuralyov <dmit...@golang.org>
Gerrit-Reviewer: Kirill Kolyshkin <koly...@gmail.com>
Gerrit-Reviewer: Michael Pratt <mpr...@google.com>
Gerrit-Reviewer: Tobias Klauser <tobias....@gmail.com>
Gerrit-Attention: Dmitri Shuralyov <dmit...@golang.org>
Gerrit-Attention: Tobias Klauser <tobias....@gmail.com>
Gerrit-Attention: Michael Pratt <mpr...@google.com>
Gerrit-Comment-Date: Sat, 06 Dec 2025 02:16:00 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy

Michael Pratt (Gerrit)

unread,
Dec 8, 2025, 1:54:22 PM (9 days ago) Dec 8
to Kirill Kolyshkin, goph...@pubsubhelper.golang.org, Go LUCI, Tobias Klauser, Michael Pratt, Dmitri Shuralyov, golang-co...@googlegroups.com
Attention needed from Dmitri Shuralyov, Kirill Kolyshkin and Tobias Klauser

Michael Pratt added 2 comments

Commit Message
Line 17, Patchset 1 (Latest):🤖 Generated with [Claude Code](https://claude.com/claude-code)
Michael Pratt . unresolved

No markdown in commit messages (though I appreciate the code generation disclaimer).

File unix/affinity_linux.go
Line 35, Patchset 1 (Parent):func SchedSetaffinity(pid int, set *CPUSet) error {
Michael Pratt . unresolved

Unfortunately changing the type of function arguments is not a backwards compatible change. It breaks code using the function as a function value. e.g., https://go.dev/play/p/StqvRpFMU1-

So this would need to be a new API, at which point (IMO) it may as well use CPUSetDynamic directly rather than an interface.

Open in Gerrit

Related details

Attention is currently required from:
  • Dmitri Shuralyov
  • Kirill Kolyshkin
  • Tobias Klauser
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sys
    Gerrit-Branch: master
    Gerrit-Change-Id: I3e96c430f18cbb18edf9ca25418c363aad92d9fe
    Gerrit-Change-Number: 727540
    Gerrit-PatchSet: 1
    Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
    Gerrit-Reviewer: Dmitri Shuralyov <dmit...@golang.org>
    Gerrit-Reviewer: Kirill Kolyshkin <koly...@gmail.com>
    Gerrit-Reviewer: Michael Pratt <mpr...@google.com>
    Gerrit-Reviewer: Tobias Klauser <tobias....@gmail.com>
    Gerrit-Attention: Kirill Kolyshkin <koly...@gmail.com>
    Gerrit-Attention: Dmitri Shuralyov <dmit...@golang.org>
    Gerrit-Attention: Tobias Klauser <tobias....@gmail.com>
    Gerrit-Comment-Date: Mon, 08 Dec 2025 18:54:17 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Kirill Kolyshkin (Gerrit)

    unread,
    Dec 16, 2025, 7:32:17 PM (7 hours ago) Dec 16
    to goph...@pubsubhelper.golang.org, Go LUCI, Tobias Klauser, Michael Pratt, Dmitri Shuralyov, golang-co...@googlegroups.com
    Attention needed from Michael Pratt and Tobias Klauser

    Kirill Kolyshkin added 1 comment

    File unix/affinity_linux.go
    Line 35, Patchset 1 (Parent):func SchedSetaffinity(pid int, set *CPUSet) error {
    Michael Pratt . unresolved

    Unfortunately changing the type of function arguments is not a backwards compatible change. It breaks code using the function as a function value. e.g., https://go.dev/play/p/StqvRpFMU1-

    So this would need to be a new API, at which point (IMO) it may as well use CPUSetDynamic directly rather than an interface.

    Kirill Kolyshkin

    How would you name new `Sched[GS]etaffinity` and `SetMemPolicy`? Add the `Dynamic` suffix to all of them?

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Michael Pratt
    • Tobias Klauser
    Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sys
    Gerrit-Branch: master
    Gerrit-Change-Id: I3e96c430f18cbb18edf9ca25418c363aad92d9fe
    Gerrit-Change-Number: 727540
    Gerrit-PatchSet: 1
    Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
    Gerrit-Reviewer: Dmitri Shuralyov <dmit...@golang.org>
    Gerrit-Reviewer: Kirill Kolyshkin <koly...@gmail.com>
    Gerrit-Reviewer: Michael Pratt <mpr...@google.com>
    Gerrit-Reviewer: Tobias Klauser <tobias....@gmail.com>
    Gerrit-Attention: Michael Pratt <mpr...@google.com>
    Gerrit-Attention: Tobias Klauser <tobias....@gmail.com>
    Gerrit-Comment-Date: Wed, 17 Dec 2025 00:32:14 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Michael Pratt <mpr...@google.com>
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages