Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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
Beispiel #6
0
    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'])
Beispiel #7
0
    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)
Beispiel #8
0
        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))
Beispiel #9
0
    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
Beispiel #10
0
        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.")
Beispiel #11
0
    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)
Beispiel #12
0
    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)
Beispiel #13
0
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
Beispiel #14
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...")