def configure(self): """ Configure Pool, based on config content. """ config = common.CONFIG_STORE cores = config.get_pool_attr('cores', self.pool) self.cores_set(cores) if caps.cat_l3_supported(): cbm = config.get_pool_attr('cbm', self.pool) self.cbm_set(cbm) if caps.mba_supported(): if caps.mba_bw_enabled(): self.mba_bw_set(config.get_pool_attr('mba_bw', self.pool)) else: self.mba_set(config.get_pool_attr('mba', self.pool)) apps = config.get_pool_attr('apps', self.pool) if apps is not None: pids = [] for app in apps: app_pids = config.get_app_attr('pids', app) if app_pids: pids.extend(app_pids) self.pids_set(pids) return Pool.apply(self.pool)
def __init__(self): self.process = None self.app = Flask(__name__) self.app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 self.api = Api(self.app) # initialize SSL context self.context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) self.context.verify_mode = ssl.CERT_REQUIRED self.context.set_ciphers(':'.join(TLS_CIPHERS)) # allow TLS 1.2 and later self.context.options |= ssl.OP_NO_SSLv2 self.context.options |= ssl.OP_NO_SSLv3 self.context.options |= ssl.OP_NO_TLSv1 self.context.options |= ssl.OP_NO_TLSv1_1 self.api.add_resource(Apps, '/apps') self.api.add_resource(App, '/apps/<int:app_id>') self.api.add_resource(Pools, '/pools') self.api.add_resource(Pool, '/pools/<int:pool_id>') if caps.sstcp_enabled(): self.api.add_resource(Powers, '/power_profiles') self.api.add_resource(Power, '/power_profiles/<int:profile_id>') self.api.add_resource(Stats, '/stats') self.api.add_resource(Caps, '/caps') if caps.sstbf_enabled(): self.api.add_resource(Sstbf, '/caps/sstbf') self.api.add_resource(CapsRdtIface, '/caps/rdt_iface') if caps.mba_supported(): self.api.add_resource(CapsMba, '/caps/mba') self.api.add_resource(CapsMbaCtrl, '/caps/mba_ctrl') self.api.add_resource(Reset, '/reset') self.app.register_error_handler(HTTPException, Server.error_handler)
def __init__(self): self.process = None self.app = Flask(__name__) self.app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 self.api = Api(self.app) # initialize SSL context self.context = ssl.SSLContext(ssl.PROTOCOL_TLS) # allow TLS 1.2 and later self.context.options |= ssl.OP_NO_SSLv2 self.context.options |= ssl.OP_NO_SSLv3 self.context.options |= ssl.OP_NO_TLSv1 self.context.options |= ssl.OP_NO_TLSv1_1 self.api.add_resource(Apps, '/apps') self.api.add_resource(App, '/apps/<int:app_id>') self.api.add_resource(Pools, '/pools') self.api.add_resource(Pool, '/pools/<int:pool_id>') if caps.sstcp_enabled(): self.api.add_resource(Powers, '/power_profiles') self.api.add_resource(Power, '/power_profiles/<int:profile_id>') self.api.add_resource(Stats, '/stats') self.api.add_resource(Caps, '/caps') if caps.sstbf_enabled(): self.api.add_resource(Sstbf, '/caps/sstbf') self.api.add_resource(CapsRdtIface, '/caps/rdt_iface') if caps.mba_supported(): self.api.add_resource(CapsMba, '/caps/mba') self.api.add_resource(CapsMbaCtrl, '/caps/mba_ctrl') self.api.add_resource(Reset, '/reset') self.app.register_error_handler(HTTPException, Server.error_handler)
def add_default_pool(data): """ Update config with "Default" pool """ # no Default pool configured default_pool = {} default_pool['id'] = 0 if caps.mba_supported(): if caps.mba_bw_enabled(): default_pool['mba_bw'] = 2**32 - 1 else: default_pool['mba'] = 100 if caps.cat_l3_supported(): default_pool['cbm'] = common.PQOS_API.get_max_l3_cat_cbm() default_pool['name'] = "Default" # Use all unallocated cores default_pool['cores'] = common.PQOS_API.get_cores() for pool in data['pools']: default_pool['cores'] = \ [core for core in default_pool['cores'] if core not in pool['cores']] data['pools'].append(default_pool)
def _validate_rdt(data): """ Validate RDT configuration (including MBA CTRL) configuration Parameters data: configuration (dict) """ # if data to be validated does not contain RDT iface and/or MBA CTRL info # get missing info from current configuration rdt_iface = data['rdt_iface']['interface'] if 'rdt_iface' in data\ else common.CONFIG_STORE.get_rdt_iface() mba_ctrl_enabled = data['mba_ctrl']['enabled'] if 'mba_ctrl' in data\ else common.CONFIG_STORE.get_mba_ctrl_enabled() if mba_ctrl_enabled and rdt_iface != "os": raise ValueError( "RDT Configuration. MBA CTRL requires RDT OS interface!") if mba_ctrl_enabled and not caps.mba_bw_supported(): raise ValueError( "RDT Configuration. MBA CTRL requested but not supported!") if not 'pools' in data: return mba_pool_ids = [] mba_bw_pool_ids = [] for pool in data['pools']: if 'cbm' in pool: result = re.search('1{1,32}0{1,32}1{1,32}', bin(pool['cbm'])) if result or pool['cbm'] == 0: raise ValueError("Pool {}, CBM {}/{} is not contiguous."\ .format(pool['id'], hex(pool['cbm']), bin(pool['cbm']))) if not caps.cat_supported(): raise ValueError("Pool {}, CBM {}/{}, CAT is not supported."\ .format(pool['id'], hex(pool['cbm']), bin(pool['cbm']))) if 'mba' in pool: mba_pool_ids.append(pool['id']) if 'mba_bw' in pool: mba_bw_pool_ids.append(pool['id']) if (mba_pool_ids or mba_bw_pool_ids) and not caps.mba_supported(): raise ValueError("Pools {}, MBA is not supported."\ .format(mba_pool_ids + mba_bw_pool_ids)) if mba_bw_pool_ids and not mba_ctrl_enabled: raise ValueError("Pools {}, MBA BW is not enabled/supported."\ .format(mba_bw_pool_ids)) if mba_pool_ids and mba_ctrl_enabled: raise ValueError("Pools {}, MBA % is not enabled. Disable MBA BW and try again."\ .format(mba_pool_ids)) return
def _validate_pools(data): """ Validate Pools configuration Parameters data: configuration (dict) """ if not 'pools' in data: return # verify pools cores = set() pool_ids = [] for pool in data['pools']: # id if pool['id'] in pool_ids: raise ValueError( "Pool {}, multiple pools with same id.".format(pool['id'])) pool_ids.append(pool['id']) # pool cores for core in pool['cores']: if not common.PQOS_API.check_core(core): raise ValueError("Pool {}, Invalid core {}.".format( pool['id'], core)) if cores.intersection(pool['cores']): raise ValueError("Pool {}, Cores {} already assigned to another pool."\ .format(pool['id'], cores.intersection(pool['cores']))) cores |= set(pool['cores']) # check app reference if 'apps' in pool: for app_id in pool['apps']: ConfigStore.get_app(data, app_id) if 'cbm' in pool: result = re.search('1{1,32}0{1,32}1{1,32}', bin(pool['cbm'])) if result or pool['cbm'] == 0: raise ValueError("Pool {}, CBM {}/{} is not contiguous."\ .format(pool['id'], hex(pool['cbm']), bin(pool['cbm']))) if not caps.cat_supported(): raise ValueError("Pool {}, CBM {}/{}, CAT is not supported."\ .format(pool['id'], hex(pool['cbm']), bin(pool['cbm']))) if 'mba' in pool: if pool['mba'] > 100 or pool['mba'] <= 0: raise ValueError("Pool {}, MBA rate {} out of range! (1-100)."\ .format(pool['id'], pool['mba'])) if not caps.mba_supported(): raise ValueError("Pool {}, MBA rate {}, MBA is not supported."\ .format(pool['id'], pool['mba'])) # check power profile reference if 'power_profile' in pool: ConfigStore.get_power(data, pool['power_profile'])
def __init__(self): self.process = None self.app = Flask(__name__) self.app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 self.app.url_map.strict_slashes = False self.api = Api(self.app) # initialize SSL context self.context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) self.context.verify_mode = ssl.CERT_REQUIRED self.context.set_ciphers(':'.join(TLS_CIPHERS)) # allow TLS 1.2 and later self.context.options |= ssl.OP_NO_SSLv2 self.context.options |= ssl.OP_NO_SSLv3 self.context.options |= ssl.OP_NO_TLSv1 self.context.options |= ssl.OP_NO_TLSv1_1 # Apps and Pools API self.api.add_resource(Apps, '/apps') self.api.add_resource(App, '/apps/<int:app_id>') self.api.add_resource(Pools, '/pools') self.api.add_resource(Pool, '/pools/<int:pool_id>') # SST-CP API if caps.sstcp_enabled(): self.api.add_resource(Powers, '/power_profiles') self.api.add_resource(Power, '/power_profiles/<int:profile_id>') # Stats and Capabilities API self.api.add_resource(Stats, '/stats') self.api.add_resource(Caps, '/caps') # SST-BF API if caps.sstbf_enabled(): self.api.add_resource(Sstbf, '/caps/sstbf') # RDT interface API self.api.add_resource(CapsRdtIface, '/caps/rdt_iface') # MBA API if caps.mba_supported(): self.api.add_resource(CapsMba, '/caps/mba') self.api.add_resource(CapsMbaCtrl, '/caps/mba_ctrl') # L3 CAT API if caps.cat_l3_supported(): self.api.add_resource(CapsL3ca, '/caps/' + common.CAT_L3_CAP) # L2 CAT API if caps.cat_l2_supported(): self.api.add_resource(CapsL2ca, '/caps/' + common.CAT_L2_CAP) # Reset API self.api.add_resource(Reset, '/reset') self.app.register_error_handler(HTTPException, Server.error_handler)
def check_alloc_tech(pool_id, json_data): if 'cbm' in json_data: if not caps.cat_supported(): raise BadRequest("System does not support CAT!") if pool_id > common.PQOS_API.get_max_cos_id([common.CAT_CAP]): raise BadRequest("Pool {} does not support CAT".format(pool_id)) if 'mba' in json_data: if not caps.mba_supported(): raise BadRequest("System does not support MBA!") if pool_id > common.PQOS_API.get_max_cos_id([common.MBA_CAP]): raise BadRequest("Pool {} does not support MBA".format(pool_id))
def _validate_rdt(data): """ Validate RDT configuration (including MBA CTRL) configuration Parameters data: configuration (dict) """ if 'mba_ctrl' in data and data['mba_ctrl']['enabled']\ and (not 'rdt_iface' in data or data['rdt_iface']['interface'] != "os"): raise ValueError( "RDT Configuration. MBA CTRL requires RDT OS interface!") if not 'pools' in data: return mba_pool_ids = [] mba_bw_pool_ids = [] for pool in data['pools']: if 'cbm' in pool: result = re.search('1{1,32}0{1,32}1{1,32}', bin(pool['cbm'])) if result or pool['cbm'] == 0: raise ValueError("Pool {}, CBM {}/{} is not contiguous."\ .format(pool['id'], hex(pool['cbm']), bin(pool['cbm']))) if not caps.cat_supported(): raise ValueError("Pool {}, CBM {}/{}, CAT is not supported."\ .format(pool['id'], hex(pool['cbm']), bin(pool['cbm']))) if 'mba' in pool: mba_pool_ids.append(pool['id']) if 'mba_bw' in pool: mba_bw_pool_ids.append(pool['id']) if mba_bw_pool_ids and mba_pool_ids: raise ValueError("It is not allowed to mix MBA (Pools: {}) "\ "and MBA BW (Pools {}), configurations."\ .format(mba_pool_ids, mba_bw_pool_ids)) if (mba_pool_ids or mba_bw_pool_ids) and not caps.mba_supported(): raise ValueError("Pools {}, MBA is not supported."\ .format(mba_pool_ids + mba_bw_pool_ids)) if mba_bw_pool_ids and not caps.mba_bw_enabled(): raise ValueError("Pools {}, MBA BW is not enabled/supported."\ .format(mba_bw_pool_ids)) return
def check_alloc_tech(pool_id, json_data): if 'cbm' in json_data: if not caps.cat_l3_supported(): raise BadRequest("System does not support CAT!") if pool_id > common.PQOS_API.get_max_cos_id([common.CAT_L3_CAP]): raise BadRequest("Pool {} does not support CAT".format(pool_id)) if 'mba' in json_data or 'mba_bw' in json_data: if not caps.mba_supported(): raise BadRequest("System does not support MBA!") if pool_id > common.PQOS_API.get_max_cos_id([common.MBA_CAP]): raise BadRequest("Pool {} does not support MBA".format(pool_id)) if 'mba_bw' in json_data and not caps.mba_bw_enabled(): raise BadRequest("MBA CTRL is not {}!"\ .format("enabled" if caps.mba_bw_supported() else "supported")) if 'mba' in json_data and caps.mba_bw_enabled(): raise BadRequest("MBA RATE is disabled! Disable MBA CTRL and try again.")
def add_default_pool(data): """ Update config with "Default" pool """ # no Default pool configured default_pool = {} default_pool['id'] = 0 if caps.mba_supported(): default_pool['mba'] = 100 if caps.cat_supported(): default_pool['cbm'] = common.PQOS_API.get_max_l3_cat_cbm() default_pool['name'] = "Default" default_pool['cores'] = list(range(common.PQOS_API.get_num_cores())) for pool in data['pools']: default_pool['cores'] = \ [core for core in default_pool['cores'] if core not in pool['cores']] data['pools'].append(default_pool)
def configure_rdt(): """ Configure RDT Returns: 0 on success """ result = 0 recreate_default = False # Change RDT interface if needed cfg_rdt_iface = common.CONFIG_STORE.get_rdt_iface() if cfg_rdt_iface != common.PQOS_API.current_iface(): if common.PQOS_API.init(cfg_rdt_iface): log.error("Failed to initialize RDT interface!") return -1 recreate_default = True log.info("RDT initialized with %s interface."\ % (common.CONFIG_STORE.get_rdt_iface().upper())) # Change MBA BW/CTRL state if needed if caps.mba_supported(): cfg_mba_ctrl_enabled = common.CONFIG_STORE.get_mba_ctrl_enabled() if cfg_mba_ctrl_enabled != common.PQOS_API.is_mba_bw_enabled(): if common.PQOS_API.enable_mba_bw(cfg_mba_ctrl_enabled): log.error("Failed to change MBA BW state!") return -1 recreate_default = True log.info("RDT MBA BW %sabled."\ % ("en" if common.PQOS_API.is_mba_bw_enabled() else "dis")) if recreate_default: # On interface or MBA BW state change it is needed to recreate Default Pool #0 common.CONFIG_STORE.recreate_default_pool() # detect removed pools old_pools = Pool.pools.copy() pool_ids = common.CONFIG_STORE.get_pool_attr('id', None) if old_pools: for pool_id in old_pools: if not pool_ids or pool_id not in pool_ids: log.debug("Pool {} removed...".format(pool_id)) Pool(pool_id).cores_set([]) # remove pool Pool.pools.pop(pool_id) if not pool_ids: log.error("No Pools to configure...") return -1 for pool_id in pool_ids: Pool(pool_id) # Configure Pools, Intel RDT (CAT, MBA) for pool_id in Pool.pools: result = Pool(pool_id).configure() if result != 0: return result # Configure Apps, core affinity result = Apps().configure() return result
def run(self): """ Runs main loop. """ # process/validate already loaded config file try: common.CONFIG_STORE.process_config() except Exception as ex: log.error("Invalid config file... ") log.error(ex) return log.debug("Cores controlled: {}".\ format(common.CONFIG_STORE.get_pool_attr('cores', None))) data = common.CONFIG_STORE.get_config() for pool in data['pools']: log.debug("Pool: {}/{} Cores: {}, Apps: {}".format(pool.get('name'),\ pool.get('id'), pool.get('cores'), pool.get('apps'))) # set initial SST-BF configuration if caps.sstbf_enabled(): result = sstbf.init_sstbf() if result != 0: log.error( "Failed to apply initial SST-BF configuration, terminating..." ) return log.info("SST-BF enabled, {}configured.".\ format("not " if not sstbf.is_sstbf_configured() else "")) log.info("SST-BF HP cores: {}".format(sstbf.get_hp_cores())) log.info("SST-BF STD cores: {}".format(sstbf.get_std_cores())) else: log.info("SST-BF not enabled") # set initial SST-CP configuration if SST-BF is not configured if caps.sstcp_enabled(): if sstbf.is_sstbf_configured(): log.info( "Power Profiles/SST-CP enabled, not configured, SST-BF is configured" ) else: log.info("Power Profiles/SST-CP enabled.") # set initial POWER configuration result = power.configure_power() if result != 0: log.error("Failed to apply initial Power Profiles configuration,"\ " terminating...") return else: log.info("Power Profiles/EPP not enabled") # set initial RDT configuration log.info("Configuring RDT") # Configure MBA CTRL if caps.mba_supported(): result = common.PQOS_API.enable_mba_bw( common.CONFIG_STORE.get_mba_ctrl_enabled()) if result != 0: log.error( "libpqos MBA CTRL initialization failed, Terminating...") return log.info("RDT MBA CTRL %sabled"\ % ("en" if common.PQOS_API.is_mba_bw_enabled() else "dis")) result = cache_ops.configure_rdt() if result != 0: log.error( "Failed to apply initial RDT configuration, terminating...") return # set CTRL+C sig handler signal.signal(signal.SIGINT, self.signal_handler) self.event_handler() log.info("Terminating...")