Change:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: CPU Manager uses topology from cAdvisor which uses which is different from in terms of coreID's. assigns coreID's in unique manner (platform-wise) whereas has coreID's from CPU registers which are unique only on socket level. This causes some unexpected cpu assignment on platforms with more than one socket. All tests written all "false positive" Example output: From What you expected to happen: Fix either by changing the way CPU manger sees topology (use ) or redesign CPU Manager to handle coreID's as socket only unique How to reproduce it (as minimally and precisely as possible): kubelet on dual socket node G pod that requests 2 cores pod gets 2 cores on different sockets
There are no sig labels on this issue. Please by: a sig: e.g., to notify the contributor experience sig, OR the label manually: e.g., to apply the label Note: Method 1 will trigger an email to the group. You can find the group list and label list . The in the method 1 has to be replaced with one of these: bugs, feature-requests, pr-reviews, test-failures, proposals
/sig node

Discussion:
visibility = ["//visibility:public"], deps = [ "//pkg/kubelet/cm/cpuset:go_default_library", <ins> "//vendor/github.com/golang/glog:go_default_library", </ins> "//vendor/github.com/google/cadvisor/info/v1:go_default_library", ], )

import ( "fmt" <ins> "sort" "github.com/golang/glog" </ins> cadvisorapi "github.com/google/cadvisor/info/v1" "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" )

} CPUDetails := CPUDetails{} numCPUs := machineInfo.NumCores numPhysicalCores := 0 <ins> var coreID int var err error </ins> for _, socket := range machineInfo.Topology { numPhysicalCores += len(socket.Cores) for _, core := range socket.Cores { <ins> if coreID, err = getUniqueCoreID(core.Threads); err != nil { glog.Errorf("could not get unique coreID for socket: %d core %d threads: %v", socket.Id, core.Id, core.Threads) return nil, err } </ins> for _, cpu := range core.Threads { CPUDetails[cpu] = CPUInfo{ <del> CoreID:   core.Id, </del> <ins> CoreID:   coreID, </ins> SocketID: socket.Id, } }

CPUDetails: CPUDetails, }, nil } <ins> // getUniqueCoreID computes coreId as the lowest cpuID // for a given Threads []int slice. This will assure that coreID's are // platform unique (opposite to what cAdvisor reports - socket unique) func getUniqueCoreID(threads []int) (coreID int, err error) { err = nil if len(threads) == 0 { return 0, fmt.Errorf("no cpus provided") } if len(threads) != cpuset.NewCPUSet(threads...).Size() { return 0, fmt.Errorf("cpus provided are not unique") } tmpThreads := make([]int, len(threads)) copy(tmpThreads, threads) sort.Ints(tmpThreads) return tmpThreads[0], err } </ins>

}, wantErr: false, }, <ins> { name: "DualSocketHT - non unique Core'ID's", args: &cadvisorapi.MachineInfo{ NumCores: 12, Topology: []cadvisorapi.Node{ {Id: 0, Cores: []cadvisorapi.Core{ {Id: 0, Threads: []int{0, 6}}, {Id: 1, Threads: []int{1, 7}}, {Id: 2, Threads: []int{2, 8}}, }, }, {Id: 1, Cores: []cadvisorapi.Core{ {Id: 0, Threads: []int{3, 9}}, {Id: 1, Threads: []int{4, 10}}, {Id: 2, Threads: []int{5, 11}}, }, }, }, }, want: &CPUTopology{ NumCPUs:    12, NumSockets: 2, NumCores:   6, CPUDetails: map[int]CPUInfo{ 0:  {CoreID: 0, SocketID: 0}, 1:  {CoreID: 1, SocketID: 0}, 2:  {CoreID: 2, SocketID: 0}, 3:  {CoreID: 3, SocketID: 1}, 4:  {CoreID: 4, SocketID: 1}, 5:  {CoreID: 5, SocketID: 1}, 6:  {CoreID: 0, SocketID: 0}, 7:  {CoreID: 1, SocketID: 0}, 8:  {CoreID: 2, SocketID: 0}, 9:  {CoreID: 3, SocketID: 1}, 10: {CoreID: 4, SocketID: 1}, 11: {CoreID: 5, SocketID: 1}, }, }, wantErr: false, }, { name: "OneSocketHT fail", args: &cadvisorapi.MachineInfo{ NumCores: 8, Topology: []cadvisorapi.Node{ {Id: 0, Cores: []cadvisorapi.Core{ {Id: 0, Threads: []int{0, 4}}, {Id: 1, Threads: []int{1, 5}}, {Id: 2, Threads: []int{2, 2}}, // Wrong case - should fail here {Id: 3, Threads: []int{3, 7}}, }, }, }, }, want:    &CPUTopology{}, wantErr: true, }, { name: "OneSocketHT fail", args: &cadvisorapi.MachineInfo{ NumCores: 8, Topology: []cadvisorapi.Node{ {Id: 0, Cores: []cadvisorapi.Core{ {Id: 0, Threads: []int{0, 4}}, {Id: 1, Threads: []int{1, 5}}, {Id: 2, Threads: []int{2, 6}}, {Id: 3, Threads: []int{}}, // Wrong case - should fail here }, }, }, }, want:    &CPUTopology{}, wantErr: true, }, </ins> } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {