-
Notifications
You must be signed in to change notification settings - Fork 1.1k
handle irqbalance service #4441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
cf61f94
3cd55b2
b3b48b3
ce99737
9930cc3
13be7ae
aa46a23
84b616b
77f1b7c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,18 +26,25 @@ import ( | |
| const ( | ||
| // HighPerformance contains the high-performance runtime handler name | ||
| HighPerformance = "high-performance" | ||
| // IrqBannedCPUConfigFile contains the original banned cpu mask configuration | ||
| IrqBannedCPUConfigFile = "/etc/sysconfig/orig_irq_banned_cpus" | ||
| // IrqSmpAffinityProcFile contains the default smp affinity mask configuration | ||
| IrqSmpAffinityProcFile = "/proc/irq/default_smp_affinity" | ||
| ) | ||
|
|
||
| const ( | ||
| annotationTrue = "true" | ||
| annotationDisable = "disable" | ||
| schedDomainDir = "/proc/sys/kernel/sched_domain" | ||
| irqSmpAffinityProcFile = "/proc/irq/default_smp_affinity" | ||
| cgroupMountPoint = "/sys/fs/cgroup" | ||
| annotationTrue = "true" | ||
| annotationDisable = "disable" | ||
| schedDomainDir = "/proc/sys/kernel/sched_domain" | ||
| cgroupMountPoint = "/sys/fs/cgroup" | ||
| irqBalanceBannedCpus = "IRQBALANCE_BANNED_CPUS" | ||
| irqBalancedName = "irqbalance" | ||
| ) | ||
|
|
||
| // HighPerformanceHooks used to run additional hooks that will configure a system for the latency sensitive workloads | ||
| type HighPerformanceHooks struct{} | ||
| type HighPerformanceHooks struct { | ||
| irqBalanceConfigFile string | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why have this file as a member of the Hooks, when the other file locations are hardcoded?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @haircommander This file location is platform dependent. For example, in Ubuntu, the config file is /etc/default/irqbalance. Hence making it to configure from a RuntimeConfig property. Can you check it now ? |
||
| } | ||
|
|
||
| func (h *HighPerformanceHooks) PreStart(ctx context.Context, c *oci.Container, s *sandbox.Sandbox) error { | ||
| log.Infof(ctx, "Run %q runtime handler pre-start hook for the container %q", HighPerformance, c.ID()) | ||
|
|
@@ -66,7 +73,7 @@ func (h *HighPerformanceHooks) PreStart(ctx context.Context, c *oci.Container, s | |
| // disable the IRQ smp load balancing for the container CPUs | ||
| if shouldIRQLoadBalancingBeDisabled(s.Annotations()) { | ||
| log.Infof(ctx, "Disable irq smp balancing for container %q", c.ID()) | ||
| if err := setIRQLoadBalancing(c, false, irqSmpAffinityProcFile); err != nil { | ||
| if err := setIRQLoadBalancing(c, false, IrqSmpAffinityProcFile, h.irqBalanceConfigFile); err != nil { | ||
| return errors.Wrap(err, "set IRQ load balancing") | ||
| } | ||
| } | ||
|
|
@@ -111,7 +118,7 @@ func (h *HighPerformanceHooks) PreStop(ctx context.Context, c *oci.Container, s | |
|
|
||
| // enable the IRQ smp balancing for the container CPUs | ||
| if shouldIRQLoadBalancingBeDisabled(s.Annotations()) { | ||
| if err := setIRQLoadBalancing(c, true, irqSmpAffinityProcFile); err != nil { | ||
| if err := setIRQLoadBalancing(c, true, IrqSmpAffinityProcFile, h.irqBalanceConfigFile); err != nil { | ||
| return errors.Wrap(err, "set IRQ load balancing") | ||
| } | ||
| } | ||
|
|
@@ -219,7 +226,7 @@ func setCPUSLoadBalancing(c *oci.Container, enable bool, schedDomainDir string) | |
| return nil | ||
| } | ||
|
|
||
| func setIRQLoadBalancing(c *oci.Container, enable bool, irqSmpAffinityFile string) error { | ||
| func setIRQLoadBalancing(c *oci.Container, enable bool, irqSmpAffinityFile, irqBalanceConfigFile string) error { | ||
| lspec := c.Spec().Linux | ||
| if lspec == nil || | ||
| lspec.Resources == nil || | ||
|
|
@@ -240,16 +247,32 @@ func setIRQLoadBalancing(c *oci.Container, enable bool, irqSmpAffinityFile strin | |
| if err := ioutil.WriteFile(irqSmpAffinityFile, []byte(newIRQSMPSetting), 0o644); err != nil { | ||
| return err | ||
| } | ||
| if _, err := exec.LookPath("irqbalance"); err != nil { | ||
| // irqbalance is not installed, skip the rest; pod should still start, so return nil instead | ||
| logrus.Warnf("irqbalance binary not found: %v", err) | ||
| return nil | ||
|
|
||
| isIrqConfigExists := fileExists(irqBalanceConfigFile) | ||
|
|
||
| if isIrqConfigExists { | ||
| if err := updateIrqBalanceConfigFile(irqBalanceConfigFile, newIRQBalanceSetting); err != nil { | ||
| return err | ||
| } | ||
| } | ||
|
|
||
| if !isServiceEnabled(irqBalancedName) || !isIrqConfigExists { | ||
| if _, err := exec.LookPath(irqBalancedName); err != nil { | ||
| // irqbalance is not installed, skip the rest; pod should still start, so return nil instead | ||
| logrus.Warnf("irqbalance binary not found: %v", err) | ||
| return nil | ||
| } | ||
| // run irqbalance in daemon mode, so this won't cause delay | ||
| cmd := exec.Command(irqBalancedName, "--oneshot") | ||
| additionalEnv := irqBalanceBannedCpus + "=" + newIRQBalanceSetting | ||
| cmd.Env = append(os.Environ(), additionalEnv) | ||
| return cmd.Run() | ||
| } | ||
|
|
||
| if err := restartIrqBalanceService(); err != nil { | ||
| logrus.Warnf("irqbalance service restart failed: %v", err) | ||
| } | ||
| // run irqbalance in daemon mode, so this won't cause delay | ||
| cmd := exec.Command("irqbalance", "--oneshot") | ||
| additionalEnv := "IRQBALANCE_BANNED_CPUS=" + newIRQBalanceSetting | ||
| cmd.Env = append(os.Environ(), additionalEnv) | ||
| return cmd.Run() | ||
| return nil | ||
| } | ||
|
|
||
| func setCPUQuota(cpuMountPoint, parentDir string, c *oci.Container, enable bool) error { | ||
|
|
@@ -311,3 +334,59 @@ func setCPUQuota(cpuMountPoint, parentDir string, c *oci.Container, enable bool) | |
|
|
||
| return nil | ||
| } | ||
|
|
||
| // RestoreIrqBalanceConfig restores irqbalance service with original banned cpu mask settings | ||
| func RestoreIrqBalanceConfig(irqBalanceConfigFile, irqBannedCPUConfigFile, irqSmpAffinityProcFile string) error { | ||
| content, err := ioutil.ReadFile(irqSmpAffinityProcFile) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| current := strings.TrimSpace(string(content)) | ||
| // remove ","; now each element is "0-9,a-f" | ||
| s := strings.ReplaceAll(current, ",", "") | ||
| currentMaskArray, err := mapHexCharToByte(s) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| if !isAllBitSet(currentMaskArray) { | ||
| // not system reboot scenario, just return it. | ||
| return nil | ||
| } | ||
|
|
||
| bannedCPUMasks, err := retrieveIrqBannedCPUMasks(irqBalanceConfigFile) | ||
| if err != nil { | ||
| // Ignore returning err as given irqBalanceConfigFile may not exist. | ||
| return nil | ||
| } | ||
| if !fileExists(irqBannedCPUConfigFile) { | ||
| irqBannedCPUsConfig, err := os.Create(irqBannedCPUConfigFile) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| defer irqBannedCPUsConfig.Close() | ||
| _, err = irqBannedCPUsConfig.WriteString(bannedCPUMasks) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| content, err = ioutil.ReadFile(irqBannedCPUConfigFile) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| origBannedCPUMasks := strings.TrimSpace(string(content)) | ||
|
|
||
| if bannedCPUMasks == origBannedCPUMasks { | ||
| return nil | ||
| } | ||
| if err := updateIrqBalanceConfigFile(irqBalanceConfigFile, origBannedCPUMasks); err != nil { | ||
| return err | ||
| } | ||
| if isServiceEnabled(irqBalancedName) { | ||
| if err := restartIrqBalanceService(); err != nil { | ||
| logrus.Warnf("irqbalance service restart failed: %v", err) | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a blurb about where this file should be for which distro (only for the most popular: ubuntu/centos, maybe debian/rhel if they differ at all)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! done, I was able to confirm the file locations only in centos/suse and ubuntu platforms. so added it only for those cases.