Files
2023-12-29 11:30:15 +08:00

288 lines
11 KiB
Python

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#############################################################################
# Copyright (c) 2023 Huawei Technologies Co.,Ltd.
#
# openGauss is licensed under Mulan PSL v2.
# You can use this software according to the terms
# and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
# ----------------------------------------------------------------------------
# Description : perf_probe.py setup a information set for configure
#############################################################################
import math
from base_utils.os.cpu_util import CpuArchitecture, CpuUtil
from base_utils.os.disk_util import DiskUtil
from impl.perf_config.basic.project import Project
from impl.perf_config.basic.anti import AntiLog
from impl.perf_config.basic.tuner import Tuner, TunerGroup, ShellTunePoint
from impl.perf_config.probes.business import BsScenario
################################################
# BIOS
# - BiosTuner
################################################
class BiosTuner(TunerGroup):
def __init__(self):
super(BiosTuner, self).__init__()
def calculate(self):
infos = Project.getGlobalPerfProbe()
if infos.os.bios.support_smmu == 'Enable':
sug = 'modify BIOS->Advances->MISC Config->Support Smmu to Disable.'
Project.report.suggest(sug)
Project.log('SUGGESTION: ' + sug)
if infos.os.bios.cpu_prefetching == 'Enable':
sug = 'modify BIOS->Advances->MISC Config->CPU Prefetching Configuration to Disable.'
Project.report.suggest(sug)
Project.log('SUGGESTION: ' + sug)
if infos.os.bios.die_interleaving == 'Enable':
sug = 'modify BIOS->Advances->MISC Config->Die Interleaving to Disable.'
Project.report.suggest(sug)
Project.log('SUGGESTION: ' + sug)
################################################
# CPU
# - CPUTuner
################################################
class CPUTuner(TunerGroup):
def __init__(self):
super(CPUTuner, self).__init__()
@staticmethod
def calculate_numa_bind():
infos = Project.getGlobalPerfProbe()
session_per_core = infos.business.parallel / infos.cpu.count()
numa_bind = (infos.cpu.architecture() == CpuArchitecture.AARCH64 and
infos.cpu.count() >= 32 and
BsScenario.isOLTPScenario(infos.business.scenario) and
session_per_core > 1)
numa_bind_info = {'use': False, 'threadpool': [], 'network': '', 'walwriter': '', 'suggestions': []}
if numa_bind:
numa_bind_info['use'] = True
ratio_for_net = 0.1 # cpu num for irq-bind / all cpu, 0.1 is ref tpcc 2P 4P.
threadpool = []
network = []
for cpu_list in infos.cpu.numa():
cpu_count = len(cpu_list)
count_for_net = max(math.floor(cpu_count * ratio_for_net), 1)
threadpool += cpu_list[:cpu_count - count_for_net]
network += cpu_list[cpu_count - count_for_net:]
walwriter = [0]
numactl_param = CpuUtil.cpuListToCpuRangeStr(threadpool)
threadpool.remove(0)
numa_bind_info['walwriter'] = CpuUtil.cpuListToCpuRangeStr(walwriter)
numa_bind_info['threadpool'] = threadpool
numa_bind_info['network'] = CpuUtil.cpuListToCpuRangeStr(network)
suggestion = "If you use numactl for startup, you are advised to add param '-C {0}'{1}.".format(
numactl_param,
'' if infos.cpu.count() < 256 or len(infos.cpu.numa()) < 4 else "and '--preferred=0'."
)
numa_bind_info['suggestions'].append(suggestion)
return numa_bind_info
def calculate(self):
infos = Project.getGlobalPerfProbe()
numa_bind_info = self.calculate_numa_bind()
infos.cpu.notebook.write('numa_bind_info', numa_bind_info)
def explain(self, apply=False):
# tune threadpool in dbtuner and network in nerwork tuner
pass
################################################
# MEMORY
# - MemoryTuner
# - MemHugePageTuner
###############################################
class MemHugePageTuner(TunerGroup):
def __init__(self):
super(MemHugePageTuner, self).__init__()
def calculate(self):
infos = Project.getGlobalPerfProbe()
if infos.memory.hugepage is None:
return
self._disable_huge_mem(infos)
def _disable_huge_mem(self, infos):
tune_enabled = (infos.memory.hugepage['enabled'] != 'never')
if tune_enabled:
cmd = "echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled"
anti = "echo '{}' > /sys/kernel/mm/transparent_hugepage/enabled".format(
infos.memory.hugepage['enabled'])
desc = 'Tune hugepage enabled to never, old value is {}'.format(infos.memory.hugepage['enabled'])
self.add(ShellTunePoint(cmd, anti, desc))
tune_defrag = (infos.memory.hugepage['defrag'] != 'never')
if tune_defrag:
cmd = "echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag"
anti = "echo '{}' > /sys/kernel/mm/transparent_hugepage/defrag".format(
infos.memory.hugepage['enabled'])
desc = 'Tune hugepage defrag to never, old value is {}'.format(infos.memory.hugepage['enabled'])
self.add(ShellTunePoint(cmd, anti, desc))
class MemoryTuner(TunerGroup):
def __init__(self):
super(MemoryTuner, self).__init__()
self.hugepage = self.add(MemHugePageTuner())
################################################
# DISK
# - DiskTuner
###############################################
class DiskTuner(TunerGroup):
def __init__(self):
super(DiskTuner, self).__init__()
def calculate(self):
infos = Project.getGlobalPerfProbe()
gausshome_disk = DiskUtil.getMountPathByDataDir(infos.db.gauss_data)
device = infos.disk.get(gausshome_disk)
if device.fstype != 'xfs':
sug = "Disk {0} is {1} format, you are advised to set the disk format to xfs ".format(
device.device, device.fstype
)
Project.report.suggest(sug)
Project.log('SUGGESTION: ' + sug)
################################################
# DISK
# - NetworkTuner
# - NetworkIRQTuner
# - EthtoolTuner
# - NetConfigTuner
###############################################
class NetworkIRQTuner(TunerGroup):
def __init__(self):
super(NetworkIRQTuner, self).__init__()
self.script = Project.environ.get_builtin_script('irq_operate.sh')
def calculate(self):
infos = Project.getGlobalPerfProbe()
numa_bind_info = infos.cpu.notebook.read('numa_bind_info')
if numa_bind_info is None or not numa_bind_info.get('use'):
return
for ip in infos.db.ip:
if ip == '*':
continue
gate = infos.network.get_gate(ip)
if gate is None or gate.is_localhost() or gate.is_virbr() or gate.irq_binds is None:
continue
bind_list = CpuUtil.cpuRangeStrToCpuList(numa_bind_info.get('network'))
roll_list = gate.irq_binds
cmd = 'sh {0} bind {1} "{2}"'.format(self.script, gate.name, ' '.join([str(cpuid) for cpuid in bind_list]))
anti = 'sh {0} bind {1} "{2}"'.format(self.script, gate.name, ' '.join([str(cpuid) for cpuid in roll_list]))
desc = 'bind irq'
self.add(ShellTunePoint(cmd, anti, desc))
class OffloadingTuner(TunerGroup):
def __init__(self):
super(OffloadingTuner, self).__init__()
def calculate(self):
infos = Project.getGlobalPerfProbe()
for ip in infos.db.ip:
if ip == '*':
continue
gate = infos.network.get_gate(ip)
if gate is None or gate.is_localhost() or gate.is_virbr():
continue
tune_tso = (gate.tso == 'off')
if tune_tso:
cmd = 'ethtool -K {} tso on'.format(gate.name)
anti = 'ethtool -K {} tso off'.format(gate.name)
desc = 'open offloading tso'
self.add(ShellTunePoint(cmd, anti, desc))
tune_lro = (gate.lro == 'off')
if tune_lro:
cmd = 'ethtool -K {} lro on'.format(gate.name)
anti = 'ethtool -K {} lro off'.format(gate.name)
desc = 'open offloading lro'
self.add(ShellTunePoint(cmd, anti, desc))
class NetConfigTuner(TunerGroup):
def __init__(self):
super(NetConfigTuner, self).__init__()
def calculate(self):
pass
class NetworkTuner(TunerGroup):
def __init__(self):
super(NetworkTuner, self).__init__()
self.network_irq = self.add(NetworkIRQTuner())
self.offloading = self.add(OffloadingTuner())
self.net_config = self.add(NetConfigTuner())
################################################
# OS CONFIGURE AND SERVICE
# - OSServiceTuner
################################################
class OSServiceTuner(TunerGroup):
def __init__(self):
super(OSServiceTuner, self).__init__()
def calculate(self):
infos = Project.getGlobalPerfProbe()
if infos.os.service.sysmonitor is not None and infos.os.service.sysmonitor:
cmd = "service sysmonitor stop"
anti = "service sysmonitor start"
desc = "stop sysmonitor"
self.add(ShellTunePoint(cmd, anti, desc))
if infos.os.service.irqbalance is not None and infos.os.service.irqbalance:
cmd = "service irqbalance stop"
anti = "service irqbalance start"
desc = "stop irqbalance"
self.add(ShellTunePoint(cmd, anti, desc))
################################################
# OS TUNER
# - OSTuner
# - BiosTuner
# - CPUTuner
# - MemoryTuner
# - DiskTuner
# - NetworkTuner
# - OSServiceTuner
###############################################
class OSTuner(TunerGroup):
def __init__(self):
super(OSTuner, self).__init__()
self.bios = self.add(BiosTuner())
self.cpu = self.add(CPUTuner())
self.memory = self.add(MemoryTuner())
self.disk = self.add(DiskTuner())
self.network = self.add(NetworkTuner())
self.service = self.add(OSServiceTuner())