Re: [PATCH RESEND v20 2/8] numa: Extend CLI to provide memory latency and bandwidth information
On Fri, 13 Dec 2019 09:19:23 +0800 Tao Xu wrote: > From: Liu Jingqi > > Add -numa hmat-lb option to provide System Locality Latency and > Bandwidth Information. These memory attributes help to build > System Locality Latency and Bandwidth Information Structure(s) > in ACPI Heterogeneous Memory Attribute Table (HMAT). Before using > hmat-lb option, enable HMAT with -machine hmat=on. > > Acked-by: Markus Armbruster > Signed-off-by: Liu Jingqi > Signed-off-by: Tao Xu Reviewed-by: Igor Mammedov > --- > > Changes in v20: > - Update the QAPI description (Markus) > - Keep base and bitmap unchanged when latency or bandwidth > out of range > > Changes in v19: > - Add description about the machine property 'hmat' in commit > message (Markus) > > Changes in v18: > - Use qapi type uint64 and only nanosecond for latency (Markus) > > Changes in v17: > - Add check when user input latency or bandwidth 0, the > lb_info_provided should also be 0. Because in ACPI 6.3 5.2.27.4, > 0 means the corresponding latency or bandwidth information is > not provided. > - Fix the infinite loop when node->latency is 0. > --- > hw/core/numa.c| 194 ++ > include/sysemu/numa.h | 53 > qapi/machine.json | 93 +++- > qemu-options.hx | 47 +- > 4 files changed, 384 insertions(+), 3 deletions(-) > > diff --git a/hw/core/numa.c b/hw/core/numa.c > index e60da99293..34eb413f5d 100644 > --- a/hw/core/numa.c > +++ b/hw/core/numa.c > @@ -23,6 +23,7 @@ > */ > > #include "qemu/osdep.h" > +#include "qemu/units.h" > #include "sysemu/hostmem.h" > #include "sysemu/numa.h" > #include "sysemu/sysemu.h" > @@ -198,6 +199,186 @@ void parse_numa_distance(MachineState *ms, > NumaDistOptions *dist, Error **errp) > ms->numa_state->have_numa_distance = true; > } > > +void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node, > +Error **errp) > +{ > +int i, first_bit, last_bit; > +uint64_t max_entry, temp_base, bitmap_copy; > +NodeInfo *numa_info = numa_state->nodes; > +HMAT_LB_Info *hmat_lb = > +numa_state->hmat_lb[node->hierarchy][node->data_type]; > +HMAT_LB_Data lb_data = {}; > +HMAT_LB_Data *lb_temp; > + > +/* Error checking */ > +if (node->initiator > numa_state->num_nodes) { > +error_setg(errp, "Invalid initiator=%d, it should be less than %d", > + node->initiator, numa_state->num_nodes); > +return; > +} > +if (node->target > numa_state->num_nodes) { > +error_setg(errp, "Invalid target=%d, it should be less than %d", > + node->target, numa_state->num_nodes); > +return; > +} > +if (!numa_info[node->initiator].has_cpu) { > +error_setg(errp, "Invalid initiator=%d, it isn't an " > + "initiator proximity domain", node->initiator); > +return; > +} > +if (!numa_info[node->target].present) { > +error_setg(errp, "The target=%d should point to an existing node", > + node->target); > +return; > +} > + > +if (!hmat_lb) { > +hmat_lb = g_malloc0(sizeof(*hmat_lb)); > +numa_state->hmat_lb[node->hierarchy][node->data_type] = hmat_lb; > +hmat_lb->list = g_array_new(false, true, sizeof(HMAT_LB_Data)); > +} > +hmat_lb->hierarchy = node->hierarchy; > +hmat_lb->data_type = node->data_type; > +lb_data.initiator = node->initiator; > +lb_data.target = node->target; > + > +if (node->data_type <= HMATLB_DATA_TYPE_WRITE_LATENCY) { > +/* Input latency data */ > + > +if (!node->has_latency) { > +error_setg(errp, "Missing 'latency' option"); > +return; > +} > +if (node->has_bandwidth) { > +error_setg(errp, "Invalid option 'bandwidth' since " > + "the data type is latency"); > +return; > +} > + > +/* Detect duplicate configuration */ > +for (i = 0; i < hmat_lb->list->len; i++) { > +lb_temp = _array_index(hmat_lb->list, HMAT_LB_Data, i); > + > +if (node->initiator == lb_temp->initiator && > +node->target == lb_temp->target) { > +error_setg(errp, "Duplicate configuration of the latency for > " > +"initiator=%d and target=%d", node->initiator, > +node->target); > +return; > +} > +} > + > +hmat_lb->base = hmat_lb->base ? hmat_lb->base : UINT64_MAX; > + > +if (node->latency) { > +/* Calculate the temporary base and compressed latency */ > +max_entry = node->latency; > +temp_base = 1; > +while (QEMU_IS_ALIGNED(max_entry, 10)) { > +max_entry /= 10; > +temp_base *= 10; > +
[PATCH RESEND v20 2/8] numa: Extend CLI to provide memory latency and bandwidth information
From: Liu Jingqi Add -numa hmat-lb option to provide System Locality Latency and Bandwidth Information. These memory attributes help to build System Locality Latency and Bandwidth Information Structure(s) in ACPI Heterogeneous Memory Attribute Table (HMAT). Before using hmat-lb option, enable HMAT with -machine hmat=on. Acked-by: Markus Armbruster Signed-off-by: Liu Jingqi Signed-off-by: Tao Xu --- Changes in v20: - Update the QAPI description (Markus) - Keep base and bitmap unchanged when latency or bandwidth out of range Changes in v19: - Add description about the machine property 'hmat' in commit message (Markus) Changes in v18: - Use qapi type uint64 and only nanosecond for latency (Markus) Changes in v17: - Add check when user input latency or bandwidth 0, the lb_info_provided should also be 0. Because in ACPI 6.3 5.2.27.4, 0 means the corresponding latency or bandwidth information is not provided. - Fix the infinite loop when node->latency is 0. --- hw/core/numa.c| 194 ++ include/sysemu/numa.h | 53 qapi/machine.json | 93 +++- qemu-options.hx | 47 +- 4 files changed, 384 insertions(+), 3 deletions(-) diff --git a/hw/core/numa.c b/hw/core/numa.c index e60da99293..34eb413f5d 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qemu/units.h" #include "sysemu/hostmem.h" #include "sysemu/numa.h" #include "sysemu/sysemu.h" @@ -198,6 +199,186 @@ void parse_numa_distance(MachineState *ms, NumaDistOptions *dist, Error **errp) ms->numa_state->have_numa_distance = true; } +void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node, +Error **errp) +{ +int i, first_bit, last_bit; +uint64_t max_entry, temp_base, bitmap_copy; +NodeInfo *numa_info = numa_state->nodes; +HMAT_LB_Info *hmat_lb = +numa_state->hmat_lb[node->hierarchy][node->data_type]; +HMAT_LB_Data lb_data = {}; +HMAT_LB_Data *lb_temp; + +/* Error checking */ +if (node->initiator > numa_state->num_nodes) { +error_setg(errp, "Invalid initiator=%d, it should be less than %d", + node->initiator, numa_state->num_nodes); +return; +} +if (node->target > numa_state->num_nodes) { +error_setg(errp, "Invalid target=%d, it should be less than %d", + node->target, numa_state->num_nodes); +return; +} +if (!numa_info[node->initiator].has_cpu) { +error_setg(errp, "Invalid initiator=%d, it isn't an " + "initiator proximity domain", node->initiator); +return; +} +if (!numa_info[node->target].present) { +error_setg(errp, "The target=%d should point to an existing node", + node->target); +return; +} + +if (!hmat_lb) { +hmat_lb = g_malloc0(sizeof(*hmat_lb)); +numa_state->hmat_lb[node->hierarchy][node->data_type] = hmat_lb; +hmat_lb->list = g_array_new(false, true, sizeof(HMAT_LB_Data)); +} +hmat_lb->hierarchy = node->hierarchy; +hmat_lb->data_type = node->data_type; +lb_data.initiator = node->initiator; +lb_data.target = node->target; + +if (node->data_type <= HMATLB_DATA_TYPE_WRITE_LATENCY) { +/* Input latency data */ + +if (!node->has_latency) { +error_setg(errp, "Missing 'latency' option"); +return; +} +if (node->has_bandwidth) { +error_setg(errp, "Invalid option 'bandwidth' since " + "the data type is latency"); +return; +} + +/* Detect duplicate configuration */ +for (i = 0; i < hmat_lb->list->len; i++) { +lb_temp = _array_index(hmat_lb->list, HMAT_LB_Data, i); + +if (node->initiator == lb_temp->initiator && +node->target == lb_temp->target) { +error_setg(errp, "Duplicate configuration of the latency for " +"initiator=%d and target=%d", node->initiator, +node->target); +return; +} +} + +hmat_lb->base = hmat_lb->base ? hmat_lb->base : UINT64_MAX; + +if (node->latency) { +/* Calculate the temporary base and compressed latency */ +max_entry = node->latency; +temp_base = 1; +while (QEMU_IS_ALIGNED(max_entry, 10)) { +max_entry /= 10; +temp_base *= 10; +} + +/* Calculate the max compressed latency */ +temp_base = MIN(hmat_lb->base, temp_base); +max_entry = node->latency / hmat_lb->base; +max_entry = MAX(hmat_lb->range_bitmap, max_entry); + +/* + * For latency hmat_lb->range_bitmap record the max compressed + *