1#!/usr/bin/env python3 2# 3# Copyright (C) 2022 Intel Corporation. 4# 5# SPDX-License-Identifier: BSD-3-Clause 6# 7 8import sys, os 9sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'library')) 10import acrn_config_utilities 11import re 12from collections import defaultdict 13from collections import namedtuple 14from acrn_config_utilities import get_node 15 16policy_owner = namedtuple("policy_owner", ["vm_name", "vcpu", "cache_type"]) 17 18class Policy: 19 def __init__(self, cache_id, clos_mask): 20 self.cache_id = cache_id 21 self.clos_mask = clos_mask 22 23 def get_cache_id(self): 24 return self.cache_id 25 26 def get_clos_mask(self): 27 return self.clos_mask 28 29 def match_policy(self, src): 30 return (self.clos_mask == None) or (src.clos_mask == None) or (self.clos_mask == src.clos_mask) 31 32class L3Policy(Policy): 33 def __init__(self, policy): 34 self.cache_id = policy.get_cache_id() 35 self.clos_mask = policy.get_clos_mask() 36 37 def merge_policy(self, src): 38 return self.match_policy(src) 39 40class L2Policy: 41 cache2_id_list = [] 42 43 def __init__(self, policy): 44 self.policy_list = [] 45 for index,cache2_id in enumerate(self.cache2_id_list): 46 if cache2_id == policy.cache_id: 47 self.policy_list.append(policy) 48 else: 49 self.policy_list.append(Policy(None, None)) 50 51 def get_cache_id(self, index): 52 return self.policy_list[index].get_cache_id() 53 54 def get_clos_mask(self, index): 55 return self.policy_list[index].get_clos_mask() 56 57 def match_policy(self, src): 58 for index in range(0, len(self.policy_list)): 59 if not self.policy_list[index].match_policy(src.policy_list[index]): 60 return False 61 return True 62 63 def merge_policy(self, src): 64 if self.match_policy(src): 65 for index in range(0, len(self.policy_list)): 66 if self.policy_list[index].clos_mask is None: 67 self.policy_list[index].clos_mask = src.policy_list[index].clos_mask 68 return True 69 return False 70 71class RdtPolicy: 72 def __init__(self, policy_list, policy_owner): 73 cache2_id = None 74 cache3_id = None 75 l2_mask = None 76 l3_mask = None 77 for policy in policy_list: 78 cache_level = get_node("../CACHE_LEVEL/text()", policy) 79 cache_id = get_node("../CACHE_ID/text()", policy) 80 clos_mask = get_node("./CLOS_MASK/text()", policy) 81 if cache_level == "2": 82 l2_mask = clos_mask 83 cache2_id = cache_id 84 else: 85 l3_mask = clos_mask 86 cache3_id = cache_id 87 self.l2policy = L2Policy(Policy(cache2_id, l2_mask)) 88 self.l3policy = L3Policy(Policy(cache3_id, l3_mask)) 89 90 # a list stored the vCPU or VM info 91 self.policy_owner_list = [policy_owner] 92 93 def match_policy(self, src): 94 return self.l2policy.match_policy(src.l2policy) and self.l3policy.match_policy(src.l3policy) 95 96 #check whether the src could be merged, if yes, add the src owner to policy_owner_list list and return True 97 def merge_policy(self, src): 98 if self.match_policy(src): 99 self.l2policy.merge_policy(src.l2policy) 100 self.l3policy.merge_policy(src.l3policy) 101 self.policy_owner_list += src.policy_owner_list 102 return True 103 return False 104 105 #check whether a VM/vCPU could use this policy 106 def find_policy_owner(self, policy_owner): 107 return policy_owner in self.policy_owner_list 108 109class vCatPolicy(RdtPolicy): 110 def merge_policy(self, src): 111 return False 112 113class CdpPolicy(): 114 def __init__(self,data_list, code_list, owner): 115 self.data_policy = RdtPolicy(data_list, policy_owner(owner.vm_name, owner.vcpu, "Data")) 116 self.code_policy = RdtPolicy(code_list, policy_owner(owner.vm_name, owner.vcpu, "Code")) 117 118 def merge_policy(self, src): 119 if self.code_policy.match_policy(src.code_policy) and self.data_policy.match_policy(src.data_policy): 120 self.code_policy.merge_policy(src.code_policy) 121 self.data_policy.merge_policy(src.data_policy) 122 return True 123 return False 124 125def merge_policy_list(policy_list): 126 result_list = [] 127 for index,p in enumerate(policy_list): 128 merged = False 129 for result in result_list: 130 if result.merge_policy(p): 131 merged = True 132 break; 133 if not merged: 134 result_list.append(p) 135 return result_list 136 137def gen_policy_owner_list(scenario_etree): 138 policy_owner_list = [] 139 vm_list = scenario_etree.xpath("//POLICY/VM") 140 for vm in vm_list: 141 vm_name = get_node("./text()", vm) 142 vcpu = get_node("../VCPU/text()", vm) 143 cache_type = get_node("../TYPE/text()", vm) 144 policy_owner_list.append(policy_owner(vm_name, int(vcpu), cache_type)) 145 return policy_owner_list 146 147def vm_vcat_enable(scenario_etree, vm_name): 148 vcat_enable = get_node(f"//VCAT_ENABLED/text()", scenario_etree) 149 virtual_cat_support = get_node(f"//vm[name = '{vm_name}']/virtual_cat_support/text()", scenario_etree) 150 return (vcat_enable == "y") and (virtual_cat_support == "y") 151 152def cdp_enable(scenario_etree): 153 cdp_enable = get_node(f"//CDP_ENABLED/text()", scenario_etree) 154 return cdp_enable == "y" 155 156def convert_cdp_to_normal(cdp_policy_list): 157 policy_list = [] 158 for cdp_policy in cdp_policy_list: 159 policy_list.append(cdp_policy.data_policy) 160 policy_list.append(cdp_policy.code_policy) 161 return policy_list 162 163def get_policy_list(scenario_etree): 164 init_cache2_id_list(scenario_etree) 165 policy_owner_list = gen_policy_owner_list(scenario_etree) 166 167 result_list = [] 168 for policy_owner in policy_owner_list: 169 dict_tmp = {} 170 policy_list = scenario_etree.xpath(f"//POLICY[VM = '{policy_owner.vm_name}' and VCPU = '{policy_owner.vcpu}']") 171 if cdp_enable(scenario_etree): 172 data_list = scenario_etree.xpath(f"//POLICY[VM = '{policy_owner.vm_name}' and VCPU = '{policy_owner.vcpu}' and TYPE = 'Data']") 173 code_list = scenario_etree.xpath(f"//POLICY[VM = '{policy_owner.vm_name}' and VCPU = '{policy_owner.vcpu}' and TYPE = 'Code']") 174 if policy_owner.cache_type == "Code": 175 continue 176 elif policy_owner.cache_type == "Data": 177 result_list.append(CdpPolicy(data_list, code_list, policy_owner)) 178 elif vm_vcat_enable(scenario_etree, policy_owner.vm_name): 179 result_list.append(vCatPolicy(policy_list, policy_owner)) 180 else: 181 result_list.append(RdtPolicy(policy_list, policy_owner)) 182 result_list = merge_policy_list(result_list) 183 184 if cdp_enable(scenario_etree): 185 result_list = convert_cdp_to_normal(result_list) 186 187 return result_list 188 189def init_cache2_id_list(scenario_etree): 190 cache2_id_list = scenario_etree.xpath("//CACHE_ALLOCATION[CACHE_LEVEL = 2]/CACHE_ID/text()") 191 cache2_id_list.sort() 192 L2Policy.cache2_id_list = cache2_id_list 193