3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 from cmdatahandlers.api import configerror
16 from cmdatahandlers.api import config
17 from cmdatahandlers.api import utils
20 class Config(config.Config):
22 DEFAULT_HUGEPAGESZ = 'default_hugepagesz'
23 HUGEPAGESZ = 'hugepagesz'
24 HUGEPAGES = 'hugepages'
25 PLATFORM_CPUS = 'platform_cpus'
26 OVS_DPDK_CPUS = 'ovs_dpdk_cpus'
28 LOW_LATENCY_OPTIONS = 'low_latency_options'
29 PROFILE_OPTIONS = {DEFAULT_HUGEPAGESZ: 'get_profile_default_hugepage_size',
30 HUGEPAGESZ: 'get_profile_hugepage_size',
31 HUGEPAGES: 'get_profile_hugepage_count',
32 PLATFORM_CPUS: 'get_platform_cpus',
33 OVS_DPDK_CPUS: 'get_ovs_dpdk_cpus',
35 LOW_LATENCY_OPTIONS: 'get_low_latency_kcmd_options'}
37 ERR_INVALID_PROFILE = 'Invalid profile name {}'
38 ERR_MISSING_PROFILE_KEY = 'Profile {} does not have %s'
39 ERR_MISSING_DEFAULT_HUGEPAGESZ = ERR_MISSING_PROFILE_KEY % DEFAULT_HUGEPAGESZ
40 ERR_MISSING_HUGEPAGESZ = ERR_MISSING_PROFILE_KEY % HUGEPAGESZ
41 ERR_MISSING_HUGEPAGES = ERR_MISSING_PROFILE_KEY % HUGEPAGES
42 ERR_MISSING_PLATFORM_CPUS = ERR_MISSING_PROFILE_KEY % PLATFORM_CPUS
43 ERR_MISSING_OVS_DPDK_CPUS = ERR_MISSING_PROFILE_KEY % OVS_DPDK_CPUS
44 ERR_MISSING_TUNING = ERR_MISSING_PROFILE_KEY % TUNING
45 ERR_INVALID_PROFILE_KEY = 'Profile {} got invalid option %s'
46 ERR_INVALID_LOW_LATENCY_OPTIONS = ERR_INVALID_PROFILE_KEY % LOW_LATENCY_OPTIONS
49 def raise_error(context, err_type):
50 raise configerror.ConfigError(err_type.format(context))
52 def __init__(self, confman):
53 super(Config, self).__init__(confman)
54 self.ROOT = 'cloud.performance_profiles'
55 self.DOMAIN = 'performance_profiles'
62 self._validate_performance_profiles()
64 def _validate_performance_profiles(self):
65 profiles = self.get_performance_profiles()
66 utils.validate_list_items_unique(profiles)
67 for profile in profiles:
68 self._validate_performance_profile(profile)
70 def _validate_performance_profile(self, profile):
71 self.get_profile_default_hugepage_size(profile)
72 self.get_profile_hugepage_size(profile)
73 self.get_profile_hugepage_count(profile)
74 self.get_platform_cpus(profile)
75 self.get_ovs_dpdk_cpus(profile)
76 self._validate_mandatory_option(profile, self.TUNING)
78 def _validate_mandatory_option(self, profile, option):
79 if getattr(self, self.PROFILE_OPTIONS[option])(profile) is None:
80 self.raise_error(profile, self.ERR_MISSING_PROFILE_KEY % option)
82 def is_valid_profile(self, profile):
83 profiles = self.get_performance_profiles()
84 if profile not in profiles:
85 self.raise_error(profile, self.ERR_INVALID_PROFILE)
87 def get_performance_profiles(self):
88 """ get the performance profiles list
92 A list of performance profile(s) names
96 ConfigError in-case of an error
99 return self.config[self.ROOT].keys()
101 # pylint: disable=invalid-name
102 def get_profile_default_hugepage_size(self, profile):
103 """ get the default hugepage size
111 The default hugepage size
115 ConfigError in-case of an error
117 self.is_valid_profile(profile)
119 if self.DEFAULT_HUGEPAGESZ not in self.config[self.ROOT][profile]:
120 self.raise_error(profile, self.ERR_MISSING_DEFAULT_HUGEPAGESZ)
122 return self.config[self.ROOT][profile][self.DEFAULT_HUGEPAGESZ]
124 def get_profile_hugepage_size(self, profile):
125 """ get the hugepage size
137 ConfigError in-case of an error
139 self.is_valid_profile(profile)
141 if self.HUGEPAGESZ not in self.config[self.ROOT][profile]:
142 self.raise_error(profile, self.ERR_MISSING_HUGEPAGESZ)
144 return self.config[self.ROOT][profile][self.HUGEPAGESZ]
146 def get_profile_hugepage_count(self, profile):
147 """ get the hugepage count
159 ConfigError in-case of an error
161 self.is_valid_profile(profile)
163 if self.HUGEPAGES not in self.config[self.ROOT][profile]:
164 self.raise_error(profile, self.ERR_MISSING_HUGEPAGES)
166 return self.config[self.ROOT][profile][self.HUGEPAGES]
168 def get_platform_cpus(self, profile):
169 """ get the Platforma CPUs (isolate CPUs from the general scheduler).
177 The platform CPUs dictionary
181 ConfigError in-case of an error
183 self.is_valid_profile(profile)
185 if self.PLATFORM_CPUS not in self.config[self.ROOT][profile]:
186 self.raise_error(profile, self.ERR_MISSING_PLATFORM_CPUS)
188 return self.config[self.ROOT][profile][self.PLATFORM_CPUS]
190 def get_ovs_dpdk_cpus(self, profile):
191 """ get the ovs-dpdk cpu(s)
199 The ovs-dpdk dedicated cpu(s) string
203 ConfigError in-case of an error
205 self.is_valid_profile(profile)
207 if self.OVS_DPDK_CPUS not in self.config[self.ROOT][profile]:
208 self.raise_error(profile, self.ERR_MISSING_OVS_DPDK_CPUS)
210 return self.config[self.ROOT][profile][self.OVS_DPDK_CPUS]
212 def get_tuning(self, profile):
213 """ get performance tuning option
218 Performance profile name.
222 Performance tuning option.
228 self.is_valid_profile(profile)
229 if self.TUNING not in self.config[self.ROOT][profile]:
232 return self.config[self.ROOT][profile][self.TUNING]
234 def get_low_latency_kcmd_options(self, profile):
235 """ get low latency kernel cmd option
240 Performance profile name.
244 Low latency kernel cmd options.
250 self.is_valid_profile(profile)
251 if self.LOW_LATENCY_OPTIONS not in self.config[self.ROOT][profile]:
254 return self.config[self.ROOT][profile][self.LOW_LATENCY_OPTIONS]
256 def set_low_latency_kcmd_options(self, profile, options):
257 """ set low latency kernel cmd option
262 Performance profile name.
266 Low latency kernel cmd options.
272 self.is_valid_profile(profile)
273 if not isinstance(options, list):
274 self.raise_error(profile, self.ERR_INVALID_LOW_LATENCY_OPTIONS)
276 self._fill_option_value(self.config[self.ROOT][profile], profile, self.LOW_LATENCY_OPTIONS, options)
279 """ Dump all performaceprofiles data. """
282 return self.config[self.ROOT]
284 def _fill_option_value(self, profile_data, profile, option, value):
287 value = getattr(self, self.PROFILE_OPTIONS[option])(profile)
288 except configerror.ConfigError:
290 profile_data.update({option:value})
292 # pylint: disable=too-many-arguments
293 def update(self, name, platform_cpus=None, ovs_dpdk_cpus=None, hugepages=None,
294 default_hugepagesz=None, hugepagesz=None, tuning=None):
295 """ Update performance profile, overwriting existing profile.
301 platform_cpus : dict, optional
303 The syntax is: {'numa0': <int>, 'numa1': <int>, ..., 'numaN': <int>}
304 ovs_dpdk_cpus : dict, optional
305 OVS-DPDK dedicated cores.
306 The syntax is the same as platform_cpus.
307 hugepages : int, optional
308 The number of allocated persistent huge pages.
309 default_hugepagesz : str, optional
310 Default huge page size (the default value is '1G').
311 Valid values are '2M' and '1G'
312 hugepagesz : str, optional
313 Huge page size (the default value is '1G').
314 Valid values are '2M' and '1G'
315 tuning : str, optional
316 Performance tuning option.
317 Valid values are 'low_latency and 'standard' (default).
320 self._fill_option_value(data, name, 'platform_cpus', platform_cpus)
321 self._fill_option_value(data, name, 'ovs_dpdk_cpus', ovs_dpdk_cpus)
322 self._fill_option_value(data, name, 'hugepages', hugepages)
323 self._fill_option_value(data, name, 'default_hugepagesz', default_hugepagesz)
324 self._fill_option_value(data, name, 'hugepagesz', hugepagesz)
325 self._fill_option_value(data, name, 'tuning', tuning)
326 self.config[self.ROOT].update({name:data})
328 def delete(self, name):
338 Raises ConfigError if profile does not exist.
341 self.config[self.ROOT].pop(name)
343 self.raise_error(name, self.ERR_INVALID_PROFILE)