config_tools: refine cat widget
refine cat widget Tracked-On: #6691 Signed-off-by: Weiyi Feng <weiyix.feng@intel.com>
This commit is contained in:
parent
9f7c4b6bab
commit
342e8c05f6
|
@ -1,18 +1,631 @@
|
|||
import {dialog, invoke} from "@tauri-apps/api";
|
||||
import JSON2XML from "./json2xml"
|
||||
import {OpenDialogOptions} from "@tauri-apps/api/dialog";
|
||||
import _ from "lodash";
|
||||
import {vueUtils} from "@lljj/vue3-form-naive";
|
||||
|
||||
enum HistoryType {
|
||||
function all(arr: boolean[]): boolean {
|
||||
return arr.every(element => element === true);
|
||||
}
|
||||
|
||||
function count(source, target) {
|
||||
return (source.match(new RegExp(target, 'g')) || []).length;
|
||||
}
|
||||
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
configurator: Configurator;
|
||||
getSchemaData: () => any;
|
||||
getCurrentScenarioData: () => any;
|
||||
getBoardData: () => any;
|
||||
pyodide: {
|
||||
pyimport: (name: string) => { main: (...any) => any },
|
||||
runPython: (code: string) => string
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
enum HistoryTypeEnum {
|
||||
WorkingFolder,
|
||||
Board,
|
||||
Scenario
|
||||
}
|
||||
|
||||
export type HistoryTypeString = keyof typeof HistoryType;
|
||||
export type HistoryTypes = keyof typeof HistoryTypeEnum;
|
||||
|
||||
|
||||
enum PolicyTypeEnum {
|
||||
Unified,
|
||||
Code,
|
||||
Data
|
||||
}
|
||||
|
||||
type PolicyType = keyof typeof PolicyTypeEnum
|
||||
|
||||
type Policy = {
|
||||
VM: string,
|
||||
VCPU: number,
|
||||
TYPE: PolicyType,
|
||||
CLOS_MASK: string
|
||||
}
|
||||
|
||||
type CATDBRecord = {
|
||||
CACHE_LEVEL: number,
|
||||
CACHE_ID: string,
|
||||
META: { vmid: number },
|
||||
VM: string,
|
||||
VCPU: number,
|
||||
TYPE: PolicyType,
|
||||
CLOS_MASK: string
|
||||
}
|
||||
|
||||
type CATUIDataObject = {
|
||||
errorMsg: string,
|
||||
regions: {
|
||||
level: number,
|
||||
id: string,
|
||||
capacity_mask_length: number,
|
||||
type: string,
|
||||
cache_size: number,
|
||||
processors: number[],
|
||||
data: {
|
||||
RTCore: Policy[],
|
||||
Standard: Policy[],
|
||||
VCAT: Policy[],
|
||||
},
|
||||
}[],
|
||||
summary: {
|
||||
[CATRegionLevel: string]: {
|
||||
count: number,
|
||||
[CATRegionID: string]: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
type vmID = number;
|
||||
|
||||
class CAT {
|
||||
private scenario: any;
|
||||
private schemaData: any;
|
||||
private CAT_REGION_INFO: any;
|
||||
|
||||
private switches: {
|
||||
SSRAM_ENABLED: boolean,
|
||||
RDT_ENABLED: boolean,
|
||||
CDP_ENABLED: boolean,
|
||||
VCAT_ENABLED: boolean
|
||||
};
|
||||
|
||||
private preLaunchedVMCPUs: string[];
|
||||
private serviceVM: any;
|
||||
private serviceVMCPUs: string[];
|
||||
|
||||
public CATDB: CATDBRecord[];
|
||||
private vmIDs: { [vmName: string]: vmID };
|
||||
|
||||
hexToRange(hexValue, maxValue) {
|
||||
let str_bin = Number.parseInt(hexValue).toString(2);
|
||||
let block_length = str_bin.length;
|
||||
let block_enabled_length = count(str_bin, "1");
|
||||
|
||||
let start: number
|
||||
let end: number
|
||||
|
||||
if (block_length > maxValue) {
|
||||
if (block_enabled_length >= maxValue) {
|
||||
str_bin = "1".repeat(maxValue);
|
||||
} else {
|
||||
str_bin = "0".repeat(maxValue - block_enabled_length) + "1".repeat(block_enabled_length);
|
||||
}
|
||||
} else {
|
||||
if (block_length < maxValue) {
|
||||
str_bin = "0".repeat(maxValue - block_length) + str_bin;
|
||||
}
|
||||
}
|
||||
|
||||
start = str_bin.indexOf("1") !== -1 ? str_bin.indexOf("1") : 0;
|
||||
end = start + count(str_bin, "1");
|
||||
|
||||
return [start, end]
|
||||
}
|
||||
|
||||
rangeToHex(value, max) {
|
||||
let newHexValue = '0'.repeat(value[0]) + '1'.repeat(value[1] - value[0]) + '0'.repeat(max - value[1])
|
||||
newHexValue = (parseInt(newHexValue, 2).toString(16))
|
||||
let zeroPadding = '0'.repeat(Number.parseInt('1'.repeat(max), 2).toString(16).length - newHexValue.length)
|
||||
newHexValue = '0x' + zeroPadding + newHexValue;
|
||||
return newHexValue;
|
||||
}
|
||||
|
||||
formDataProxy(name, data = null, update = false) {
|
||||
let path = {
|
||||
'SSRAM_ENABLED': 'FEATURES.SSRAM.SSRAM_ENABLED',
|
||||
'RDT_ENABLED': 'FEATURES.RDT.RDT_ENABLED',
|
||||
'CDP_ENABLED': 'FEATURES.RDT.CDP_ENABLED',
|
||||
'VCAT_ENABLED': 'FEATURES.RDT.VCAT_ENABLED',
|
||||
}[name]
|
||||
|
||||
// check parent node exists
|
||||
let oldValue = vueUtils.getPathVal(this.scenario.hv, path);
|
||||
if (oldValue === undefined) {
|
||||
let t = path.split('.');
|
||||
let parentPath = t.splice(0, t.length - 1).join('.');
|
||||
if (!vueUtils.getPathVal(this.scenario.hv, parentPath)) {
|
||||
vueUtils.setPathVal(this.scenario.hv, parentPath, {});
|
||||
}
|
||||
// set to checkbox default value
|
||||
vueUtils.setPathVal(this.scenario.hv, path, 'n');
|
||||
}
|
||||
// if data is not empty, set value
|
||||
if (data !== null) {
|
||||
vueUtils.setPathVal(this.scenario.hv, path, data)
|
||||
|
||||
// if data is not empty, set value as expected and update CAT_INFO
|
||||
if (update) {
|
||||
switch (name) {
|
||||
case 'SSRAM_ENABLED':
|
||||
this.formDataProxy('RDT_ENABLED', 'n');
|
||||
this.formDataProxy('CDP_ENABLED', 'n');
|
||||
this.formDataProxy('VCAT_ENABLED', 'n');
|
||||
break;
|
||||
case 'RDT_ENABLED':
|
||||
this.formDataProxy('SSRAM_ENABLED', 'n');
|
||||
if (data === 'n') {
|
||||
this.formDataProxy('CDP_ENABLED', 'n');
|
||||
this.formDataProxy('VCAT_ENABLED', 'n');
|
||||
}
|
||||
break;
|
||||
case 'CDP_ENABLED':
|
||||
this.formDataProxy('SSRAM_ENABLED', 'n');
|
||||
if (data === 'y') {
|
||||
this.formDataProxy('RDT_ENABLED', 'y');
|
||||
this.formDataProxy('VCAT_ENABLED', 'n');
|
||||
}
|
||||
break;
|
||||
case 'VCAT_ENABLED':
|
||||
this.formDataProxy('SSRAM_ENABLED', 'n');
|
||||
if (data === 'y') {
|
||||
this.formDataProxy('RDT_ENABLED', 'y');
|
||||
this.formDataProxy('CDP_ENABLED', 'n');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let result: string;
|
||||
// @ts-ignore
|
||||
result = vueUtils.getPathVal(this.scenario.hv, path);
|
||||
if (typeof result !== 'string') {
|
||||
console.log(`Unexpected result of ${name}: `, result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
scenarioLoaded() {
|
||||
// get CAT schema && scenario data
|
||||
this.schemaData = window.getSchemaData();
|
||||
this.scenario = window.getCurrentScenarioData();
|
||||
this.vmIDs = this.getVMIDs()
|
||||
// get cat scenario data
|
||||
this.CATDB = this.getCATDataFromScenario();
|
||||
}
|
||||
|
||||
getScenarioDataFromCAT() {
|
||||
let CATUIData = this.getCATUIData();
|
||||
let ScenarioCATData: {
|
||||
CACHE_ALLOCATION: {
|
||||
CACHE_ID: string,
|
||||
CACHE_LEVEL: number,
|
||||
POLICY: Policy[]
|
||||
}[]
|
||||
}
|
||||
if (CATUIData.regions.length === 0) {
|
||||
return null;
|
||||
}
|
||||
ScenarioCATData = {CACHE_ALLOCATION: []}
|
||||
for (const region of CATUIData.regions) {
|
||||
let policies: Policy[] = region.data.RTCore.concat(region.data.Standard, region.data.VCAT);
|
||||
ScenarioCATData.CACHE_ALLOCATION.push({
|
||||
CACHE_ID: region.id,
|
||||
CACHE_LEVEL: region.level,
|
||||
POLICY: policies
|
||||
})
|
||||
}
|
||||
return ScenarioCATData;
|
||||
}
|
||||
|
||||
|
||||
getCATUIData(): CATUIDataObject {
|
||||
// get CAT schema && scenario && board basic data
|
||||
this.schemaData = window.getSchemaData();
|
||||
this.scenario = window.getCurrentScenarioData();
|
||||
this.CAT_REGION_INFO = window.getBoardData().CAT_INFO;
|
||||
|
||||
// check scenario data is empty
|
||||
// usually, this happens when user has no scenario loaded, then import a board
|
||||
if (!this.scenario.hv) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// get switches status from scenario
|
||||
// @ts-ignore
|
||||
this.switches = new Proxy({}, {
|
||||
get: (target: {}, switchName: string | symbol): any => {
|
||||
return this.formDataProxy(switchName) === 'y'
|
||||
},
|
||||
set: (target: {}, switchName: string | symbol, value: boolean): boolean => {
|
||||
return this.formDataProxy(switchName, value ? 'y' : 'n', true) === 'y';
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// if no CAT REGION INFO from board xml,
|
||||
// means this board(or CPU) not support CAT, or all support CAT region only have one CPU core
|
||||
if (this.CAT_REGION_INFO.length === 0) {
|
||||
let errorMsg = 'This board(or CPU) not support CAT, or all support CAT region only have one CPU core';
|
||||
console.log(errorMsg);
|
||||
return {
|
||||
errorMsg,
|
||||
regions: [],
|
||||
summary: {}
|
||||
};
|
||||
}
|
||||
|
||||
// correct switches and return rdt_enabled result
|
||||
if (!this.correctSwitches()) {
|
||||
return {
|
||||
errorMsg: '',
|
||||
regions: [],
|
||||
summary: {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// CPU affinity data checks
|
||||
// If error, only show error message
|
||||
let errorMsg = this.checkCPUAffinity()
|
||||
|
||||
|
||||
// get CPU data
|
||||
this.preLaunchedVMCPUs = this.getPreLaunchedVMCPUs();
|
||||
this.serviceVM = this.getServiceVM();
|
||||
this.serviceVMCPUs = this.getServiceVMVCPUs()
|
||||
this.vmIDs = this.getVMIDs()
|
||||
|
||||
|
||||
let CATUIData: CATUIDataObject = {
|
||||
errorMsg, regions: [], summary: {}
|
||||
};
|
||||
// mapping CAT region info
|
||||
this.CAT_REGION_INFO.map(region => {
|
||||
let regionData = _.cloneDeep(region);
|
||||
if (!CATUIData.summary.hasOwnProperty(regionData.level)) {
|
||||
CATUIData.summary[regionData.level] = {count: 0}
|
||||
}
|
||||
CATUIData.summary[regionData.level].count++;
|
||||
CATUIData.summary[regionData.level][regionData.id] = CATUIData.summary[regionData.level].count;
|
||||
|
||||
regionData['data'] = {
|
||||
RTCore: this.getRTCoreData(regionData),
|
||||
Standard: this.getStandardData(regionData),
|
||||
VCAT: this.getVCATData(regionData)
|
||||
}
|
||||
CATUIData.regions.push(regionData);
|
||||
})
|
||||
|
||||
|
||||
return CATUIData
|
||||
}
|
||||
|
||||
haveCPUAffinity(vmConfig) {
|
||||
if (vmConfig.load_order === 'SERVICE_VM') {
|
||||
return false
|
||||
}
|
||||
return (
|
||||
vmConfig.hasOwnProperty('cpu_affinity') &&
|
||||
vmConfig.cpu_affinity.hasOwnProperty('pcpu') &&
|
||||
_.isArray(vmConfig.cpu_affinity.pcpu)
|
||||
)
|
||||
}
|
||||
|
||||
checkCPUAffinity() {
|
||||
// check cpu affinity
|
||||
let errMsg = ['CPU affinity is not set for the following VMs:'];
|
||||
let result = all(this.scenario.vm.map(vmConfig => {
|
||||
if (vmConfig.load_order === 'SERVICE_VM') {
|
||||
return true
|
||||
}
|
||||
let haveCPUAffinitySetting = this.haveCPUAffinity(vmConfig);
|
||||
if (!haveCPUAffinitySetting) {
|
||||
errMsg.push(`VM ${vmConfig.name} has no CPU affinity setting`);
|
||||
}
|
||||
return haveCPUAffinitySetting;
|
||||
}))
|
||||
if (result) {
|
||||
return '';
|
||||
}
|
||||
errMsg.push('Please set CPU affinity for all VMs');
|
||||
return errMsg.join('\n')
|
||||
}
|
||||
|
||||
correctSwitches() {
|
||||
if (this.switches.SSRAM_ENABLED) {
|
||||
if (this.switches.RDT_ENABLED) {
|
||||
this.switches.RDT_ENABLED = false
|
||||
}
|
||||
if (this.switches.CDP_ENABLED) {
|
||||
this.switches.CDP_ENABLED = false
|
||||
}
|
||||
if (this.switches.VCAT_ENABLED) {
|
||||
this.switches.VCAT_ENABLED = false
|
||||
}
|
||||
} else if (this.switches.RDT_ENABLED) {
|
||||
if (this.switches.CDP_ENABLED) {
|
||||
if (this.switches.VCAT_ENABLED) {
|
||||
this.switches.VCAT_ENABLED = false
|
||||
}
|
||||
}
|
||||
} else if (this.switches.CDP_ENABLED || this.switches.VCAT_ENABLED) {
|
||||
if (!this.switches.RDT_ENABLED) {
|
||||
this.switches.RDT_ENABLED = true
|
||||
}
|
||||
}
|
||||
return this.switches.RDT_ENABLED
|
||||
}
|
||||
|
||||
getPreLaunchedVMCPUs() {
|
||||
let preLaunchedVMCPUs = [];
|
||||
|
||||
this.scenario.vm.map(vmConfig => {
|
||||
if (vmConfig.load_order === 'PRE_LAUNCHED_VM' && this.haveCPUAffinity(vmConfig)) {
|
||||
let vmCPUIDs = vmConfig.cpu_affinity.pcpu.map(pcpu => {
|
||||
return pcpu.pcpu_id;
|
||||
})
|
||||
preLaunchedVMCPUs.concat(vmCPUIDs)
|
||||
}
|
||||
})
|
||||
|
||||
return preLaunchedVMCPUs;
|
||||
}
|
||||
|
||||
newPolicy(CACHE_ID, CACHE_LEVEL, vmConfig, VCPU, TYPE: PolicyType, maxLength): Policy {
|
||||
let originPolicy = {
|
||||
VM: vmConfig.name,
|
||||
VCPU, TYPE,
|
||||
CLOS_MASK: this.getCLOSMask(CACHE_ID, CACHE_LEVEL, vmConfig['@id'], vmConfig.name, VCPU, TYPE, maxLength)
|
||||
}
|
||||
return new Proxy(originPolicy, {
|
||||
set: (target, key, value) => {
|
||||
target[key] = value;
|
||||
if (key === 'CLOS_MASK') {
|
||||
console.log(`${CACHE_ID} ${CACHE_LEVEL} ${vmConfig.name} ${VCPU} ${TYPE} CLOS_MASK: ${value}`);
|
||||
this.setCLOSMask(CACHE_ID, CACHE_LEVEL, vmConfig['@id'], vmConfig.name, VCPU, TYPE, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
selectCATData(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE: PolicyType) {
|
||||
for (let i = 0; i < this.CATDB.length; i++) {
|
||||
let CATData = this.CATDB[i];
|
||||
if (
|
||||
CATData.CACHE_ID === CACHE_ID && CATData.CACHE_LEVEL === CACHE_LEVEL &&
|
||||
CATData.META.vmid === vmID && CATData.VCPU === VCPU && CATData.TYPE === TYPE
|
||||
) {
|
||||
return CATData
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
setCLOSMask(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE: PolicyType, CLOS_MASK: string) {
|
||||
let CATData = this.selectCATData(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE);
|
||||
if (CATData !== false) {
|
||||
CATData.CLOS_MASK = CLOS_MASK;
|
||||
return true;
|
||||
}
|
||||
|
||||
this.CATDB.push({
|
||||
META: {vmid: vmID},
|
||||
CACHE_ID, CACHE_LEVEL,
|
||||
CLOS_MASK,
|
||||
VM: vmName, VCPU, TYPE,
|
||||
})
|
||||
return true;
|
||||
}
|
||||
|
||||
getCLOSMask(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE: PolicyType, maxLength: number) {
|
||||
let CATData = this.selectCATData(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE);
|
||||
if (CATData !== false) {
|
||||
let CLOS_MASK = CATData.CLOS_MASK;
|
||||
// ensure CLOS_MASK length is shorter or equal to maxLength
|
||||
CLOS_MASK = this.rangeToHex(this.hexToRange(CLOS_MASK, maxLength), maxLength);
|
||||
return CLOS_MASK;
|
||||
}
|
||||
let CLOS_MASK = "0x" + parseInt('1'.repeat(maxLength), 2).toString(16)
|
||||
this.CATDB.push({
|
||||
META: {vmid: vmID},
|
||||
CACHE_ID, CACHE_LEVEL,
|
||||
CLOS_MASK,
|
||||
VM: vmName, VCPU, TYPE,
|
||||
})
|
||||
return CLOS_MASK;
|
||||
}
|
||||
|
||||
getRTCoreData(regionData): Policy[] {
|
||||
let RTCoreData: Policy[] = [];
|
||||
this.scenario.vm.map(vmConfig => {
|
||||
if (this.haveCPUAffinity(vmConfig)) {
|
||||
vmConfig.cpu_affinity.pcpu.map(
|
||||
(pcpu, index) => {
|
||||
if (
|
||||
regionData.processors.indexOf(pcpu.pcpu_id) !== -1 &&
|
||||
pcpu.hasOwnProperty('real_time_vcpu') &&
|
||||
pcpu.real_time_vcpu === 'y'
|
||||
) {
|
||||
if (!this.switches.CDP_ENABLED) {
|
||||
RTCoreData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, 'Unified', regionData.capacity_mask_length))
|
||||
} else {
|
||||
RTCoreData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, 'Code', regionData.capacity_mask_length))
|
||||
RTCoreData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, 'Data', regionData.capacity_mask_length))
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
_.sortBy(RTCoreData, ['VM', 'VCPU', 'TYPE']);
|
||||
|
||||
return RTCoreData;
|
||||
}
|
||||
|
||||
|
||||
getStandardData(regionData): Policy[] {
|
||||
let StandardData: Policy[] = [];
|
||||
this.scenario.vm.map(vmConfig => {
|
||||
if (this.haveCPUAffinity(vmConfig)) {
|
||||
vmConfig.cpu_affinity.pcpu.map(
|
||||
(pcpu, index) => {
|
||||
if (
|
||||
regionData.processors.indexOf(pcpu.pcpu_id) !== -1 && (
|
||||
!pcpu.hasOwnProperty('real_time_vcpu') ||
|
||||
pcpu.real_time_vcpu === 'n'
|
||||
)
|
||||
) {
|
||||
if (!this.switches.CDP_ENABLED) {
|
||||
StandardData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, 'Unified', regionData.capacity_mask_length))
|
||||
} else {
|
||||
StandardData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, "Code", regionData.capacity_mask_length))
|
||||
StandardData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, "Data", regionData.capacity_mask_length))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// add service vm policy
|
||||
StandardData = StandardData.concat(
|
||||
this.getServiceData(regionData),
|
||||
)
|
||||
|
||||
_.sortBy(StandardData, ['VM', 'VCPU', 'TYPE']);
|
||||
return StandardData;
|
||||
}
|
||||
|
||||
getServiceData(regionData): Policy[] {
|
||||
let ServiceData: Policy[] = [];
|
||||
|
||||
this.serviceVMCPUs.map((pcpuID, index) => {
|
||||
if (regionData.processors.indexOf(pcpuID) !== -1) {
|
||||
if (!this.switches.CDP_ENABLED) {
|
||||
ServiceData.push(this.newPolicy(regionData.level, regionData.id, this.serviceVM, index, "Unified", regionData.capacity_mask_length))
|
||||
} else {
|
||||
ServiceData.push(this.newPolicy(regionData.level, regionData.id, this.serviceVM, index, "Code", regionData.capacity_mask_length))
|
||||
ServiceData.push(this.newPolicy(regionData.level, regionData.id, this.serviceVM, index, "Data", regionData.capacity_mask_length))
|
||||
}
|
||||
}
|
||||
})
|
||||
return ServiceData;
|
||||
}
|
||||
|
||||
getVCATData(regionData): Policy[] {
|
||||
let VCATData: Policy[] = [];
|
||||
// VCAT is only available for CPU 0
|
||||
if (this.switches.VCAT_ENABLED && regionData.processors.indexOf(0) !== -1) {
|
||||
this.scenario.vm.map(vmConfig => {
|
||||
if (
|
||||
this.haveCPUAffinity(vmConfig) &&
|
||||
vmConfig.hasOwnProperty('virtual_cat_support') &&
|
||||
vmConfig.virtual_cat_support === "y"
|
||||
) {
|
||||
VCATData.push(
|
||||
this.newPolicy(regionData.level, regionData.id, vmConfig, 0, "Unified", vmConfig.virtual_cat_number)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
_.sortBy(VCATData, ['VM']);
|
||||
return VCATData;
|
||||
}
|
||||
|
||||
private getServiceVM() {
|
||||
let serviceVM = null;
|
||||
this.scenario.vm.map(vmConfig => {
|
||||
if (vmConfig.load_order === 'SERVICE_VM') {
|
||||
serviceVM = vmConfig;
|
||||
}
|
||||
})
|
||||
return serviceVM;
|
||||
}
|
||||
|
||||
private getServiceVMVCPUs() {
|
||||
let serviceVMCPUs = [];
|
||||
if (this.serviceVM !== null) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
this.schemaData.HV.BasicConfigType.definitions.CPUAffinityConfiguration.properties.pcpu_id.enum.map((pcpu_id) => {
|
||||
// if pcpu_id in preLaunchedVMCPUIDs, it's used by pre launched vm, we need skip it
|
||||
if (this.preLaunchedVMCPUs.indexOf(pcpu_id) !== -1) {
|
||||
return;
|
||||
}
|
||||
serviceVMCPUs.push(pcpu_id);
|
||||
})
|
||||
}
|
||||
return serviceVMCPUs;
|
||||
}
|
||||
|
||||
|
||||
private getCATDataFromScenario() {
|
||||
let hv = this.scenario.hv;
|
||||
let scenarioCATData: CATDBRecord[] = []
|
||||
|
||||
// noinspection JSUnresolvedVariable
|
||||
if (
|
||||
hv !== null &&
|
||||
hv.hasOwnProperty('CACHE_ALLOCATION') &&
|
||||
_.isArray(hv.CACHE_ALLOCATION)
|
||||
) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
hv.CACHE_ALLOCATION.map((cache_region) => {
|
||||
if (
|
||||
cache_region.hasOwnProperty('POLICY') &&
|
||||
cache_region.POLICY.length > 0
|
||||
) {
|
||||
cache_region.POLICY.map(policy => {
|
||||
scenarioCATData.push({
|
||||
CACHE_ID: cache_region.id,
|
||||
CACHE_LEVEL: cache_region.level,
|
||||
CLOS_MASK: policy.CLOS_MASK,
|
||||
META: {vmid: this.vmIDs[policy.VM]},
|
||||
TYPE: policy.TYPE,
|
||||
VCPU: policy.VCPU,
|
||||
VM: policy.VM
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
return scenarioCATData
|
||||
}
|
||||
|
||||
private getVMIDs(): { [vmName: string]: vmID } {
|
||||
let vmIDs = {}
|
||||
this.scenario.vm.map(vmConfig => {
|
||||
vmIDs[vmConfig.name] = vmConfig['@id']
|
||||
})
|
||||
return vmIDs
|
||||
}
|
||||
}
|
||||
|
||||
class PythonObject {
|
||||
api(scriptName, output_format, ...params) {
|
||||
// @ts-ignore
|
||||
let pythonFunction = window.pyodide.pyimport(`configurator.pyodide.${scriptName}`);
|
||||
let result = pythonFunction.main(...params);
|
||||
if (output_format === 'json') {
|
||||
|
@ -54,12 +667,14 @@ class PythonObject {
|
|||
|
||||
class Configurator {
|
||||
public pythonObject: PythonObject;
|
||||
public cat: CAT;
|
||||
|
||||
constructor() {
|
||||
this.pythonObject = new PythonObject()
|
||||
this.cat = new CAT()
|
||||
}
|
||||
|
||||
getHistory(historyType: HistoryTypeString): Promise<String[] | []> {
|
||||
getHistory(historyType: HistoryTypes): Promise<String[] | []> {
|
||||
return invoke("get_history", {historyType})
|
||||
.then((historyJsonText) => {
|
||||
if (typeof historyJsonText === "string") {
|
||||
|
@ -69,7 +684,7 @@ class Configurator {
|
|||
})
|
||||
}
|
||||
|
||||
addHistory(historyType: HistoryTypeString, historyPath: String) {
|
||||
addHistory(historyType: HistoryTypes, historyPath: string) {
|
||||
return invoke("add_history", {historyType, historyPath})
|
||||
}
|
||||
|
||||
|
@ -77,44 +692,43 @@ class Configurator {
|
|||
return dialog.open(options)
|
||||
}
|
||||
|
||||
readFile(filePath: String): Promise<String> {
|
||||
readFile(filePath: string): Promise<String> {
|
||||
return invoke("acrn_read", {filePath})
|
||||
}
|
||||
|
||||
writeFile(filePath: String, contents: String) {
|
||||
writeFile(filePath: string, contents: string) {
|
||||
return invoke("acrn_write", {filePath, contents})
|
||||
}
|
||||
|
||||
isFile(filePath: String): Promise<Boolean> {
|
||||
isFile(filePath: string): Promise<Boolean> {
|
||||
return invoke("acrn_is_file", {path: filePath})
|
||||
}
|
||||
|
||||
readDir(path: String, recursive: Boolean) {
|
||||
readDir(path: string, recursive: Boolean) {
|
||||
return invoke('acrn_read_dir', {path, recursive})
|
||||
}
|
||||
|
||||
creatDir(path: String, recursive = true) {
|
||||
creatDir(path: string, recursive = true) {
|
||||
return invoke('acrn_create_dir', {path, recursive})
|
||||
}
|
||||
|
||||
removeDir(path: String) {
|
||||
removeDir(path: string) {
|
||||
return invoke('acrn_remove_dir', {path})
|
||||
}
|
||||
|
||||
removeFile(path: String) {
|
||||
removeFile(path: string) {
|
||||
return invoke('acrn_remove_file', {path})
|
||||
}
|
||||
|
||||
runPython(code: String, isJSON = false): String | Object {
|
||||
// @ts-ignore
|
||||
let result = window.pydoide.runPython(code);
|
||||
runPython(code: string, isJSON = false): string | Object {
|
||||
let result = window.pyodide.runPython(code);
|
||||
if (isJSON) {
|
||||
result = JSON.parse(result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
loadBoard(path: String) {
|
||||
loadBoard(path: string) {
|
||||
return this.readFile(path)
|
||||
.then((fileContent) => {
|
||||
let syntactical_errors = this.pythonObject.validateBoardStructure(fileContent);
|
||||
|
@ -125,7 +739,7 @@ class Configurator {
|
|||
})
|
||||
}
|
||||
|
||||
loadScenario(path: String): Object {
|
||||
loadScenario(path: string): Object {
|
||||
return this.readFile(path).then((fileContent) => {
|
||||
let syntactical_errors = this.pythonObject.validateScenarioStructure(fileContent);
|
||||
if (syntactical_errors !== "") {
|
||||
|
@ -174,11 +788,12 @@ class Configurator {
|
|||
|
||||
convertScenarioToXML(scenarioData: Object) {
|
||||
let json2xml = new JSON2XML();
|
||||
let xml_data = json2xml.convert(scenarioData);
|
||||
return xml_data
|
||||
return json2xml.convert(scenarioData)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let configurator = new Configurator()
|
||||
|
||||
window.configurator = configurator
|
||||
export default configurator
|
||||
|
|
|
@ -192,6 +192,7 @@ export default {
|
|||
this.showFlag = false;
|
||||
this.updateCurrentFormSchema()
|
||||
this.updateCurrentFormData()
|
||||
configurator.cat.scenarioLoaded()
|
||||
},
|
||||
getSchemaData() {
|
||||
return this.schemas
|
||||
|
@ -438,6 +439,8 @@ export default {
|
|||
let totalMsg = msg.length // msg and errMsg must be same length.
|
||||
let needSaveLaunchScript = false
|
||||
|
||||
this.scenario.hv.CACHE_REGION = configurator.cat.getScenarioDataFromCAT()
|
||||
|
||||
let scenarioWithDefaults = this.applyScenarioDefaults(this.scenario)
|
||||
let scenarioXMLData = this.scenarioToXML(scenarioWithDefaults)
|
||||
this.scenario = scenarioWithDefaults
|
||||
|
|
|
@ -56,7 +56,11 @@
|
|||
</b-form-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-4" v-for="CACHE_ALLOCATION in CAT_INFO" v-if="RDT_ENABLED==='y'">
|
||||
<!-- begin CAT Table -->
|
||||
<div class="py-3" v-if="CAT_INFO.errorMsg">
|
||||
{{ CAT_INFO.errorMsg }}
|
||||
</div>
|
||||
<div class="py-4" v-for="CACHE_ALLOCATION in CAT_INFO.regions" v-if="RDT_ENABLED==='y'">
|
||||
<p v-if="CACHE_ALLOCATION.level===3">
|
||||
L3 Cache Allocation Technology
|
||||
<br/>
|
||||
|
@ -67,7 +71,7 @@
|
|||
<div class="d-flex justify-content-between py-2 align-items-center">
|
||||
<text>
|
||||
L{{ CACHE_ALLOCATION.level }} Cache Allocation Technology {{
|
||||
cat_level_region_sum[CACHE_ALLOCATION.level].count > 1 ? ' Module ' + cat_level_region_sum[CACHE_ALLOCATION.level][CACHE_ALLOCATION.id] : ''
|
||||
CAT_INFO.summary[CACHE_ALLOCATION.level].count > 1 ? ' Module ' + CAT_INFO.summary[CACHE_ALLOCATION.level.toString()][CACHE_ALLOCATION.id] : ''
|
||||
}}
|
||||
(requires CPU affinity to cores {{
|
||||
Math.min(...CACHE_ALLOCATION.processors)
|
||||
|
@ -80,14 +84,24 @@
|
|||
<div class="d-flex">
|
||||
<div class="leftTitle">
|
||||
<!--left title-->
|
||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.POLICY">
|
||||
<div v-if="index===0&&CACHE_ALLOCATION.real_time_count>0">Real-time</div>
|
||||
<div v-if="index===CACHE_ALLOCATION.real_time_count&&CACHE_ALLOCATION.cat_count>0">Standard</div>
|
||||
<div v-if="index===CACHE_ALLOCATION.cat_count">Virtual CAT</div>
|
||||
<text v-if="index<CACHE_ALLOCATION.cat_count">
|
||||
<div style="min-height: 36px">
|
||||
<!-- for align right -->
|
||||
</div>
|
||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.RTCore">
|
||||
<div v-if="index===0">Real-time</div>
|
||||
<text>
|
||||
{{ POLICY.VM }} vCPU {{ POLICY.VCPU }}{{ POLICY.TYPE === 'Unified' ? '' : "_" + POLICY.TYPE }}
|
||||
</text>
|
||||
<text v-else>
|
||||
</div>
|
||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.Standard">
|
||||
<div v-if="index===0">Standard</div>
|
||||
<text>
|
||||
{{ POLICY.VM }} vCPU {{ POLICY.VCPU }}{{ POLICY.TYPE === 'Unified' ? '' : "_" + POLICY.TYPE }}
|
||||
</text>
|
||||
</div>
|
||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.VCAT">
|
||||
<div v-if="index===0">Virtual CAT</div>
|
||||
<text>
|
||||
{{ POLICY.VM }}
|
||||
</text>
|
||||
</div>
|
||||
|
@ -103,14 +117,30 @@
|
|||
</div>
|
||||
<div>
|
||||
<!--right table-->
|
||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.POLICY">
|
||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.RTCore">
|
||||
<div class="policyDisabledBlock"
|
||||
v-if="index===CACHE_ALLOCATION.real_time_count && CACHE_ALLOCATION.real_time_count>0"></div>
|
||||
<div class="policyDisabledBlock"
|
||||
v-if="index===CACHE_ALLOCATION.cat_count && CACHE_ALLOCATION.cat_count>0"></div>
|
||||
v-if="index===0"></div>
|
||||
<HexBlockRangeSelector
|
||||
v-model="POLICY.CLOS_MASK"
|
||||
:isVcat="index>=CACHE_ALLOCATION.cat_count"
|
||||
:isVcat="false"
|
||||
:max="CACHE_ALLOCATION.capacity_mask_length"
|
||||
/>
|
||||
</div>
|
||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.Standard">
|
||||
<div class="policyDisabledBlock"
|
||||
v-if="index===0"></div>
|
||||
<HexBlockRangeSelector
|
||||
v-model="POLICY.CLOS_MASK"
|
||||
:isVcat="false"
|
||||
:max="CACHE_ALLOCATION.capacity_mask_length"
|
||||
/>
|
||||
</div>
|
||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.VCAT">
|
||||
<div class="policyDisabledBlock"
|
||||
v-if="index===0"></div>
|
||||
<HexBlockRangeSelector
|
||||
v-model="POLICY.CLOS_MASK"
|
||||
:isVcat="true"
|
||||
:max="CACHE_ALLOCATION.capacity_mask_length"
|
||||
/>
|
||||
</div>
|
||||
|
@ -130,6 +160,7 @@ import _ from "lodash";
|
|||
import {vueUtils, fieldProps} from "@lljj/vue3-form-naive";
|
||||
import HexBlockRangeSelector from "./CAT/HexBlockRangeSelector.vue";
|
||||
import IconInfo from '@lljj/vjsf-utils/icons/IconInfo.vue';
|
||||
import configurator from "../../../../lib/acrn";
|
||||
|
||||
function count(source, target) {
|
||||
return (source.match(new RegExp(target, 'g')) || []).length;
|
||||
|
@ -185,29 +216,9 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
CAT_INFO: {
|
||||
handler(newValue, _) {
|
||||
if (newValue === null) {
|
||||
// set formData CACHE_REGION to null
|
||||
vueUtils.setPathVal(this.rootFormData, this.curNodePath, newValue)
|
||||
return;
|
||||
}
|
||||
let data = [];
|
||||
for (let i = 0; i < newValue.length; i++) {
|
||||
data.push(newValue[i].data)
|
||||
}
|
||||
// set formData CACHE_REGION.CACHE_ALLOCATION to data
|
||||
let CACHE_REGION = {CACHE_ALLOCATION: data}
|
||||
vueUtils.setPathVal(this.rootFormData, this.curNodePath, CACHE_REGION)
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
CAT_INFO: null,
|
||||
cat_level_region_sum: {},
|
||||
CAT_INFO: {errorMsg: null, regions: [], summary: {}},
|
||||
SSRAMInfo: this.rootSchema.definitions['SSRAMInfo'],
|
||||
RDTType: this.rootSchema.definitions['RDTType']
|
||||
}
|
||||
|
@ -302,414 +313,28 @@ export default {
|
|||
return vueUtils.getPathVal(this.rootFormData, path)
|
||||
},
|
||||
setDefaultClosMask(CACHE_REGION) {
|
||||
if (CACHE_REGION.capacity_mask_length < (CACHE_REGION.real_time_count + 1)) {
|
||||
if (CACHE_REGION.data.RTCore.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (CACHE_REGION.capacity_mask_length < (CACHE_REGION.data.RTCore.length + 1)) {
|
||||
alert('Can\'t generate default settings for this region(due to too many realtime cpu)')
|
||||
return;
|
||||
}
|
||||
for (let policyIndex = 0; policyIndex < CACHE_REGION.data.POLICY.length; policyIndex++) {
|
||||
if (policyIndex < CACHE_REGION.real_time_count) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
CACHE_REGION.data.POLICY[policyIndex].CLOS_MASK = '0x' + parseInt(
|
||||
'0'.repeat(policyIndex) + '1' + '0'.repeat(CACHE_REGION.capacity_mask_length - policyIndex - 1),
|
||||
2).toString(16)
|
||||
} else {
|
||||
// noinspection JSUnresolvedVariable
|
||||
CACHE_REGION.data.POLICY[policyIndex].CLOS_MASK = '0x' + parseInt(
|
||||
'0'.repeat(CACHE_REGION.real_time_count) + '1'.repeat(CACHE_REGION.capacity_mask_length - CACHE_REGION.real_time_count),
|
||||
2).toString(16)
|
||||
}
|
||||
for (let policyIndex = 0; policyIndex < CACHE_REGION.data.RTCore.length; policyIndex++) {
|
||||
CACHE_REGION.data.RTCore[policyIndex].CLOS_MASK = '0x' + parseInt(
|
||||
'0'.repeat(policyIndex) + '1' + '0'.repeat(CACHE_REGION.capacity_mask_length - policyIndex - 1),
|
||||
2).toString(16)
|
||||
}
|
||||
|
||||
for (let policyIndex = 0; policyIndex < CACHE_REGION.data.Standard.length; policyIndex++) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
CACHE_REGION.data.Standard[policyIndex].CLOS_MASK = '0x' + parseInt(
|
||||
'0'.repeat(CACHE_REGION.data.RTCore.length) + '1'.repeat(CACHE_REGION.capacity_mask_length - CACHE_REGION.data.RTCore.length),
|
||||
2).toString(16);
|
||||
}
|
||||
},
|
||||
updateCatInfo() {
|
||||
// get settings from formData
|
||||
let RDT_ENABLED = this.RDT_ENABLED === 'y'
|
||||
let CDP_ENABLED = this.CDP_ENABLED === 'y'
|
||||
let VCAT_ENABLED = this.VCAT_ENABLED === 'y'
|
||||
|
||||
if (!RDT_ENABLED) {
|
||||
// keep CAT_INFO
|
||||
return
|
||||
}
|
||||
|
||||
// get vmConfig from formData
|
||||
// let getCPUAffinity = () => {
|
||||
// // vmName: {pcpu_id:0, vcpu_id:0, isRT:false}
|
||||
// let vmCpuAffinity = {};
|
||||
// window.getCurrentScenarioData().vm.map((vmConfig) => {
|
||||
// // if this vm is service vm, skip it
|
||||
// if (vmConfig.load_order === 'SERVICE_VM') {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// })
|
||||
// }
|
||||
|
||||
|
||||
let getCurrentFormDataCPUAffinitySettings = () => {
|
||||
/**
|
||||
* let vCatsExample = [
|
||||
* // VCPU is force set to 0
|
||||
* // CLOS_MASK is force set to width of capacity_mask_length (for vcat only)
|
||||
* {"VM": "VM_C", "VCPU": 0, "CLOS_MASK": 2},
|
||||
* {"VM": "VM_D", "VCPU": 0, "CLOS_MASK": 5},
|
||||
* ]
|
||||
*/
|
||||
let vCats = []
|
||||
/**
|
||||
* get pcpu config from current formData
|
||||
* let pcpu_vms_example = {
|
||||
* 0: {
|
||||
* 'y': [],
|
||||
* 'n': [
|
||||
* {"VM": "POST_VM_1", "VCPU": 0},
|
||||
* {"VM": "POST_VM_2", "VCPU": 2}
|
||||
* ]
|
||||
* },
|
||||
* 1: {
|
||||
* 'y': [
|
||||
* {"VM": "POST_VM_1", "VCPU": 1}
|
||||
* ],
|
||||
* 'n': [
|
||||
* {"VM": "POST_VM_2", "VCPU": 2}
|
||||
* ]
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
let pcpu_vms = {}
|
||||
let serviceVM = null;
|
||||
let preLaunchedVMCPUIDs = [];
|
||||
|
||||
window.getCurrentScenarioData().vm.map((vmConfig) => {
|
||||
// if this vm is service vm, we got it and skip it
|
||||
if (vmConfig.load_order === 'SERVICE_VM') {
|
||||
serviceVM = vmConfig;
|
||||
return;
|
||||
}
|
||||
|
||||
// no cpu affinity, skip it
|
||||
if (
|
||||
!vmConfig.hasOwnProperty('cpu_affinity') ||
|
||||
!vmConfig.cpu_affinity.hasOwnProperty('pcpu') ||
|
||||
!_.isArray(vmConfig.cpu_affinity.pcpu)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
// now, we got pre/post vm config with cpu affinity data here
|
||||
|
||||
if (vmConfig.load_order === 'PRE_LAUNCHED_VM') {
|
||||
preLaunchedVMCPUIDs = preLaunchedVMCPUIDs.concat(vmConfig.cpu_affinity.pcpu)
|
||||
return;
|
||||
}
|
||||
|
||||
// if vcat is enabled in hv, we need to check current vm is enabled vcat
|
||||
// noinspection JSUnresolvedVariable
|
||||
if (
|
||||
VCAT_ENABLED &&
|
||||
vmConfig.hasOwnProperty('virtual_cat_support') &&
|
||||
vmConfig.virtual_cat_support === "y"
|
||||
) {
|
||||
// if enabled vcat in vmConfig, add vm's vcat config to vCats
|
||||
// noinspection JSUnresolvedVariable
|
||||
vCats.push({"VM": vmConfig.name, "VCPU": 0, "CLOS_MASK": vmConfig.virtual_cat_number})
|
||||
// for enabled virtual_cat_support vm, it doesn't need set CAT
|
||||
return;
|
||||
}
|
||||
|
||||
// get cpu affinity settings from pre/post vms which are not enabled vCAT
|
||||
vmConfig.cpu_affinity.pcpu.map((pcpu, index) => {
|
||||
if (!pcpu_vms.hasOwnProperty(pcpu.pcpu_id)) {
|
||||
pcpu_vms[pcpu.pcpu_id] = {'y': [], 'n': []}
|
||||
}
|
||||
pcpu_vms[pcpu.pcpu_id][
|
||||
// old scenario may not have this attr
|
||||
pcpu.real_time_vcpu ?
|
||||
// if it had this attr, use it
|
||||
pcpu.real_time_vcpu :
|
||||
// doesn't have it, auto set to no
|
||||
'n'
|
||||
].push({
|
||||
// '@id': vmConfig['@id'],
|
||||
"VM": vmConfig.name,
|
||||
"VCPU": index,
|
||||
})
|
||||
})
|
||||
})
|
||||
// generate service vm cpu affinity setting
|
||||
if (serviceVM !== null) {
|
||||
let serviceVMCPUIndex = 0;
|
||||
let schemaData = window.getSchemaData()
|
||||
// noinspection JSUnresolvedVariable
|
||||
schemaData.HV.BasicConfigType.definitions.CPUAffinityConfiguration.properties.pcpu_id.enum.map((pcpu_id) => {
|
||||
// if pcpu_id in preLaunchedVMCPUIDs, it's used by pre launched vm, we need skip it
|
||||
if (preLaunchedVMCPUIDs.indexOf(pcpu_id) !== -1) {
|
||||
return;
|
||||
}
|
||||
// noinspection JSCheckFunctionSignatures
|
||||
if (!pcpu_vms.hasOwnProperty(pcpu_id)) {
|
||||
pcpu_vms[pcpu_id] = {'y': [], 'n': []}
|
||||
}
|
||||
pcpu_vms[pcpu_id].n.push({
|
||||
// '@id': serviceVM['@id'],
|
||||
"VM": serviceVM.name,
|
||||
"VCPU": serviceVMCPUIndex
|
||||
})
|
||||
serviceVMCPUIndex++;
|
||||
})
|
||||
}
|
||||
return {
|
||||
vCats: vCats,
|
||||
pcpu_vms: pcpu_vms,
|
||||
serviceVM: serviceVM
|
||||
}
|
||||
}
|
||||
|
||||
let getScenarioCATData = () => {
|
||||
/**
|
||||
* load data from scenario
|
||||
* let scenarioHVCACHE_REGIONData_data_example = {
|
||||
* "CACHE_ALLOCATION": [
|
||||
* {
|
||||
* "CACHE_ID": "0x8", "CACHE_LEVEL": 2, "POLICY": [
|
||||
* {"VM": "POST_RT_VM1", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
||||
* {"VM": "POST_RT_VM1", "VCPU": 1, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
||||
* {"VM": "VM4-RTVM2", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
||||
* {"VM": "VM4-RTVM2", "VCPU": 1, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
||||
* ]
|
||||
* },
|
||||
* {
|
||||
* "CACHE_ID": "0x9", "CACHE_LEVEL": 2, "POLICY": [
|
||||
* {"VM": "VM5-RTVM3", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
||||
* {"VM": "VM5-RTVM3", "VCPU": 1, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
||||
* {"VM": "VM6-RTVM4", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
||||
* {"VM": "VM6-RTVM4", "VCPU": 1, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
||||
* ]
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
let scenarioHVCACHE_REGIONData = vueUtils.getPathVal(this.rootFormData, this.curNodePath);
|
||||
|
||||
/**
|
||||
* let scenario_cat_data_example = {
|
||||
* 2: {
|
||||
* '0x7': {
|
||||
* "CACHE_ID": "0x7", "CACHE_LEVEL": 2, "POLICY": [
|
||||
* {"VM": "POST_RT_VM1", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
||||
* ]
|
||||
* },
|
||||
* '0x8': {
|
||||
* "CACHE_ID": "0x8", "CACHE_LEVEL": 2, "POLICY": [
|
||||
* {"VM": "POST_RT_VM1", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
||||
* ]
|
||||
* }
|
||||
* },
|
||||
* 3: {
|
||||
* '0x0': {}
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
let scenario_cat_data = {}
|
||||
// noinspection JSUnresolvedVariable
|
||||
if (
|
||||
scenarioHVCACHE_REGIONData !== null &&
|
||||
scenarioHVCACHE_REGIONData.hasOwnProperty('CACHE_ALLOCATION') &&
|
||||
_.isArray(scenarioHVCACHE_REGIONData.CACHE_ALLOCATION)
|
||||
) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
scenarioHVCACHE_REGIONData.CACHE_ALLOCATION.map((cache_region) => {
|
||||
if (!scenario_cat_data.hasOwnProperty(cache_region['CACHE_LEVEL'])) {
|
||||
scenario_cat_data[cache_region['CACHE_LEVEL']] = {}
|
||||
}
|
||||
scenario_cat_data[cache_region['CACHE_LEVEL']][cache_region['CACHE_ID']] = cache_region
|
||||
})
|
||||
}
|
||||
return scenario_cat_data
|
||||
}
|
||||
|
||||
|
||||
let mergeAndGenerateData = (currentFormDataCPUAffinitySettings, scenarioCatData) => {
|
||||
|
||||
/**
|
||||
* get CAT info from board xml
|
||||
* let board_cat_info_example = [
|
||||
* {
|
||||
* "id": "0x0", "level": 3, "type": "3", "cache_size": 31457280, "capacity_mask_length": 12,
|
||||
* "processors": [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15]
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
|
||||
/**
|
||||
* let cat_level_region_sum_example = {
|
||||
* 2: {
|
||||
* count: 2,
|
||||
* '0x8': 1,
|
||||
* '0x9': 2
|
||||
* },
|
||||
* 3: {
|
||||
* count: 1,
|
||||
* '0x0': 1
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
let scenario_cat_data = scenarioCatData
|
||||
let {pcpu_vms, vCats} = currentFormDataCPUAffinitySettings;
|
||||
|
||||
this.cat_level_region_sum = {}
|
||||
|
||||
let board_cat_info = _.cloneDeep(window.getBoardData().CAT_INFO);
|
||||
|
||||
board_cat_info.map((
|
||||
cat_region_info
|
||||
) => {
|
||||
|
||||
// count regions for each cat level
|
||||
if (!this.cat_level_region_sum.hasOwnProperty(cat_region_info.level)) {
|
||||
this.cat_level_region_sum[cat_region_info.level] = {count: 0};
|
||||
}
|
||||
this.cat_level_region_sum[cat_region_info.level].count += 1
|
||||
this.cat_level_region_sum[cat_region_info.level][cat_region_info.id] = this.cat_level_region_sum[cat_region_info.level].count;
|
||||
|
||||
/**
|
||||
* get vm cpu clos_mask from scenario
|
||||
* let vmCPUClosMasks_example = {
|
||||
* 'VM_NAME': {
|
||||
* // vcpu_id: {type: clos_mask}
|
||||
* 0: {"Unified": '0xfff'},
|
||||
* 1: {"Code": '0xff0', "Data": '0x00f'} // CDP_ENABLED
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
let vmCPUClosMasks = {}
|
||||
if (
|
||||
scenario_cat_data.hasOwnProperty(cat_region_info.level) &&
|
||||
scenario_cat_data[cat_region_info.level].hasOwnProperty(cat_region_info.id)
|
||||
) {
|
||||
/**
|
||||
* let current_region_scenario_cat_data_example = {
|
||||
* "CACHE_ID": "0x7", "CACHE_LEVEL": 2, "POLICY": [
|
||||
* {"VM": "POST_RT_VM1", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
let current_region_scenario_cat_data = scenario_cat_data[cat_region_info.level][cat_region_info.id];
|
||||
|
||||
for (let i = 0; i < current_region_scenario_cat_data.POLICY.length; i++) {
|
||||
let currentRegionScenarioPolicy = current_region_scenario_cat_data.POLICY[i]
|
||||
if (!vmCPUClosMasks.hasOwnProperty(currentRegionScenarioPolicy.VM)) {
|
||||
vmCPUClosMasks[currentRegionScenarioPolicy.VM] = {}
|
||||
}
|
||||
if (!vmCPUClosMasks[currentRegionScenarioPolicy.VM].hasOwnProperty(currentRegionScenarioPolicy.VCPU)) {
|
||||
vmCPUClosMasks[currentRegionScenarioPolicy.VM][currentRegionScenarioPolicy.VCPU] = {}
|
||||
}
|
||||
if (["Unified", "Code", "Data"].indexOf(currentRegionScenarioPolicy.TYPE) >= 0) {
|
||||
vmCPUClosMasks[currentRegionScenarioPolicy.VM][currentRegionScenarioPolicy.VCPU][currentRegionScenarioPolicy.TYPE] = currentRegionScenarioPolicy.CLOS_MASK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cat_region_info['data'] = {
|
||||
"CACHE_ID": cat_region_info.id,
|
||||
"CACHE_LEVEL": cat_region_info.level,
|
||||
"POLICY": []
|
||||
}
|
||||
|
||||
function addCATPolicy(cpu_policy_line, line_type, vcat_mask_length = null) {
|
||||
let cpu_policy = _.cloneDeep(cpu_policy_line)
|
||||
cpu_policy['TYPE'] = line_type;
|
||||
// noinspection JSUnresolvedVariable
|
||||
let clos_mask = "0x" + parseInt('1'.repeat(
|
||||
// if vcat_mask_length is not null
|
||||
vcat_mask_length !== null ?
|
||||
// filled by vcat_mask_length
|
||||
vcat_mask_length :
|
||||
// filled by capacity_mask_length
|
||||
cat_region_info.capacity_mask_length
|
||||
), 2).toString(16);
|
||||
if (
|
||||
vmCPUClosMasks.hasOwnProperty(cpu_policy.VM) &&
|
||||
vmCPUClosMasks[cpu_policy.VM].hasOwnProperty(cpu_policy.VCPU) &&
|
||||
vmCPUClosMasks[cpu_policy.VM][cpu_policy.VCPU].hasOwnProperty(line_type)
|
||||
) {
|
||||
let scenario_clos_mask = vmCPUClosMasks[cpu_policy.VM][cpu_policy.VCPU][line_type];
|
||||
if (vcat_mask_length === null || count(Number.parseInt(scenario_clos_mask).toString(2), '1') === vcat_mask_length) {
|
||||
clos_mask = scenario_clos_mask
|
||||
}
|
||||
}
|
||||
cpu_policy['CLOS_MASK'] = clos_mask;
|
||||
cat_region_info.data.POLICY.push(cpu_policy)
|
||||
}
|
||||
|
||||
/**
|
||||
* let cpu_policies_example = [
|
||||
* {"VM": "POST_VM_1", "VCPU": 0},
|
||||
* {"VM": "POST_VM_2", "VCPU": 2}
|
||||
* ]
|
||||
*/
|
||||
function addPolicy(cpu_policies) {
|
||||
for (let j = 0; j < cpu_policies.length; j++) {
|
||||
let cpu_policies_line = cpu_policies[j];
|
||||
if (CDP_ENABLED) {
|
||||
addCATPolicy(cpu_policies_line, "Code")
|
||||
addCATPolicy(cpu_policies_line, "Data")
|
||||
} else {
|
||||
addCATPolicy(cpu_policies_line, "Unified")
|
||||
}
|
||||
}
|
||||
return CDP_ENABLED ? 2 * cpu_policies.length : cpu_policies.length
|
||||
}
|
||||
|
||||
// add rt vm policy
|
||||
cat_region_info.real_time_count = 0
|
||||
// noinspection JSUnresolvedVariable
|
||||
for (let i = 0; i < cat_region_info.processors.length; i++) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
let pcpu_id = cat_region_info.processors[i];
|
||||
let cpu_policies = pcpu_vms[pcpu_id] ? pcpu_vms[pcpu_id]['y'] : [];
|
||||
cat_region_info.real_time_count += addPolicy(cpu_policies)
|
||||
}
|
||||
// add std vm policy
|
||||
cat_region_info.cat_count = _.cloneDeep(cat_region_info.real_time_count)
|
||||
// noinspection JSUnresolvedVariable
|
||||
for (let i = 0; i < cat_region_info.processors.length; i++) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
let pcpu_id = cat_region_info.processors[i];
|
||||
let cpu_policies = pcpu_vms[pcpu_id] ? pcpu_vms[pcpu_id]['n'] : [];
|
||||
cat_region_info.cat_count += addPolicy(cpu_policies)
|
||||
}
|
||||
|
||||
// add vcat vm policy
|
||||
// noinspection JSUnresolvedVariable
|
||||
if (cat_region_info.processors.indexOf(0) !== -1) {
|
||||
for (let i = 0; i < vCats.length; i++) {
|
||||
addCATPolicy(vCats[i], 'Unified', vCats[i].CLOS_MASK)
|
||||
}
|
||||
}
|
||||
|
||||
// order policy by @id
|
||||
// cat_region_info.data.POLICY.sort(function (a, b) {
|
||||
// return a['@id'] - b['@id']
|
||||
// });
|
||||
})
|
||||
|
||||
for (let i = 0; i < board_cat_info.length; i++) {
|
||||
if (board_cat_info[i].data.POLICY.length === 0) {
|
||||
board_cat_info.splice(i--, 1)
|
||||
}
|
||||
}
|
||||
return board_cat_info;
|
||||
}
|
||||
|
||||
let generate = () => {
|
||||
let currentFormDataCPUAffinitySettings = getCurrentFormDataCPUAffinitySettings();
|
||||
let scenarioCatData = getScenarioCATData();
|
||||
this.CAT_INFO = mergeAndGenerateData(currentFormDataCPUAffinitySettings, scenarioCatData);
|
||||
}
|
||||
|
||||
|
||||
generate()
|
||||
this.CAT_INFO = configurator.cat.getCATUIData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,20 +6,14 @@
|
|||
|
||||
<script>
|
||||
import Slider from '@vueform/slider'
|
||||
import configurator from '../../../../../lib/acrn'
|
||||
|
||||
function count(source, target) {
|
||||
return (source.match(new RegExp(target, 'g')) || []).length;
|
||||
}
|
||||
|
||||
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
let getHexValue = (value, max) => {
|
||||
let newHexValue = '0'.repeat(value[0]) + '1'.repeat(value[1] - value[0]) + '0'.repeat(max - value[1])
|
||||
newHexValue = (parseInt(newHexValue, 2).toString(16))
|
||||
let zeroPadding = '0'.repeat(Number.parseInt('1'.repeat(max), 2).toString(16).length - newHexValue.length)
|
||||
newHexValue = '0x' + zeroPadding + newHexValue;
|
||||
return newHexValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export default {
|
||||
name: "HexBlockRangeSelector",
|
||||
|
@ -36,32 +30,7 @@ export default {
|
|||
},
|
||||
hexField: {
|
||||
get() {
|
||||
let str_bin = Number.parseInt(this.modelValue).toString(2);
|
||||
let block_length = str_bin.length;
|
||||
let block_enabled_length = count(str_bin, "1");
|
||||
|
||||
let start = 0
|
||||
let end = 0
|
||||
|
||||
if (block_length > this.max) {
|
||||
if (block_enabled_length >= this.max) {
|
||||
str_bin = "1".repeat(this.max);
|
||||
} else {
|
||||
str_bin = "0".repeat(this.max - block_enabled_length) + "1".repeat(block_enabled_length);
|
||||
}
|
||||
} else {
|
||||
if (block_length < this.max) {
|
||||
str_bin = "0".repeat(this.max - block_length) + str_bin;
|
||||
}
|
||||
}
|
||||
|
||||
start = str_bin.indexOf("1") !== -1 ? str_bin.indexOf("1") : 0;
|
||||
end = start + count(str_bin, "1");
|
||||
|
||||
// noinspection UnnecessaryLocalVariableJS
|
||||
let result = [start, end]
|
||||
return result
|
||||
|
||||
return configurator.cat.hexToRange(this.modelValue, this.max)
|
||||
},
|
||||
set(value) {
|
||||
if (value[1] - value[0] === 0) {
|
||||
|
@ -71,7 +40,7 @@ export default {
|
|||
} else {
|
||||
this.lastValue = JSON.parse(JSON.stringify(value))
|
||||
}
|
||||
this.$emit("update:modelValue", getHexValue(value, this.max))
|
||||
this.$emit("update:modelValue", configurator.cat.rangeToHex(value, this.max))
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue