return spapr->FORM1_assoc_array[node_id];
}
+/*
+ * Wrapper that returns node distance from ms->numa_state->nodes
+ * after handling edge cases where the distance might be absent.
+ */
+static int get_numa_distance(MachineState *ms, int src, int dst)
+{
+ NodeInfo *numa_info = ms->numa_state->nodes;
+ int ret = numa_info[src].distance[dst];
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ /*
+ * In case QEMU adds a default NUMA single node when the user
+ * did not add any, or where the user did not supply distances,
+ * the distance will be absent (zero). Return local/remote
+ * distance in this case.
+ */
+ if (src == dst) {
+ return NUMA_DISTANCE_MIN;
+ }
+
+ return NUMA_DISTANCE_DEFAULT;
+}
+
static bool spapr_numa_is_symmetrical(MachineState *ms)
{
- int src, dst;
int nb_numa_nodes = ms->numa_state->num_nodes;
- NodeInfo *numa_info = ms->numa_state->nodes;
+ int src, dst;
for (src = 0; src < nb_numa_nodes; src++) {
for (dst = src; dst < nb_numa_nodes; dst++) {
- if (numa_info[src].distance[dst] !=
- numa_info[dst].distance[src]) {
+ if (get_numa_distance(ms, src, dst) !=
+ get_numa_distance(ms, dst, src)) {
return false;
}
}
static void spapr_numa_define_FORM1_domains(SpaprMachineState *spapr)
{
MachineState *ms = MACHINE(spapr);
- NodeInfo *numa_info = ms->numa_state->nodes;
int nb_numa_nodes = ms->numa_state->num_nodes;
int src, dst, i, j;
* The PPC kernel expects the associativity domains of node 0 to
* be always 0, and this algorithm will grant that by default.
*/
- uint8_t distance = numa_info[src].distance[dst];
+ uint8_t distance = get_numa_distance(ms, src, dst);
uint8_t n_level = spapr_numa_get_numa_level(distance);
uint32_t assoc_src;
void *fdt, int rtas)
{
MachineState *ms = MACHINE(spapr);
- NodeInfo *numa_info = ms->numa_state->nodes;
int nb_numa_nodes = ms->numa_state->num_nodes;
int distance_table_entries = nb_numa_nodes * nb_numa_nodes;
g_autofree uint32_t *lookup_index_table = NULL;
for (src = 0; src < nb_numa_nodes; src++) {
for (dst = 0; dst < nb_numa_nodes; dst++) {
- /*
- * We need to be explicit with the local distance
- * value to cover the case where the user didn't added any
- * NUMA nodes, but QEMU adds the default NUMA node without
- * adding the numa_info to retrieve distance info from.
- */
- distance_table[i] = numa_info[src].distance[dst];
- if (distance_table[i] == 0) {
- /*
- * In case QEMU adds a default NUMA single node when the user
- * did not add any, or where the user did not supply distances,
- * the value will be 0 here. Populate the table with a fallback
- * simple local / remote distance.
- */
- if (src == dst) {
- distance_table[i] = NUMA_DISTANCE_MIN;
- } else {
- distance_table[i] = numa_info[src].distance[dst];
- if (distance_table[i] < NUMA_DISTANCE_MIN) {
- distance_table[i] = NUMA_DISTANCE_DEFAULT;
- }
- }
- }
- i++;
+ distance_table[i++] = get_numa_distance(ms, src, dst);
}
}