[sys] unix: add CPUSetDynamic for systems with more than 1024 CPUs

10 views
Skip to first unread message

Kirill Kolyshkin (Gerrit)

unread,
Jan 10, 2026, 8:00:00 PMJan 10
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Kirill Kolyshkin has uploaded the change for review

Commit message

unix: add CPUSetDynamic for systems with more than 1024 CPUs

The existing CPUSet type is a fixed-size array limited to 1024 CPUs,
which makes it problematic to use for large systems (such as Google's
X4 instances with 1440 and 1920 vCPUs), see e.g.
https://github.com/opencontainers/runc/issues/5023.

Introduce CPUSetDynamic type and NewCPUSet constructor to support large
systems. The bit-managing routines (set/clear/isset/fill/count) are
separated and reused.

Add variants of SchedGetaffinity, SchedSetaffinity and SetMemPolicy
that accept the new type.

Amend the documentation for CPUSet.

Add tests for new functionality (mostly a copy of existing tests).

This is an alternative to CL 727540 / CL 727541.
Co-Authored-By: Claude Sonnet 4.5 <nor...@anthropic.com>
Change-Id: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1

Change diff

diff --git a/unix/affinity_linux.go b/unix/affinity_linux.go
index 3ea4703..af5e6c8 100644
--- a/unix/affinity_linux.go
+++ b/unix/affinity_linux.go
@@ -13,11 +13,19 @@

const cpuSetSize = _CPU_SETSIZE / _NCPUBITS

-// CPUSet represents a CPU affinity mask.
+// CPUSet represents a bit mask of CPUs, to be used with [SchedGetaffinity], [SchedSetaffinity],
+// and [SetMemPolicy].
+//
+// Note that this a fixed-size type that can represent CPU IDs 0 through 1023 only.
+// Use [CPUSetDynamic]/[NewCPUSet] instead to avoid this limit.
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)))
+// CPUSetDynamic represents a bit mask of CPUs, to be used with [SchedGetaffinityDynamic],
+// [SchedSetaffinityDynamic], and [SetMemPolicyDynamic]. Use [NewCPUSet] to allocate.
+type CPUSetDynamic []cpuMask
+
+func schedAffinity(trap uintptr, pid int, size uintptr, ptr unsafe.Pointer) error {
+ _, _, e := RawSyscall(trap, uintptr(pid), uintptr(size), uintptr(ptr))
if e != 0 {
return errnoErr(e)
}
@@ -27,13 +35,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 {
- return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
+ return schedAffinity(SYS_SCHED_GETAFFINITY, pid, unsafe.Sizeof(*set), unsafe.Pointer(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 {
- return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
+ return schedAffinity(SYS_SCHED_SETAFFINITY, pid, unsafe.Sizeof(*set), unsafe.Pointer(set))
}

// Zero clears the set s, so that it contains no CPUs.
@@ -45,9 +53,7 @@
// will silently ignore any invalid CPU bits in [CPUSet] so this is an
// efficient way of resetting the CPU affinity of a process.
func (s *CPUSet) Fill() {
- for i := range s {
- s[i] = ^cpuMask(0)
- }
+ cpuMaskFill(s[:])
}

func cpuBitsIndex(cpu int) int {
@@ -58,24 +64,27 @@
return cpuMask(1 << (uint(cpu) % _NCPUBITS))
}

-// Set adds cpu to the set s.
-func (s *CPUSet) Set(cpu int) {
+func cpuMaskFill(s []cpuMask) {
+ for i := range s {
+ s[i] = ^cpuMask(0)
+ }
+}
+
+func cpuMaskSet(s []cpuMask, cpu int) {
i := cpuBitsIndex(cpu)
if i < len(s) {
s[i] |= cpuBitsMask(cpu)
}
}

-// Clear removes cpu from the set s.
-func (s *CPUSet) Clear(cpu int) {
+func cpuMaskClear(s []cpuMask, cpu int) {
i := cpuBitsIndex(cpu)
if i < len(s) {
s[i] &^= cpuBitsMask(cpu)
}
}

-// IsSet reports whether cpu is in the set s.
-func (s *CPUSet) IsSet(cpu int) bool {
+func cpuMaskIsSet(s []cpuMask, cpu int) bool {
i := cpuBitsIndex(cpu)
if i < len(s) {
return s[i]&cpuBitsMask(cpu) != 0
@@ -83,11 +92,95 @@
return false
}

-// Count returns the number of CPUs in the set s.
-func (s *CPUSet) Count() int {
+func cpuMaskCount(s []cpuMask) int {
c := 0
for _, b := range s {
c += bits.OnesCount64(uint64(b))
}
return c
}
+
+// Set adds cpu to the set s. If cpu is out of bounds for s, no action is taken.
+func (s *CPUSet) Set(cpu int) {
+ cpuMaskSet(s[:], cpu)
+}
+
+// Clear removes cpu from the set s. If cpu is out of bounds for s, no action is taken.
+func (s *CPUSet) Clear(cpu int) {
+ cpuMaskClear(s[:], cpu)
+}
+
+// IsSet reports whether cpu is in the set s.
+func (s *CPUSet) IsSet(cpu int) bool {
+ return cpuMaskIsSet(s[:], cpu)
+}
+
+// Count returns the number of CPUs in the set s.
+func (s *CPUSet) Count() int {
+ return cpuMaskCount(s[:])
+}
+
+// NewCPUSet creates a dynamically-sized CPU affinity mask capable of
+// representing CPU IDs up to maxCPU (exclusive).
+func NewCPUSet(maxCPU int) CPUSetDynamic {
+ numMasks := (maxCPU + _NCPUBITS - 1) / _NCPUBITS
+ if numMasks == 0 {
+ numMasks = 1
+ }
+ return make(CPUSetDynamic, numMasks)
+}
+
+// Zero clears the set s, so that it contains no CPUs.
+func (s CPUSetDynamic) Zero() {
+ clear(s)
+}
+
+// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity]
+// will silently ignore any invalid CPU bits in [CPUSet] so this is an
+// efficient way of resetting the CPU affinity of a process.
+func (s CPUSetDynamic) Fill() {
+ cpuMaskFill(s)
+}
+
+// Set adds cpu to the set s. If cpu is out of bounds for s, no action is taken.
+func (s CPUSetDynamic) Set(cpu int) {
+ cpuMaskSet(s, cpu)
+}
+
+// Clear removes cpu from the set s. If cpu is out of bounds for s, no action is taken.
+func (s CPUSetDynamic) Clear(cpu int) {
+ cpuMaskClear(s, cpu)
+}
+
+// IsSet reports whether cpu is in the set s.
+func (s CPUSetDynamic) IsSet(cpu int) bool {
+ return cpuMaskIsSet(s, cpu)
+}
+
+// Count returns the number of CPUs in the set s.
+func (s CPUSetDynamic) Count() int {
+ return cpuMaskCount(s)
+}
+
+func (s CPUSetDynamic) size() uintptr {
+ return uintptr(len(s)) * unsafe.Sizeof(cpuMask(0))
+}
+
+func (s CPUSetDynamic) pointer() unsafe.Pointer {
+ if len(s) == 0 {
+ return nil
+ }
+ return unsafe.Pointer(&s[0])
+}
+
+// SchedGetaffinityDynamic gets the CPU affinity mask of the thread specified by pid.
+// If pid is 0 the calling thread is used.
+func SchedGetaffinityDynamic(pid int, set CPUSetDynamic) error {
+ return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set.size(), set.pointer())
+}
+
+// SchedSetaffinityDynamic sets the CPU affinity mask of the thread specified by pid.
+// If pid is 0 the calling thread is used.
+func SchedSetaffinityDynamic(pid int, set CPUSetDynamic) error {
+ return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set.size(), set.pointer())
+}
diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go
index 06c0eea..f7b82bc 100644
--- a/unix/syscall_linux.go
+++ b/unix/syscall_linux.go
@@ -2644,8 +2644,12 @@
//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 uintptr) (err error) = SYS_SET_MEMPOLICY

func SetMemPolicy(mode int, mask *CPUSet) error {
- return setMemPolicy(mode, mask, _CPU_SETSIZE)
+ return setMemPolicy(mode, unsafe.Pointer(mask), _CPU_SETSIZE)
+}
+
+func SetMemPolicyDynamic(mode int, mask CPUSetDynamic) error {
+ return setMemPolicy(mode, mask.pointer(), mask.size())
}
diff --git a/unix/syscall_linux_test.go b/unix/syscall_linux_test.go
index d3075ca..0baa1e8 100644
--- a/unix/syscall_linux_test.go
+++ b/unix/syscall_linux_test.go
@@ -19,6 +19,7 @@
"path/filepath"
"runtime"
"runtime/debug"
+ "slices"
"strconv"
"strings"
"syscall"
@@ -512,7 +513,12 @@
}

func TestSchedSetaffinity(t *testing.T) {
+ const maxcpus = 1024 // _CPU_SETSIZE
var newMask unix.CPUSet
+ newMask.Fill()
+ if count := newMask.Count(); count != maxcpus {
+ t.Errorf("Fill: got %d CPUs, want %d", count, maxcpus)
+ }
newMask.Zero()
if newMask.Count() != 0 {
t.Errorf("CpuZero: didn't zero CPU set: %v", newMask)
@@ -588,6 +594,89 @@
}
}

+func TestSchedSetaffinityDynamic(t *testing.T) {
+ const maxcpus = 4096
+
+ newMask := unix.NewCPUSet(maxcpus)
+ newMask.Fill()
+ if count := newMask.Count(); count != maxcpus {
+ t.Errorf("Fill: got %d CPUs, want %d", count, maxcpus)
+ }
+ newMask.Zero()
+ if newMask.Count() != 0 {
+ t.Errorf("Zero: didn't zero CPU set: %v", newMask)
+ }
+ cpu := 1
+ newMask.Set(cpu)
+ if newMask.Count() != 1 || !newMask.IsSet(cpu) {
+ t.Errorf("Set: didn't set CPU %d in set: %v", cpu, newMask)
+ }
+ cpu = 5
+ newMask.Set(cpu)
+ if newMask.Count() != 2 || !newMask.IsSet(cpu) {
+ t.Errorf("Set: didn't set CPU %d in set: %v", cpu, newMask)
+ }
+ newMask.Clear(cpu)
+ if newMask.Count() != 1 || newMask.IsSet(cpu) {
+ t.Errorf("Clear: didn't clear CPU %d in set: %v", cpu, newMask)
+ }
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ oldMask := unix.NewCPUSet(maxcpus)
+ err := unix.SchedGetaffinityDynamic(0, oldMask)
+ if err != nil {
+ t.Fatalf("SchedGetaffinityDynamic: %v", err)
+ }
+
+ if runtime.NumCPU() < 2 {
+ t.Skip("skipping setaffinity tests on single CPU system")
+ }
+ if runtime.GOOS == "android" {
+ t.Skip("skipping setaffinity tests on android")
+ }
+
+ // On a system like ppc64x where some cores can be disabled using ppc64_cpu,
+ // setaffinity should only be called with enabled cores. The valid cores
+ // are found from the oldMask, but if none are found then the setaffinity
+ // tests are skipped. Issue #27875.
+ cpu = 1
+ if !oldMask.IsSet(cpu) {
+ newMask.Zero()
+ for i := range len(oldMask) {
+ if oldMask.IsSet(i) {
+ newMask.Set(i)
+ break
+ }
+ }
+ if newMask.Count() == 0 {
+ t.Skip("skipping setaffinity tests if CPU not available")
+ }
+ }
+
+ err = unix.SchedSetaffinityDynamic(0, newMask)
+ if err != nil {
+ t.Fatalf("SchedSetaffinityDynamic: %v", err)
+ }
+
+ gotMask := unix.NewCPUSet(maxcpus)
+ err = unix.SchedGetaffinityDynamic(0, gotMask)
+ if err != nil {
+ t.Fatalf("SchedGetaffinityDynamic: %v", err)
+ }
+
+ if !slices.Equal(gotMask, newMask) {
+ t.Errorf("SchedSetaffinityDynamic: returned affinity mask does not match set affinity mask (%+v != %+v", gotMask, newMask)
+ }
+
+ // Restore old mask so it doesn't affect successive tests.
+ err = unix.SchedSetaffinityDynamic(0, oldMask)
+ if err != nil {
+ t.Fatalf("SchedSetaffinityDynamic: %v", err)
+ }
+}
+
func TestStatx(t *testing.T) {
var stx unix.Statx_t
err := unix.Statx(unix.AT_FDCWD, ".", 0, 0, &stx)
diff --git a/unix/zsyscall_linux.go b/unix/zsyscall_linux.go
index 8935d10..886f5de 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 uintptr) (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/syscall_linux_test.go
  • M unix/zsyscall_linux.go
Change size: M
Delta: 4 files changed, 206 insertions(+), 20 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: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
Gerrit-Change-Number: 735380
Gerrit-PatchSet: 1
Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Kirill Kolyshkin (Gerrit)

unread,
Jan 10, 2026, 8:00:39 PMJan 10
to goph...@pubsubhelper.golang.org, Tobias Klauser, Michael Pratt, golang-co...@googlegroups.com

Kirill Kolyshkin voted Commit-Queue+1

Commit-Queue+1
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: comment
Gerrit-Project: sys
Gerrit-Branch: master
Gerrit-Change-Id: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
Gerrit-Change-Number: 735380
Gerrit-PatchSet: 1
Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
Gerrit-Reviewer: Kirill Kolyshkin <koly...@gmail.com>
Gerrit-CC: Michael Pratt <mpr...@google.com>
Gerrit-CC: Tobias Klauser <tobias....@gmail.com>
Gerrit-Comment-Date: Sun, 11 Jan 2026 01:00:36 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy

Kirill Kolyshkin (Gerrit)

unread,
Jan 10, 2026, 8:07:24 PMJan 10
to goph...@pubsubhelper.golang.org, Go LUCI, Tobias Klauser, Michael Pratt, golang-co...@googlegroups.com

Kirill Kolyshkin added 1 comment

Patchset-level comments
File-level comment, Patchset 1 (Latest):
Kirill Kolyshkin . resolved

Note this is a replacement for CL 727540 / CL 727541.

I don't really like this approach, as it looks even worse than what we have in glibc, but apparently there's no better way as we used a fixed type from the beginning and have to maintain API compatibility.

Having said that, if you see a better way, please speak up.

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: comment
Gerrit-Project: sys
Gerrit-Branch: master
Gerrit-Change-Id: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
Gerrit-Change-Number: 735380
Gerrit-PatchSet: 1
Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
Gerrit-Reviewer: Kirill Kolyshkin <koly...@gmail.com>
Gerrit-CC: Michael Pratt <mpr...@google.com>
Gerrit-CC: Tobias Klauser <tobias....@gmail.com>
Gerrit-Comment-Date: Sun, 11 Jan 2026 01:07:21 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
satisfied_requirement
open
diffy

Kirill Kolyshkin (Gerrit)

unread,
Jan 12, 2026, 7:45:52 PMJan 12
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Kirill Kolyshkin uploaded new patchset

Kirill Kolyshkin uploaded patch set #2 to this change.
Following approvals got outdated and were removed:
  • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
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: newpatchset
Gerrit-Project: sys
Gerrit-Branch: master
Gerrit-Change-Id: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
Gerrit-Change-Number: 735380
Gerrit-PatchSet: 2
Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
Gerrit-Reviewer: Kirill Kolyshkin <koly...@gmail.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Kirill Kolyshkin (Gerrit)

unread,
Jan 12, 2026, 7:46:25 PMJan 12
to goph...@pubsubhelper.golang.org, Go LUCI, Tobias Klauser, Michael Pratt, golang-co...@googlegroups.com

Kirill Kolyshkin voted Commit-Queue+1

Commit-Queue+1
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: comment
Gerrit-Project: sys
Gerrit-Branch: master
Gerrit-Change-Id: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
Gerrit-Change-Number: 735380
Gerrit-PatchSet: 2
Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
Gerrit-Reviewer: Kirill Kolyshkin <koly...@gmail.com>
Gerrit-CC: Michael Pratt <mpr...@google.com>
Gerrit-CC: Tobias Klauser <tobias....@gmail.com>
Gerrit-Comment-Date: Tue, 13 Jan 2026 00:46:21 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy

Michael Pratt (Gerrit)

unread,
Feb 23, 2026, 6:26:37 PMFeb 23
to Kirill Kolyshkin, goph...@pubsubhelper.golang.org, Michael Pratt, Ian Lance Taylor, Tobias Klauser, Go LUCI, golang-co...@googlegroups.com
Attention needed from Ian Lance Taylor, Kirill Kolyshkin and Tobias Klauser

Michael Pratt voted and added 3 comments

Votes added by Michael Pratt

Code-Review+1

3 comments

Patchset-level comments
Kirill Kolyshkin . resolved

Note this is a replacement for CL 727540 / CL 727541.

I don't really like this approach, as it looks even worse than what we have in glibc, but apparently there's no better way as we used a fixed type from the beginning and have to maintain API compatibility.

Having said that, if you see a better way, please speak up.

Michael Pratt

I think this is not so bad. NewCPUSet is a good name. If you use that plus the methods you never actually see the CPUSetDynamic name.

Probably the most awkward part is SchedSetaffinityDynamic, since you actually have the see the "dynamic" part.

I don't really have better suggestions for "dynamic" either.

File-level comment, Patchset 2 (Latest):
Michael Pratt . resolved

Pretty much LGTM, @ia...@golang.org do you have any thoughts on this API?

File unix/affinity_linux.go
Line 177, Patchset 2 (Latest):// If pid is 0 the calling thread is used.
Michael Pratt . resolved

On Linux at least, sched_getaffinity returns EINVAL if the cpu set is too small. I wonder if we should document that here and on SchedGetaffinity, since it is relevant to custom CPUSets?

Open in Gerrit

Related details

Attention is currently required from:
  • Ian Lance Taylor
  • Kirill Kolyshkin
  • Tobias Klauser
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement 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: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
    Gerrit-Change-Number: 735380
    Gerrit-PatchSet: 2
    Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
    Gerrit-Reviewer: Ian Lance Taylor <ia...@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: Ian Lance Taylor <ia...@golang.org>
    Gerrit-Attention: Tobias Klauser <tobias....@gmail.com>
    Gerrit-Comment-Date: Mon, 23 Feb 2026 23:26:33 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Kirill Kolyshkin <koly...@gmail.com>
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy

    Kirill Kolyshkin (Gerrit)

    unread,
    Feb 23, 2026, 6:48:36 PMFeb 23
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
    Attention needed from Ian Lance Taylor, Kirill Kolyshkin and Tobias Klauser

    Kirill Kolyshkin uploaded new patchset

    Kirill Kolyshkin uploaded patch set #3 to this change.
    Following approvals got outdated and were removed:
    • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI

    Related details

    Attention is currently required from:
    • Ian Lance Taylor
    • Kirill Kolyshkin
    • 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: newpatchset
      Gerrit-Project: sys
      Gerrit-Branch: master
      Gerrit-Change-Id: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
      Gerrit-Change-Number: 735380
      Gerrit-PatchSet: 3
      unsatisfied_requirement
      satisfied_requirement
      open
      diffy

      Kirill Kolyshkin (Gerrit)

      unread,
      Feb 23, 2026, 6:48:55 PMFeb 23
      to goph...@pubsubhelper.golang.org, Michael Pratt, Ian Lance Taylor, Tobias Klauser, Go LUCI, golang-co...@googlegroups.com
      Attention needed from Ian Lance Taylor, Michael Pratt and Tobias Klauser

      Kirill Kolyshkin voted and added 2 comments

      Votes added by Kirill Kolyshkin

      Commit-Queue+1

      2 comments

      Patchset-level comments
      Kirill Kolyshkin . resolved

      Note this is a replacement for CL 727540 / CL 727541.

      I don't really like this approach, as it looks even worse than what we have in glibc, but apparently there's no better way as we used a fixed type from the beginning and have to maintain API compatibility.

      Having said that, if you see a better way, please speak up.

      Michael Pratt

      I think this is not so bad. NewCPUSet is a good name. If you use that plus the methods you never actually see the CPUSetDynamic name.

      Probably the most awkward part is SchedSetaffinityDynamic, since you actually have the see the "dynamic" part.

      I don't really have better suggestions for "dynamic" either.

      Kirill Kolyshkin

      I guess the only way to avoid the "Dynamic" suffix is to make SchedGetaffinity, SchedSetaffinity and SetMemPolicy methods of CPUSetDynamic.

      OTOH it'd be a bit messy since bit-manipulation routines and syscalls are all mixed together.

      File unix/affinity_linux.go
      Line 177, Patchset 2:// If pid is 0 the calling thread is used.
      Michael Pratt . resolved

      On Linux at least, sched_getaffinity returns EINVAL if the cpu set is too small. I wonder if we should document that here and on SchedGetaffinity, since it is relevant to custom CPUSets?

      Kirill Kolyshkin

      In general, x/sys/unix do not duplicate man pages, but in this case it actually makes sense (and can actually be used to check if the mask size is adequate).

      Added.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Ian Lance Taylor
      • 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: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
      Gerrit-Change-Number: 735380
      Gerrit-PatchSet: 3
      Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
      Gerrit-Reviewer: Ian Lance Taylor <ia...@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: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Attention: Michael Pratt <mpr...@google.com>
      Gerrit-Attention: Tobias Klauser <tobias....@gmail.com>
      Gerrit-Comment-Date: Mon, 23 Feb 2026 23:48:52 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      Comment-In-Reply-To: Kirill Kolyshkin <koly...@gmail.com>
      Comment-In-Reply-To: Michael Pratt <mpr...@google.com>
      unsatisfied_requirement
      satisfied_requirement
      open
      diffy

      Kirill Kolyshkin (Gerrit)

      unread,
      Mar 23, 2026, 4:24:41 PMMar 23
      to goph...@pubsubhelper.golang.org, Go LUCI, Michael Pratt, Ian Lance Taylor, Tobias Klauser, golang-co...@googlegroups.com
      Attention needed from Ian Lance Taylor, Michael Pratt and Tobias Klauser

      Kirill Kolyshkin added 1 comment

      Patchset-level comments
      File-level comment, Patchset 3 (Latest):
      Kirill Kolyshkin . resolved

      Anything I can do to move this forward?

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Ian Lance Taylor
      • Michael Pratt
      • Tobias Klauser
      Submit Requirements:
        • requirement is not satisfiedCode-Review
        • requirement 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: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
        Gerrit-Change-Number: 735380
        Gerrit-PatchSet: 3
        Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
        Gerrit-Reviewer: Ian Lance Taylor <ia...@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: Ian Lance Taylor <ia...@golang.org>
        Gerrit-Attention: Michael Pratt <mpr...@google.com>
        Gerrit-Attention: Tobias Klauser <tobias....@gmail.com>
        Gerrit-Comment-Date: Mon, 23 Mar 2026 20:24:39 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        unsatisfied_requirement
        satisfied_requirement
        open
        diffy

        Tobias Klauser (Gerrit)

        unread,
        Mar 25, 2026, 6:37:17 PMMar 25
        to Kirill Kolyshkin, goph...@pubsubhelper.golang.org, Go LUCI, Michael Pratt, Ian Lance Taylor, golang-co...@googlegroups.com
        Attention needed from Ian Lance Taylor, Kirill Kolyshkin and Michael Pratt

        Tobias Klauser voted and added 1 comment

        Votes added by Tobias Klauser

        Code-Review+2

        1 comment

        File unix/affinity_linux.go
        Line 138, Patchset 3 (Latest):// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity]

        // will silently ignore any invalid CPU bits in [CPUSet] so this is an
        Tobias Klauser . unresolved

        Should this mention the *Dynamic variants instead?

        ```suggestion
        // Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinityDynamic]
        // will silently ignore any invalid CPU bits in [CPUSetDynamic] so this is an
        ```

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Ian Lance Taylor
        • Kirill Kolyshkin
        • Michael Pratt
        Submit Requirements:
        • requirement 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: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
        Gerrit-Change-Number: 735380
        Gerrit-PatchSet: 3
        Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
        Gerrit-Reviewer: Ian Lance Taylor <ia...@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: Ian Lance Taylor <ia...@golang.org>
        Gerrit-Attention: Michael Pratt <mpr...@google.com>
        Gerrit-Comment-Date: Wed, 25 Mar 2026 22:37:10 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: Yes
        satisfied_requirement
        unsatisfied_requirement
        open
        diffy

        Kirill Kolyshkin (Gerrit)

        unread,
        Mar 25, 2026, 7:13:57 PMMar 25
        to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
        Attention needed from Ian Lance Taylor, Kirill Kolyshkin and Michael Pratt

        Kirill Kolyshkin uploaded new patchset

        Kirill Kolyshkin uploaded patch set #4 to this change.
        Following approvals got outdated and were removed:
        • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI

        Related details

        Attention is currently required from:
        • Ian Lance Taylor
        • Kirill Kolyshkin
        • Michael Pratt
        Submit Requirements:
          • requirement satisfiedCode-Review
          • requirement is not 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: newpatchset
          Gerrit-Project: sys
          Gerrit-Branch: master
          Gerrit-Change-Id: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
          Gerrit-Change-Number: 735380
          Gerrit-PatchSet: 4
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy

          Kirill Kolyshkin (Gerrit)

          unread,
          Mar 25, 2026, 7:14:16 PMMar 25
          to goph...@pubsubhelper.golang.org, Tobias Klauser, Go LUCI, Michael Pratt, Ian Lance Taylor, golang-co...@googlegroups.com
          Attention needed from Ian Lance Taylor and Michael Pratt

          Kirill Kolyshkin voted and added 1 comment

          Votes added by Kirill Kolyshkin

          Commit-Queue+1

          1 comment

          File unix/affinity_linux.go
          Line 138, Patchset 3:// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity]

          // will silently ignore any invalid CPU bits in [CPUSet] so this is an
          Tobias Klauser . resolved

          Should this mention the *Dynamic variants instead?

          ```suggestion
          // Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinityDynamic]
          // will silently ignore any invalid CPU bits in [CPUSetDynamic] so this is an
          ```

          Kirill Kolyshkin

          Thanks, fixed.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Ian Lance Taylor
          • Michael Pratt
          Submit Requirements:
          • requirement 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: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
          Gerrit-Change-Number: 735380
          Gerrit-PatchSet: 3
          Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@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: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Attention: Michael Pratt <mpr...@google.com>
          Gerrit-Comment-Date: Wed, 25 Mar 2026 23:14:13 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: Yes
          Comment-In-Reply-To: Tobias Klauser <tobias....@gmail.com>
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy

          Kirill Kolyshkin (Gerrit)

          unread,
          Apr 4, 2026, 1:52:41 AM (5 days ago) Apr 4
          to goph...@pubsubhelper.golang.org, Tobias Klauser, Go LUCI, Michael Pratt, Ian Lance Taylor, golang-co...@googlegroups.com
          Attention needed from Ian Lance Taylor and Michael Pratt

          Kirill Kolyshkin voted Commit-Queue+1

          Commit-Queue+1
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Ian Lance Taylor
          • Michael Pratt
          Submit Requirements:
          • requirement 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: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
          Gerrit-Change-Number: 735380
          Gerrit-PatchSet: 4
          Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@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: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Attention: Michael Pratt <mpr...@google.com>
          Gerrit-Comment-Date: Sat, 04 Apr 2026 05:52:37 +0000
          Gerrit-HasComments: No
          Gerrit-Has-Labels: Yes
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy

          David Chase (Gerrit)

          unread,
          Apr 8, 2026, 6:39:35 AM (18 hours ago) Apr 8
          to Kirill Kolyshkin, goph...@pubsubhelper.golang.org, Go LUCI, Tobias Klauser, Michael Pratt, Ian Lance Taylor, golang-co...@googlegroups.com
          Attention needed from Ian Lance Taylor, Kirill Kolyshkin and Michael Pratt

          David Chase voted Code-Review+1

          Code-Review+1
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Ian Lance Taylor
          • Kirill Kolyshkin
          • Michael Pratt
          Submit Requirements:
            • requirement satisfiedCode-Review
            • requirement satisfiedNo-Unresolved-Comments
            • requirement 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: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
            Gerrit-Change-Number: 735380
            Gerrit-PatchSet: 4
            Gerrit-Owner: Kirill Kolyshkin <koly...@gmail.com>
            Gerrit-Reviewer: David Chase <drc...@google.com>
            Gerrit-Reviewer: Ian Lance Taylor <ia...@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: Ian Lance Taylor <ia...@golang.org>
            Gerrit-Attention: Michael Pratt <mpr...@google.com>
            Gerrit-Comment-Date: Wed, 08 Apr 2026 10:39:31 +0000
            Gerrit-HasComments: No
            Gerrit-Has-Labels: Yes
            satisfied_requirement
            open
            diffy

            Kirill Kolyshkin (Gerrit)

            unread,
            Apr 8, 2026, 7:32:38 PM (5 hours ago) Apr 8
            to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, David Chase, Go LUCI, Tobias Klauser, Michael Pratt, Ian Lance Taylor, golang-co...@googlegroups.com

            Kirill Kolyshkin submitted the change with unreviewed changes

            Unreviewed changes

            3 is the latest approved patch-set.
            The change was submitted with unreviewed changes in the following files:

            ```
            The name of the file: unix/affinity_linux.go
            Insertions: 2, Deletions: 2.

            @@ -135,8 +135,8 @@
            clear(s)
            }

            -// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity]
            -// will silently ignore any invalid CPU bits in [CPUSet] so this is an
            +// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinityDynamic]
            +// will silently ignore any invalid CPU bits in [CPUSetDynamic] so this is an

            // efficient way of resetting the CPU affinity of a process.
             func (s CPUSetDynamic) Fill() {
            cpuMaskFill(s)
            ```

            Change information

            Commit message:
            unix: add CPUSetDynamic for systems with more than 1024 CPUs

            The existing CPUSet type is a fixed-size array limited to 1024 CPUs,
            which makes it problematic to use for large systems (such as Google's
            X4 instances with 1440 and 1920 vCPUs), see e.g.
            https://github.com/opencontainers/runc/issues/5023.

            Introduce CPUSetDynamic type and NewCPUSet constructor to support large
            systems. The bit-managing routines (set/clear/isset/fill/count) are
            separated and reused.

            Add variants of SchedGetaffinity, SchedSetaffinity and SetMemPolicy
            that accept the new type.

            Amend the documentation for CPUSet.

            Amend the existing TestSchedSetaffinity to:
            - test set.Fill;
            - use t.Cleanup to restore the affinity.


            Add tests for new functionality (mostly a copy of existing tests).

            This is an alternative to CL 727540 / CL 727541.
            Co-Authored-By: Claude Sonnet 4.5 <nor...@anthropic.com>
            Change-Id: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
            Reviewed-by: Tobias Klauser <tobias....@gmail.com>
            Reviewed-by: David Chase <drc...@google.com>
            Reviewed-by: Michael Pratt <mpr...@google.com>
            Files:
            • M unix/affinity_linux.go
            • M unix/syscall_linux.go
            • M unix/syscall_linux_test.go
            • M unix/zsyscall_linux.go
            Change size: M
            Delta: 4 files changed, 216 insertions(+), 23 deletions(-)
            Branch: refs/heads/master
            Submit Requirements:
            • requirement satisfiedCode-Review: +1 by David Chase, +2 by Tobias Klauser, +1 by Michael Pratt
            • requirement satisfiedTryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
            Open in Gerrit
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: merged
            Gerrit-Project: sys
            Gerrit-Branch: master
            Gerrit-Change-Id: I51bba0305b8dfa7a88a4e7fb8758d73f798574f1
            Gerrit-Change-Number: 735380
            Gerrit-PatchSet: 5
            open
            diffy
            satisfied_requirement
            Reply all
            Reply to author
            Forward
            0 new messages