예제 #1
0
    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
예제 #2
0
    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")
예제 #3
0
    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()
예제 #4
0
    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...")
예제 #5
0
    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...")