misc: refine cache config

The current RDT setting requires users to calculate the CLOS mask and
the details, it is not a user-friendly setting.

So we redesigned RDT, users can easily specify the cache of each vcpu
for VMs.

This patch add an RDT region element for schema, calculate and generate
all the mask and rdt parameters by config tool to generates rdt_info
struct for board.c.

Tracked-On: #6690
Signed-off-by: Chenli Wei <chenli.wei@intel.com>
This commit is contained in:
Chenli Wei 2022-04-24 13:39:18 +08:00 committed by acrnsi-robot
parent c25de24a92
commit 4807385fe2
7 changed files with 419 additions and 84 deletions

View File

@ -7,6 +7,8 @@ import sys
import enum
import board_cfg_lib
import common
import lxml.etree
import os
class RDT(enum.Enum):
L2 = 0
@ -17,6 +19,7 @@ INCLUDE_HEADER = """
#include <asm/board.h>
#include <asm/vtd.h>
#include <asm/msr.h>
#include <asm/rdt.h>
#include <pci.h>
#include <misc_cfg.h>
"""
@ -102,9 +105,7 @@ def populate_clos_mask_msr(rdt_res, cat_mask_list, config):
idx = 0
for cat_mask in cat_mask_list:
print("\t{", file=config)
print("\t\t.value.clos_mask = CLOS_MASK_{},".format(idx), file=config)
print("\t\t.msr_index = MSR_IA32_{0}_MASK_BASE + {1},".format(
rdt_res, idx), file=config)
print("\t\t.clos_mask = {},".format(cat_mask), file=config)
print("\t},", file=config)
idx += 1
@ -118,58 +119,148 @@ def populate_mba_delay_mask(rdt_res, mba_delay_list, config):
idx = 0
for mba_delay_mask in mba_delay_list:
print("\t{", file=config)
print("\t\t.value.mba_delay = MBA_MASK_{},".format(idx), file=config)
print("\t\t.msr_index = MSR_IA32_{0}_MASK_BASE + {1},".format(
rdt_res, idx), file=config)
print("\t\t.mba_delay = ,".format(mba_delay_mask), file=config)
print("\t},", file=config)
idx += 1
def gen_rdt_res(config):
"""
Get RDT resource (L2, L3, MBA) information
:param config: it is a file pointer of board information for writing to
"""
err_dic = {}
rdt_res_str =""
res_present = [0, 0, 0]
(rdt_resources, rdt_res_clos_max, _) = board_cfg_lib.clos_info_parser(common.BOARD_INFO_FILE)
common_clos_max = board_cfg_lib.get_common_clos_max()
cat_mask_list = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "RDT", "CLOS_MASK")
mba_delay_list = common.get_hv_item_tag(common.SCENARIO_INFO_FILE, "FEATURES", "RDT", "MBA_DELAY")
if common_clos_max > MSR_IA32_L2_MASK_END - MSR_IA32_L2_MASK_BASE or\
common_clos_max > MSR_IA32_L3_MASK_END - MSR_IA32_L3_MASK_BASE:
err_dic["board config: generate board.c failed"] = "CLOS MAX should be less than reserved adress region length of L2/L3 cache"
return err_dic
print("\n#ifdef CONFIG_RDT_ENABLED", file=config)
if len(rdt_resources) == 0 or common_clos_max == 0:
print("struct platform_clos_info platform_{0}_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];".format("l2"), file=config)
print("struct platform_clos_info platform_{0}_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];".format("l3"), file=config)
print("struct platform_clos_info platform_{0}_clos_array[MAX_MBA_CLOS_NUM_ENTRIES];".format("mba"), file=config)
def get_rdt_enabled():
scenario_etree = lxml.etree.parse(common.SCENARIO_INFO_FILE)
enable = scenario_etree.xpath(f"//RDT_ENABLED/text()")
if enable[0] == "y":
return "true"
else:
for idx, rdt_res in enumerate(rdt_resources):
if rdt_res == "L2":
rdt_res_str = "l2"
print("struct platform_clos_info platform_{0}_clos_array[{1}] = {{".format(rdt_res_str,
"MAX_CACHE_CLOS_NUM_ENTRIES"), file=config)
populate_clos_mask_msr(rdt_res, cat_mask_list, config)
return "false"
def get_cdp_enabled():
scenario_etree = lxml.etree.parse(common.SCENARIO_INFO_FILE)
enable = scenario_etree.xpath(f"//CDP_ENABLED/text()")
if enable[0] == "y":
return "true"
else:
return "false"
def get_common_clos_max(clos_number, capability_id):
common_clos_max = 0
if get_rdt_enabled() and not get_cdp_enabled():
common_clos_max = clos_number
if get_cdp_enabled() and capability_id != 'MBA':
common_clos_max = clos_number / 2
return common_clos_max
def gen_rdt_str(cache, config):
err_dic = {}
cat_mask_list = {}
board_etree = lxml.etree.parse(common.BOARD_INFO_FILE)
mask_length = common.get_node(f"./capability[@id='CAT']/capacity_mask_length/text()", cache)
clos_number = common.get_node(f"./capability[@id='CAT']/clos_number/text()", cache)
bitmask = (1 << int(mask_length)) - 1
cache_level = common.get_node(f"./@level", cache)
cache_id = common.get_node(f"./@id", cache)
processor_list = board_etree.xpath(f"//cache[@level = '{cache_level}' and @id = '{cache_id}']/processors/processor/text()")
capability_list = board_etree.xpath(f"//cache[@level = '{cache_level}' and @id = '{cache_id}']/capability/@id")
for capability_id in capability_list:
common_clos_max = get_common_clos_max(int(clos_number), capability_id)
if capability_id == "CAT":
if common_clos_max > MSR_IA32_L2_MASK_END - MSR_IA32_L2_MASK_BASE or\
common_clos_max > MSR_IA32_L3_MASK_END - MSR_IA32_L3_MASK_BASE:
err_dic["board config: Failed to generate board.c"] = "CLOS Mask Number is more then the reserved address region length of L2/L3 cache"
return err_dic
cdp_enable = get_cdp_enabled()
cat_mask_list = get_mask_list(cache_level, int(cache_id, 16))
if len(cat_mask_list) > int(clos_number):
err_dic['board config: Failed to generate board.c'] = "CLOS Mask Number too bigger then the supported of L2/L3 cache"
return err_dic;
if cache_level == "2":
rdt_res = "l2"
elif cache_level == "3":
rdt_res = "l3"
clos_config_array = "platform_l{0}_clos_array_{1}".format(cache_level, int(cache_id, 16))
print("\t{", file=config)
print("\t\t.res.cache = {", file=config)
print("\t\t\t.bitmask = {0},".format(hex(bitmask)), file=config)
print("\t\t\t.cbm_len = {0},".format(mask_length), file=config)
print("\t\t\t.is_cdp_enabled = {0},".format(cdp_enable), file=config)
print("\t\t},", file=config)
elif capability_id == "MBA":
max_throttling_value = common.get_node(f"./capability/max_throttling_value/text()", cache)
rdt_res = "mba"
clos_config_array = "platform_mba_clos_array"
print("\t{", file=config)
print("\t\t.res.membw = {", file=config)
print("\t\t\t.mba_max = {0},".format(clos_number), file=config)
print("\t\t\t.delay_linear = {0}".format(max_throttling_value), file=config)
print("\t\t},", file=config)
print("\t\t.num_closids = {0},".format(clos_number), file=config)
print("\t\t.num_clos_config = {0},".format(len(cat_mask_list)), file=config)
print("\t\t.clos_config_array = {0},".format(clos_config_array), file=config)
cpu_mask = 0
for processor in processor_list:
core_id = common.get_node(f"//core[@id = '{processor}']/thread/cpu_id/text()", board_etree)
if core_id is None:
continue
else:
cpu_mask = cpu_mask | (1 << int(core_id))
print("\t\t.cpu_mask = {0},".format(hex(cpu_mask)), file=config)
print("\t},", file=config)
return err_dic;
def get_mask_list(cache_level, cache_id):
allocation_dir = os.path.split(common.SCENARIO_INFO_FILE)[0] + "/configs/allocation.xml"
allocation_etree = lxml.etree.parse(allocation_dir)
if cache_level == "3":
clos_list = allocation_etree.xpath(f"//clos_mask[@id = 'l3']/clos/text()")
else:
clos_list = allocation_etree.xpath(f"//clos_mask[@id = '{cache_id}']/clos/text()")
return clos_list
def gen_clos_array(cache_list, config):
err_dic = {}
res_present = [0, 0, 0]
if len(cache_list) == 0:
print("union clos_config platform_{0}_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];".format("l2"), file=config)
print("union clos_config platform_{0}_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];".format("l3"), file=config)
print("union clos_config platform_{0}_clos_array[MAX_MBA_CLOS_NUM_ENTRIES];".format("mba"), file=config)
print("struct rdt_info res_infos[RDT_INFO_NUMBER];", file=config)
else:
for idx, cache in enumerate(cache_list):
cache_level = common.get_node(f"./@level", cache)
cache_id = common.get_node(f"./@id", cache)
clos_number = common.get_node(f"./capability/clos_number/text()", cache)
if cache_level == "2":
cat_mask_list = get_mask_list(cache_level, int(cache_id, 16))
array_size = len(cat_mask_list)
print("union clos_config platform_l2_clos_array_{0}[{1}] = {{".format(int(cache_id, 16), clos_number), file=config)
populate_clos_mask_msr("L2", cat_mask_list, config)
print("};\n", file=config)
res_present[RDT.L2.value] = 1
elif rdt_res == "L3":
rdt_res_str = "l3"
print("struct platform_clos_info platform_{0}_clos_array[{1}] = {{".format(rdt_res_str,
"MAX_CACHE_CLOS_NUM_ENTRIES"), file=config)
populate_clos_mask_msr(rdt_res, cat_mask_list, config)
res_present[RDT.L2.value] += 1
elif cache_level == "3":
cat_mask_list = get_mask_list(cache_level, int(cache_id, 16))
print("union clos_config platform_l3_clos_array_{0}[{1}] = {{".format(int(cache_id, 16), clos_number), file=config)
populate_clos_mask_msr("L3", cat_mask_list, config)
print("};\n", file=config)
res_present[RDT.L3.value] = 1
elif rdt_res == "MBA":
rdt_res_str = "mba"
print("struct platform_clos_info platform_{0}_clos_array[{1}] = {{".format(rdt_res_str,
"MAX_MBA_CLOS_NUM_ENTRIES"), file=config)
err_dic = populate_mba_delay_mask(rdt_res, mba_delay_list, config)
res_present[RDT.L3.value] += 1
elif cache_level == "MBA":
print("union clos_config platform_mba_clos_array[MAX_MBA_CLOS_NUM_ENTRIES] = {", file=config)
err_dic = populate_mba_delay_mask("mba", mba_delay_list, config)
print("};\n", file=config)
res_present[RDT.MBA.value] = 1
else:
@ -177,18 +268,93 @@ def gen_rdt_res(config):
return err_dic
if res_present[RDT.L2.value] == 0:
print("struct platform_clos_info platform_{0}_clos_array[{1}];".format("l2", "MAX_CACHE_CLOS_NUM_ENTRIES"), file=config)
print("union clos_config platform_l2_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];", file=config)
if res_present[RDT.L3.value] == 0:
print("struct platform_clos_info platform_{0}_clos_array[{1}];".format("l3", "MAX_CACHE_CLOS_NUM_ENTRIES"), file=config)
print("union clos_config platform_l3_clos_array[MAX_CACHE_CLOS_NUM_ENTRIES];", file=config)
if res_present[RDT.MBA.value] == 0:
print("struct platform_clos_info platform_{0}_clos_array[{1}];".format("mba", "MAX_MBA_CLOS_NUM_ENTRIES"), file=config)
print("union clos_config platform_mba_clos_array[MAX_MBA_CLOS_NUM_ENTRIES];", file=config)
return 0
print("#endif", file=config)
def gen_rdt_res(config):
"""
Get RDT resource (L2, L3, MBA) information
:param config: it is a file pointer of board information for writing to
"""
print("\n#ifdef CONFIG_RDT_ENABLED", file=config)
err_dic = {}
res_present = [0, 0, 0]
scenario_etree = lxml.etree.parse(common.SCENARIO_INFO_FILE)
allocation_etree = lxml.etree.parse(common.SCENARIO_INFO_FILE)
board_etree = lxml.etree.parse(common.BOARD_INFO_FILE)
cache_list = board_etree.xpath(f"//cache[capability/@id = 'CAT' or capability/@id = 'MBA']")
gen_clos_array(cache_list, config)
cache_list = board_etree.xpath(f"//cache[capability/@id = 'CAT' and @level = '2']")
if len(cache_list) > 0:
res_present[RDT.L2.value] = len(cache_list)
rdt_ins_name = "rdt_ins_l2[" + str(len(cache_list)) + "] = {"
print("struct rdt_ins {}".format(rdt_ins_name), file=config)
for idx, cache in enumerate(cache_list):
err_dic = gen_rdt_str(cache, config)
if err_dic:
return err_dic;
print("};\n", file=config)
cache_list = board_etree.xpath(f"//cache[capability/@id = 'CAT' and @level = '3']")
if len(cache_list) > 0:
res_present[RDT.L3.value] = len(cache_list)
rdt_ins_name = "rdt_ins_l3[" + str(len(cache_list)) + "] = {"
print("struct rdt_ins {}".format(rdt_ins_name), file=config)
for idx, cache in enumerate(cache_list):
err_dic = gen_rdt_str(cache, config)
if err_dic:
return err_dic;
print("};\n", file=config)
cache_list = board_etree.xpath(f"//cache[capability/@id = 'MBA']")
if len(cache_list) > 0:
res_present[RDT.L2.value] = 1
rdt_ins_name = "rdt_ins_mba[" + str(len(cache_list)) + "] = {"
print("struct rdt_ins {}".format(rdt_ins_name), file=config)
for idx, cache in enumerate(cache_list):
err_dic = gen_rdt_str(cache, config)
if err_dic:
return err_dic;
print("};\n", file=config)
print("struct rdt_type res_cap_info[RDT_NUM_RESOURCES] = {", file=config)
if res_present[RDT.L2.value] > 0:
print("\t{", file=config)
print("\t\t.res_id = RDT_RESID_L2,", file=config)
print("\t\t.msr_qos_cfg = MSR_IA32_L2_QOS_CFG,", file=config)
print("\t\t.msr_base = MSR_IA32_L2_MASK_BASE,", file=config)
print("\t\t.num_ins = {},".format(res_present[RDT.L2.value]), file=config)
print("\t\t.ins_array = rdt_ins_l2,", file=config)
print("\t},", file=config)
if res_present[RDT.L3.value] > 0:
print("\t{", file=config)
print("\t\t.res_id = RDT_RESID_L3,", file=config)
print("\t\t.msr_qos_cfg = MSR_IA32_L3_QOS_CFG,", file=config)
print("\t\t.msr_base = MSR_IA32_L3_MASK_BASE,", file=config)
print("\t\t.num_ins = {},".format(res_present[RDT.L3.value]), file=config)
print("\t\t.ins_array = rdt_ins_l3,", file=config)
print("\t},", file=config)
if res_present[RDT.MBA.value] > 0:
print("\t{", file=config)
print("\t\t.res_id = RDT_RESID_MBA,", file=config)
print("\t\t.msr_qos_cfg = MSR_IA32_MBA_QOS_CFG,", file=config)
print("\t\t.msr_base = MSR_IA32_MBA_MASK_BASE,", file=config)
print("\t\t.num_ins = {},".format(res_present[RDT.MBA.value]), file=config)
print("\t\t.ins_array = rdt_ins_mba,", file=config)
print("\t},", file=config)
print("};\n", file=config)
print("#endif\n", file=config)
print("", file=config)
return err_dic
def gen_single_data(data_lines, domain_str, config):
line_i = 0
data_statues = True

View File

@ -277,6 +277,11 @@ These settings can only be changed at build time.</xs:documentation>
Refer to :ref:`vuart_config` for detailed vUART settings.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="CACHE_REGION" type="CacheRegionType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Specify the cache setting.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>

View File

@ -320,20 +320,6 @@ RDT, setting this option to ``y`` is ignored.</xs:documentation>
<xs:documentation>Enable virtualization of the Cache Allocation Technology (CAT) feature in RDT. CAT enables you to allocate cache to VMs, providing isolation to avoid performance interference from other VMs.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="CLOS_MASK" type="xs:string" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Specify the cache capacity bitmask for the CLOS; only continuous '1' bits
are allowed. The value will be ignored when hardware does not support RDT.
This option takes effect only if :option:`hv.FEATURES.RDT.RDT_ENABLED` is set to ``y``.
As :option:`vm.clos.vcpu_clos` specifies the index of the CLOS to be associated with the given vCPU,
:option:`hv.FEATURES.RDT.CLOS_MASK` of that CLOS would impact the performance of the given vCPU.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="MBA_DELAY" type="xs:string" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Memory Bandwidth Allocation delay value.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
@ -347,4 +333,38 @@ As :option:`vm.clos.vcpu_clos` specifies the index of the CLOS to be associated
</xs:sequence>
</xs:complexType>
<xs:simpleType name="CacheType">
<xs:annotation>
<xs:documentation>Option: Unified, Code, Data</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="Unified"/>
<xs:enumeration value="Code" />
<xs:enumeration value="Data" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="CachePolicyType">
<xs:sequence>
<xs:element name="VM" type="xs:string" />
<xs:element name="VCPU" type="xs:integer" />
<xs:element name="TYPE" type="CacheType" minOccurs="1"/>
<xs:element name="CLOS_MASK" type="HexFormat" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="CacheAllocationType">
<xs:sequence>
<xs:element name="CACHE_ID" type="xs:integer"/>
<xs:element name="CACHE_LEVEL" type="xs:integer"/>
<xs:element name="POLICY" type="CachePolicyType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CacheRegionType">
<xs:sequence>
<xs:element name="CACHE_ALLOCATION" type="CacheAllocationType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>

View File

@ -0,0 +1,150 @@
#!/usr/bin/env python3
#
# Copyright (C) 2022 Intel Corporation.
#
# SPDX-License-Identifier: BSD-3-Clause
#
import sys, os
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'library'))
import common
import re
from collections import defaultdict
from itertools import combinations
def create_clos_node(etree, vm_id, index_list):
allocation_vm_node = common.get_node(f"/acrn-config/vm[@id = '{vm_id}']", etree)
if allocation_vm_node is None:
allocation_vm_node = common.append_node("/acrn-config/vm", None, etree, id = vm_id)
if common.get_node("./clos", allocation_vm_node) is None:
clos_node = common.append_node("./clos", None, allocation_vm_node)
for index in index_list:
common.append_node(f"./vcpu_clos", str(index), clos_node)
def find_cache2_id(mask, cache2_id_list):
for cache2 in cache2_id_list:
if mask[cache2] != "None":
return cache2
return "None"
def merge_policy_list(mask_list, cache2_id_list):
index = 0
result_list = []
for index,mask in enumerate(mask_list):
merged = 0
if index == 0:
result_list.append(mask)
continue
for result in result_list:
if result["l3"] != mask["l3"]:
continue
else:
cache2_id = find_cache2_id(mask, cache2_id_list)
if cache2_id == "None" or result[cache2_id] == mask[cache2_id]:
merged = 1
break
if result[cache2_id] == "None":
merged = 1
result[cache2_id] = mask[cache2_id]
break
if merged == 0:
result_list.append(mask)
return result_list
def gen_all_clos_index(board_etree, scenario_etree, allocation_etree):
policy_list = []
allocation_list = scenario_etree.xpath(f"//POLICY")
cache2_id_list = scenario_etree.xpath("//CACHE_ALLOCATION[CACHE_LEVEL = 2]/CACHE_ID/text()")
cache2_id_list.sort()
for policy in allocation_list:
cache_level = common.get_node("../CACHE_LEVEL/text()", policy)
cache_id = common.get_node("../CACHE_ID/text()", policy)
vcpu = common.get_node("./VCPU/text()", policy)
mask = common.get_node("./CLOS_MASK/text()", policy)
tmp = (cache_level, cache_id, vcpu, mask)
policy_list.append(tmp)
vCPU_list = scenario_etree.xpath(f"//POLICY/VCPU/text()")
l3_mask_list = scenario_etree.xpath(f"//CACHE_ALLOCATION[CACHE_LEVEL = 3]/POLICY/CLOS_MASK")
mask_list = []
for vCPU in vCPU_list:
dict_tmp = {}
l3_mask = l2_mask = "None"
l3_mask_list = scenario_etree.xpath(f"//CACHE_ALLOCATION[CACHE_LEVEL = 3]/POLICY[VCPU = '{vCPU}']/CLOS_MASK/text()")
if len(l3_mask_list) > 0:
l3_mask = l3_mask_list[0]
dict_tmp["l3"] = l3_mask
l2_mask_list = scenario_etree.xpath(f"//CACHE_ALLOCATION[CACHE_LEVEL = 2]/POLICY[VCPU = '{vCPU}']/CLOS_MASK")
if len(l2_mask_list) > 0:
l2_mask = l2_mask_list[0].text
cache_id = scenario_etree.xpath(f"//CACHE_ALLOCATION[CACHE_LEVEL = 2 and POLICY/VCPU = '{vCPU}']/CACHE_ID/text()")[0]
for cache2 in cache2_id_list:
if cache2 == cache_id:
dict_tmp[cache_id] = l2_mask
else:
dict_tmp[cache2] = "None"
mask_list.append(dict_tmp)
mask_list = merge_policy_list(mask_list, cache2_id_list)
return mask_list
def get_clos_index(cache_level, cache_id, clos_mask):
mask_list = common.get_mask_list(cache_level, cache_id)
idx = 0
for mask in mask_list:
idx += 1
if mask == clos_mask:
break
return idx
def get_clos_id(mask_list, l2_id, l2_mask, l3_mask):
for mask in mask_list:
if mask[l2_id] == l2_mask and mask["l3"] == l3_mask:
return mask_list.index(mask)
return 0
def alloc_clos_index(board_etree, scenario_etree, allocation_etree, mask_list):
vm_node_list = scenario_etree.xpath("//vm")
for vm_node in vm_node_list:
vmname = common.get_node("./name/text()", vm_node)
allocation_list = scenario_etree.xpath(f"//CACHE_ALLOCATION[POLICY/VM = '{vmname}']")
for allocation in allocation_list:
index_list = []
cache_level = common.get_node("./CACHE_LEVEL/text()", allocation)
cache_id = common.get_node("./CACHE_ID/text()", allocation)
clos_mask_list = allocation.xpath(f".//POLICY[VM = '{vmname}']/CLOS_MASK/text()")
for clos_mask in clos_mask_list:
index = get_clos_id(mask_list, cache_id, clos_mask, "None")
index_list.append(index)
create_clos_node(allocation_etree, common.get_node("./@id", vm_node), index_list)
def creat_mask_list_node(board_etree, scenario_etree, allocation_etree, mask_list):
allocation_hv_node = common.get_node(f"//hv", allocation_etree)
if allocation_hv_node is None:
allocation_hv_node = common.append_node("//hv", None, allocation_etree, id = vm_id)
cache2_id_list = scenario_etree.xpath("//CACHE_ALLOCATION[CACHE_LEVEL = 2]/CACHE_ID/text()")
cache2_id_list.sort()
if common.get_node("./clos_mask[@id = l3]", allocation_hv_node) is None:
clos_mask = common.append_node("./clos_mask", None, allocation_hv_node, id="l3")
for i in range(0, len(mask_list)):
if mask_list[i]["l3"] == "None":
value = "0xffff"
else:
value = str(mask_list[i]["l3"])
common.append_node(f"./clos", value, clos_mask)
for cache2 in cache2_id_list:
if common.get_node("./clos_mask[@id = '{cache2}']", allocation_hv_node) is None:
clos_mask = common.append_node("./clos_mask", None, allocation_hv_node, id=cache2)
for i in range(0, len(mask_list)):
if mask_list[i][cache2] == "None":
value = "0xffff"
else:
value = str(mask_list[i][cache2] )
common.append_node(f"./clos", value, clos_mask)
def fn(board_etree, scenario_etree, allocation_etree):
mask_list = gen_all_clos_index(board_etree, scenario_etree, allocation_etree)
creat_mask_list_node(board_etree, scenario_etree, allocation_etree, mask_list)
alloc_clos_index(board_etree, scenario_etree, allocation_etree, mask_list)

View File

@ -564,12 +564,12 @@
<!-- Board-specific functions-->
<func:function name="acrn:get-normalized-closinfo-rdt-res-str">
<xsl:variable name="rdt_resource" select="translate(substring-before(substring-after(//CLOS_INFO, 'rdt resources supported:'), 'rdt resource clos max:'), $whitespaces, '')" />
<xsl:variable name="rdt_resource" select="acrn:string-join(//cache[capability/@id='CAT']/@level, ', ', 'L', '')" />
<func:result select="$rdt_resource" />
</func:function>
<func:function name="acrn:get-normalized-closinfo-rdt-clos-max-str">
<xsl:variable name="rdt_res_clos_max" select="translate(substring-before(substring-after(//CLOS_INFO, 'rdt resource clos max:'), 'rdt resource mask max:'), $whitespaces, '')" />
<xsl:variable name="rdt_res_clos_max" select="acrn:string-join(//cache[capability/@id='CAT']/capability/clos_number, ', ', '', '')"/>
<func:result select="$rdt_res_clos_max" />
</func:function>

View File

@ -152,12 +152,6 @@
</xsl:otherwise>
</xsl:choose>
<xsl:if test="acrn:is-rdt-supported()">
<xsl:for-each select="hv/FEATURES/RDT/MBA_DELAY">
<xsl:value-of select="acrn:define(concat('MBA_MASK_', position() - 1), current(), 'U')" />
</xsl:for-each>
<xsl:for-each select="hv/FEATURES/RDT/CLOS_MASK">
<xsl:value-of select="acrn:define(concat('CLOS_MASK_', position() - 1), current(), 'U')" />
</xsl:for-each>
<xsl:value-of select="$endif" />
</xsl:if>
</xsl:template>

View File

@ -68,8 +68,9 @@
<xsl:value-of select="acrn:ifdef('CONFIG_RDT_ENABLED')" />
<xsl:for-each select="vm">
<xsl:value-of select="concat('static uint16_t ', concat('vm', @id, '_vcpu_clos'), '[', count(clos/vcpu_clos), 'U] = {')" />
<xsl:value-of select="acrn:string-join(clos/vcpu_clos, ', ', '', 'U')" />
<xsl:variable name="vm_id" select="@id" />
<xsl:value-of select="concat('static uint16_t ', concat('vm', @id, '_vcpu_clos'), '[', count(//allocation-data/acrn-config/vm[@id=$vm_id]/clos/vcpu_clos), 'U] = {')" />
<xsl:value-of select="acrn:string-join(//allocation-data/acrn-config/vm[@id=$vm_id]/clos/vcpu_clos, ', ', '', 'U')" />
<xsl:text>};</xsl:text>
<xsl:value-of select="$newline" />
</xsl:for-each>
@ -179,18 +180,17 @@
<xsl:value-of select="acrn:ifdef('CONFIG_RDT_ENABLED')" />
<xsl:value-of select="acrn:initializer('pclosids', concat('vm', ../@id, '_vcpu_clos'))" />
<xsl:value-of select="acrn:initializer('num_pclosids', concat(count(vcpu_clos), 'U'))" />
<xsl:variable name="vm_id" select="../@id" />
<xsl:value-of select="acrn:initializer('num_pclosids', concat(count(//allocation-data/acrn-config/vm[@id=$vm_id]/clos/vcpu_clos), 'U'))" />
<xsl:if test="acrn:is-vcat-enabled() and ../virtual_cat_support[text() = 'y']">
<xsl:variable name="rdt_res_str" select="acrn:get-normalized-closinfo-rdt-res-str()" />
<xsl:variable name="closid" select="vcpu_clos[1]" />
<xsl:if test="contains($rdt_res_str, 'L2')">
<xsl:value-of select="acrn:initializer('max_l2_pcbm', concat(../../hv/FEATURES/RDT/CLOS_MASK[$closid + 1], 'U'))" />
<xsl:value-of select="acrn:initializer('max_l2_pcbm', concat(math:max(//allocation-data/acrn-config/vm[@id=$vm_id]/clos/vcpu_clos), 'U'))" />
</xsl:if>
<xsl:if test="contains($rdt_res_str, 'L3')">
<xsl:value-of select="acrn:initializer('max_l3_pcbm', concat(../../hv/FEATURES/RDT/CLOS_MASK[$closid + 1], 'U'))" />
<xsl:value-of select="acrn:initializer('max_l3_pcbm', concat(math:max(//allocation-data/acrn-config/vm[@id=$vm_id]/clos/vcpu_clos), 'U'))" />
</xsl:if>
</xsl:if>