Updated code snippets to match PoC branch.
This commit is contained in:
parent
b961e4eee9
commit
a6afac8372
|
|
@ -87,43 +87,39 @@ system yields two cores on the same socket.
|
||||||
contains code to build a ThreadSet from the output of `lscpu -p`.
|
contains code to build a ThreadSet from the output of `lscpu -p`.
|
||||||
1. Execute a mature external topology program like [`mpi-hwloc`][hwloc] --
|
1. Execute a mature external topology program like [`mpi-hwloc`][hwloc] --
|
||||||
potentially adding support for the hwloc file format to the Kubelet.
|
potentially adding support for the hwloc file format to the Kubelet.
|
||||||
|
1. Re-use existing discovery functionality from cAdvisor. **(preferred initial
|
||||||
|
solution)**
|
||||||
|
|
||||||
#### CPU Manager interfaces (sketch)
|
#### CPU Manager interfaces (sketch)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type CPUManagerPolicy interface {
|
type State interface {
|
||||||
Init(driver CPUDriver, topo CPUTopo)
|
GetCPUSet(containerID string) (cpuset.CPUSet, bool)
|
||||||
Add(c v1.Container, qos QoS) error
|
GetDefaultCPUSet() cpuset.CPUSet
|
||||||
Remove(c v1.Container, qos QoS) error
|
GetCPUSetOrDefault(containerID string) cpuset.CPUSet
|
||||||
|
SetCPUSet(containerID string, cpuset CPUSet)
|
||||||
|
SetDefaultCPUSet(cpuset CPUSet)
|
||||||
|
Delete(containerID string)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CPUDriver {
|
type Manager interface {
|
||||||
GetPods() []v1.Pod
|
Start()
|
||||||
GetCPUs(containerID string) CPUList
|
Policy() Policy
|
||||||
SetCPUs(containerID string, clist CPUList) error
|
RegisterContainer(p *Pod, c *Container, containerID string) error
|
||||||
// Future: RDT L3 and L2 cache masks, etc.
|
UnregisterContainer(containerID string) error
|
||||||
|
State() state.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
type CPUTopo TBD
|
type Policy interface {
|
||||||
|
Name() string
|
||||||
|
Start(s state.State)
|
||||||
|
RegisterContainer(s State, pod *Pod, container *Container, containerID string) error
|
||||||
|
UnregisterContainer(s State, containerID string) error
|
||||||
|
}
|
||||||
|
|
||||||
type CPUList string
|
type CPUSet map[int]struct{} // set operations and parsing/formatting helpers
|
||||||
|
|
||||||
func (c CPUList) Size() int {}
|
type CPUTopology TBD
|
||||||
|
|
||||||
// Returns a CPU list with size n and the remainder or
|
|
||||||
// an error if the request cannot be satisfied, taking
|
|
||||||
// into account the supplied topology.
|
|
||||||
//
|
|
||||||
// @post: c = set_union(taken, remaining),
|
|
||||||
// empty_set = set_intersection(taken, remainder)
|
|
||||||
func (c CPUList) Take(n int, topo CPUTopo) (taken CPUList,
|
|
||||||
remainder CPUList,
|
|
||||||
err error) {}
|
|
||||||
|
|
||||||
// Returns a CPU list that includes all CPUs in c and d and no others.
|
|
||||||
//
|
|
||||||
// @post: result = set_union(c, d)
|
|
||||||
func (c CPUList) Add(d CPUList) (result CPUList) {}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Kubernetes will ship with three CPU manager policies. Only one policy is
|
Kubernetes will ship with three CPU manager policies. Only one policy is
|
||||||
|
|
@ -154,69 +150,36 @@ becomes terminal.)
|
||||||
##### Implementation sketch
|
##### Implementation sketch
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Implements CPUManagerPolicy
|
func (p *staticPolicy) Start(s State) {
|
||||||
type staticManager struct {
|
// Iteration starts at index `1` here because CPU `0` is reserved
|
||||||
driver CPUDriver
|
// for infrastructure processes.
|
||||||
topo CPUTopo
|
// TODO(CD): Improve this to align with kube/system reserved resources.
|
||||||
// CPU list assigned to non-exclusive containers.
|
shared := NewCPUSet()
|
||||||
shared CPUList
|
for cpuid := 1; cpuid < p.topology.NumCPUs; cpuid++ {
|
||||||
|
shared.Add(cpuid)
|
||||||
|
}
|
||||||
|
s.SetDefaultCPUSet(shared)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *staticManager) Init(driver CPUDriver, topo CPUTopo) {
|
func (p *staticPolicy) RegisterContainer(s State, pod *Pod, container *Container, containerID string) error {
|
||||||
m.driver = driver
|
if numCPUs := numGuaranteedCPUs(pod, container); numCPUs != 0 {
|
||||||
m.topo = topo
|
// container should get some exclusively allocated CPUs
|
||||||
}
|
cpuset, err := p.allocateCPUs(s, numCPUs)
|
||||||
|
|
||||||
func (m *staticManager) Add(c v1.Container, qos QoS) error {
|
|
||||||
if p.QoS == GUARANTEED && numExclusive(c) > 0 {
|
|
||||||
excl, err := allocate(numExclusive(c))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
m.driver.SetCPUs(c.ID, excl)
|
s.SetCPUSet(containerID, cpuset)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
// container belongs in the shared pool (nothing to do; use default cpuset)
|
||||||
// Default case: assign the shared set.
|
|
||||||
m.driver.SetCPUs(c.ID, m.shared)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *staticManager) Remove(c v1.Container, qos QoS) error {
|
func (p *staticPolicy) UnregisterContainer(s State, containerID string) error {
|
||||||
m.free(m.driver.GetCPUs(c.ID))
|
if toRelease, ok := s.GetCPUSet(containerID); ok {
|
||||||
}
|
s.Delete(containerID)
|
||||||
|
p.releaseCPUs(s, toRelease)
|
||||||
func (m *staticManager) allocate(n int) (CPUList, err) {
|
|
||||||
excl, remaining, err := m.shared.Take(n, m.topo)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
}
|
||||||
m.setShared(remaining)
|
return nil
|
||||||
return excl, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *staticManager) free(c CPUList) {
|
|
||||||
m.setShared(m.shared.add(c))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *staticManager) setShared(c CPUList) {
|
|
||||||
prev := m.shared
|
|
||||||
m.shared = c
|
|
||||||
for _, pod := range m.driver.GetPods() {
|
|
||||||
for _, container := range p.Containers {
|
|
||||||
if driver.GetCPUs(container.ID) == prev {
|
|
||||||
driver.SetCPUs(m.shared)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @pre: container_qos = guaranteed
|
|
||||||
func numExclusive(c v1.Container) int {
|
|
||||||
if c.resources.requests["cpu"] % 1000 == 0 {
|
|
||||||
return c.resources.requests["cpu"] / 1000
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -238,19 +201,16 @@ _TODO: Describe the policy._
|
||||||
##### Implementation sketch
|
##### Implementation sketch
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Implements CPUManagerPolicy.
|
func (p *dynamicPolicy) Start(s State) {
|
||||||
type dynamicManager struct {}
|
// TODO
|
||||||
|
|
||||||
func (m *dynamicManager) Init(driver CPUDriver, topo CPUTopo) {
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *dynamicManager) Add(c v1.Container, qos QoS) error {
|
func (p *dynamicPolicy) RegisterContainer(s State, pod *Pod, container *Container, containerID string) error {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *dynamicManager) Remove(c v1.Container, qos QoS) error {
|
func (p *dynamicPolicy) UnregisterContainer(s State, containerID string) error {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue