From 051b66b82d8cc76eca0da38e44ae0e7dd391ba09 Mon Sep 17 00:00:00 2001
From: zhaoxiaohu <zhaoxiaohu@kuaishou.com>
Date: Tue, 27 Aug 2024 16:04:40 +0800
Subject: [PATCH] Fix cpu share issues on systems with large amounts of cpu

On systems where the calculated cpu shares results in a value above the
max value in linux, containers getting that value are unable to start.
This occur on systems with 300+ cpu cores, and where containers are
given such a value.

This issue was fixed for the pod and qos control groups in the similar
cm.MilliCPUToShares that also has tests verifying the behavior. Since
this code already has an dependency on kubelet/cm, lets reuse that code
instead.

Reference: https://github.com/kubernetes/kubernetes/pull/106570/commits/de0ece541c7fd885a32f1562342fe85535fc11f5

Signed-off-by: zhaoxiaohu <zhaoxiaohu@kuaishou.com>
Signed-off-by: Odin Ugedal <odin@uged.al>
Signed-off-by: yuwang@kuaishou.com
---
 pkg/kubelet/kuberuntime/helpers_linux.go        | 17 -----------------
 pkg/kubelet/kuberuntime/helpers_unsupported.go  |  5 -----
 .../kuberuntime/kuberuntime_container_linux.go  |  7 ++++---
 3 files changed, 4 insertions(+), 25 deletions(-)

diff --git a/pkg/kubelet/kuberuntime/helpers_linux.go b/pkg/kubelet/kuberuntime/helpers_linux.go
index 204bc4e9..4257a014 100644
--- a/pkg/kubelet/kuberuntime/helpers_linux.go
+++ b/pkg/kubelet/kuberuntime/helpers_linux.go
@@ -19,9 +19,6 @@ limitations under the License.
 package kuberuntime
 
 const (
-	// Taken from lmctfy https://github.com/google/lmctfy/blob/master/lmctfy/controllers/cpu_controller.cc
-	minShares     = 2
-	sharesPerCPU  = 1024
 	milliCPUToCPU = 1000
 
 	// 100000 is equivalent to 100ms
@@ -29,20 +26,6 @@ const (
 	minQuotaPeriod = 1000
 )
 
-// milliCPUToShares converts milliCPU to CPU shares
-func milliCPUToShares(milliCPU int64) int64 {
-	if milliCPU == 0 {
-		// Return 2 here to really match kernel default for zero milliCPU.
-		return minShares
-	}
-	// Conceptually (milliCPU / milliCPUToCPU) * sharesPerCPU, but factored to improve rounding.
-	shares := (milliCPU * sharesPerCPU) / milliCPUToCPU
-	if shares < minShares {
-		return minShares
-	}
-	return shares
-}
-
 // milliCPUToQuota converts milliCPU to CFS quota and period values
 func milliCPUToQuota(milliCPU int64, period int64) (quota int64) {
 	// CFS quota is measured in two values:
diff --git a/pkg/kubelet/kuberuntime/helpers_unsupported.go b/pkg/kubelet/kuberuntime/helpers_unsupported.go
index cc1e88a5..8f6da8f4 100644
--- a/pkg/kubelet/kuberuntime/helpers_unsupported.go
+++ b/pkg/kubelet/kuberuntime/helpers_unsupported.go
@@ -17,8 +17,3 @@ limitations under the License.
 */
 
 package kuberuntime
-
-// milliCPUToShares converts milliCPU to CPU shares
-func milliCPUToShares(milliCPU int64) int64 {
-	return 0
-}
diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go
index d7c22c86..25fb68ad 100644
--- a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go
+++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go
@@ -28,6 +28,7 @@ import (
 	"k8s.io/klog/v2"
 	v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
 	kubefeatures "k8s.io/kubernetes/pkg/features"
+	"k8s.io/kubernetes/pkg/kubelet/cm"
 	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 	"k8s.io/kubernetes/pkg/kubelet/qos"
 )
@@ -69,11 +70,11 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.C
 	// API server does this for new containers, but we repeat this logic in Kubelet
 	// for containers running on existing Kubernetes clusters.
 	if cpuRequest.IsZero() && !cpuLimit.IsZero() {
-		cpuShares = milliCPUToShares(cpuLimit.MilliValue())
+		cpuShares = int64(cm.MilliCPUToShares(cpuLimit.MilliValue()))
 	} else {
-		// if cpuRequest.Amount is nil, then milliCPUToShares will return the minimal number
+		// if cpuRequest.Amount is nil, then MilliCPUToShares will return the minimal number
 		// of CPU shares.
-		cpuShares = milliCPUToShares(cpuRequest.MilliValue())
+		cpuShares = int64(cm.MilliCPUToShares(cpuRequest.MilliValue()))
 	}
 	lc.Resources.CpuShares = cpuShares
 	if memoryLimit != 0 {
-- 
2.33.0

