def put(): """ Handles HTTP PUT /caps/sstbf request. Raises BadRequest, InternalError Returns: response, status code """ json_data = request.get_json() # validate app schema try: schema, resolver = ConfigStore.load_json_schema('modify_sstbf.json') jsonschema.validate(json_data, schema, resolver=resolver) except (jsonschema.ValidationError, OverflowError) as error: raise BadRequest("Request validation failed - %s" % (str(error))) if not sstbf.configure_sstbf(json_data['configured']) == 0: raise InternalError("Failed to change SST-BF configured state.") # update power profile configuration power.configure_power() res = {'message': "SST-BF caps modified"} return res, 200
def event_handler(self): """ Handles config_changed event """ # rate limiting last_cfg_change_ts = 0 min_time_diff = 1 / common.RATE_LIMIT while not self.stop_event.is_set(): if common.CONFIG_STORE.is_config_changed(): time_diff = time.time() - last_cfg_change_ts if time_diff < min_time_diff: log.info("Rate Limiter, sleeping " \ + str(round((min_time_diff - time_diff) * 1000)) + "ms...") time.sleep(min_time_diff - time_diff) log.info("Configuration changed, processing new config...") result = cache_ops.configure_rdt() if result != 0: log.error("Failed to apply RDT configuration!") break if caps.sstcp_enabled() and not sstbf.is_sstbf_configured(): result = power.configure_power() if result != 0: log.error( "Failed to apply Power Profiles configuration!") break last_cfg_change_ts = time.time() log.info("New configuration processed")
def test_configure_power(self): pool_ids = [0, 1] profile_ids = [5, 6] pool_to_cores = {0: [2, 3], 1: [4, 5]} pool_to_profiles = {0: 5, 1: 6} profiles = { 5: { "min_freq": 1500, "max_freq": 2500, "epp": "performance", "id": 5 }, 6: { "min_freq": 1000, "max_freq": 1200, "epp": "power", "id": 6 } } def get_pool_attr(attr, pool_id): if attr == 'id': if pool_id is None: return pool_ids else: return None elif attr == 'cores': return pool_to_cores[pool_id] elif attr == 'power_profile': if pool_id is None: return profile_ids else: return pool_to_profiles[pool_id] return None def get_power_profile(id): return profiles[id] # ERROR POWER: No Pools configured... power.PREV_PROFILES.clear() with mock.patch('common.CONFIG_STORE.get_pool_attr', return_value=None) as mock_get_pool_attr,\ mock.patch('common.CONFIG_STORE.get_power_profile') as mock_get_power_profile,\ mock.patch('power.reset') as mock_reset,\ mock.patch('power._set_freqs_epp') as mock_set_freqs_epp: assert -1 == power.configure_power() mock_get_pool_attr.assert_called_once_with('id', None) mock_get_power_profile.assert_not_called() mock_reset.assert_not_called() mock_set_freqs_epp.assert_not_called() # ERROR POWER: Profile 5 does not exist! power.PREV_PROFILES.clear() with mock.patch('common.CONFIG_STORE.get_pool_attr', new=get_pool_attr),\ mock.patch('common.CONFIG_STORE.get_power_profile', return_value=None) as mock_get_power_profile,\ mock.patch('power.reset') as mock_reset,\ mock.patch('power._set_freqs_epp') as mock_set_freqs_epp: assert -1 == power.configure_power() mock_get_power_profile.assert_called_once_with(5) mock_reset.assert_not_called() mock_set_freqs_epp.assert_not_called() # All OK! power.PREV_PROFILES.clear() with mock.patch('common.CONFIG_STORE.get_pool_attr', new=get_pool_attr),\ mock.patch('common.CONFIG_STORE.get_power_profile', new=get_power_profile),\ mock.patch('power.reset') as mock_reset,\ mock.patch('power._set_freqs_epp') as mock_set_freqs_epp: assert 0 == power.configure_power() mock_reset.assert_not_called() mock_set_freqs_epp.assert_any_call(pool_to_cores[0], profiles[5]["min_freq"], profiles[5]["max_freq"], profiles[5]["epp"]) mock_set_freqs_epp.assert_any_call(pool_to_cores[1], profiles[6]["min_freq"], profiles[6]["max_freq"], profiles[6]["epp"]) # POWER: Skipping Pool 0, no cores assigned power.PREV_PROFILES.clear() pool_to_cores[0] = [] with mock.patch('common.CONFIG_STORE.get_pool_attr', new=get_pool_attr),\ mock.patch('common.CONFIG_STORE.get_power_profile', new=get_power_profile),\ mock.patch('power.reset') as mock_reset,\ mock.patch('power._set_freqs_epp') as mock_set_freqs_epp: assert 0 == power.configure_power() mock_reset.assert_not_called() mock_set_freqs_epp.assert_called_once_with(pool_to_cores[1], profiles[6]["min_freq"], profiles[6]["max_freq"], profiles[6]["epp"]) # POWER: Pool 1, no power profile assigned. Resetting to defaults. power.PREV_PROFILES.clear() pool_to_profiles[1] = None with mock.patch('common.CONFIG_STORE.get_pool_attr', new=get_pool_attr),\ mock.patch('common.CONFIG_STORE.get_power_profile', new=get_power_profile),\ mock.patch('power.reset') as mock_reset,\ mock.patch('power._set_freqs_epp') as mock_set_freqs_epp: assert 0 == power.configure_power() mock_reset.assert_called_once_with(pool_to_cores[1]) mock_set_freqs_epp.assert_not_called()
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...")
def run(self, args): """ Runs main loop. Parameters: args: command line arguments """ # load config file try: common.CONFIG_STORE.from_file(args.config) except IOError as ex: log.error("Error reading from config file {}... ".format(args.config)) log.error(ex) return except Exception as ex: log.error("Invalid config file {}... ".format(args.config)) 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") 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...")