@@ -188,11 +188,7 @@ func (p *setnsProcess) startWithCPUAffinity() error {
188
188
}
189
189
190
190
func (p * setnsProcess ) setFinalCPUAffinity () error {
191
- aff := p .config .CPUAffinity
192
- if aff == nil || aff .Final == nil {
193
- return nil
194
- }
195
- if err := unix .SchedSetaffinity (p .pid (), aff .Final ); err != nil {
191
+ if err := unix .SchedSetaffinity (p .pid (), p .config .CPUAffinity .Final ); err != nil {
196
192
return fmt .Errorf ("error setting final CPU affinity: %w" , err )
197
193
}
198
194
return nil
@@ -254,9 +250,16 @@ func (p *setnsProcess) start() (retErr error) {
254
250
}
255
251
}
256
252
}
257
- // Set final CPU affinity right after the process is moved into container's cgroup.
258
- if err := p .setFinalCPUAffinity (); err != nil {
259
- return err
253
+
254
+ if aff := p .config .CPUAffinity ; aff == nil || aff .Final == nil {
255
+ if err := setAffinityAll (p .pid ()); err != nil {
256
+ return err
257
+ }
258
+ } else {
259
+ // Set final CPU affinity right after the process is moved into container's cgroup.
260
+ if err := p .setFinalCPUAffinity (); err != nil {
261
+ return err
262
+ }
260
263
}
261
264
if p .intelRdtPath != "" {
262
265
// if Intel RDT "resource control" filesystem path exists
@@ -615,6 +618,11 @@ func (p *initProcess) start() (retErr error) {
615
618
return fmt .Errorf ("unable to apply cgroup configuration: %w" , err )
616
619
}
617
620
}
621
+
622
+ if err := setAffinityAll (p .pid ()); err != nil {
623
+ return err
624
+ }
625
+
618
626
if p .intelRdtManager != nil {
619
627
if err := p .intelRdtManager .Apply (p .pid ()); err != nil {
620
628
return fmt .Errorf ("unable to apply Intel RDT configuration: %w" , err )
@@ -981,3 +989,24 @@ func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
981
989
}
982
990
return i , nil
983
991
}
992
+
993
+ // Set all inherited cpu affinity. Old kernels do that automatically, but
994
+ // new kernels remember the affinity that was set before the cgroup move.
995
+ // This is undesirable, because it inherits the systemd affinity when the container
996
+ // should really move to the container space cpus.
997
+ // here we can't use runtime.NumCPU() to get cpu counts because it call sched_getaffinity to get cpu counts.
998
+ // If systemd set CPUAffinity then use runtime.NumCPU() can't get real cpu counts.
999
+ func setAffinityAll (pid int ) error {
1000
+ cpus , err := utils .SystemCPUCores ()
1001
+ if err != nil {
1002
+ return err
1003
+ }
1004
+ cpuset := unix.CPUSet {}
1005
+ for i := 0 ; i < int (cpus ); i ++ {
1006
+ cpuset .Set (i )
1007
+ }
1008
+ if err := unix .SchedSetaffinity (pid , & cpuset ); err != nil {
1009
+ return fmt .Errorf ("error resetting pid %d affinity: %w" , pid , err )
1010
+ }
1011
+ return nil
1012
+ }
0 commit comments