dpdk/lib/eal/windows/eal_lcore.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2019 Intel Corporation
   3 */
   4
   5#include <pthread.h>
   6#include <stdbool.h>
   7#include <stdint.h>
   8
   9#include <rte_common.h>
  10#include <rte_debug.h>
  11#include <rte_lcore.h>
  12
  13#include "eal_private.h"
  14#include "eal_thread.h"
  15#include "eal_windows.h"
  16
  17/** Number of logical processors (cores) in a processor group (32 or 64). */
  18#define EAL_PROCESSOR_GROUP_SIZE (sizeof(KAFFINITY) * CHAR_BIT)
  19
  20struct lcore_map {
  21        uint8_t socket_id;
  22        uint8_t core_id;
  23};
  24
  25struct socket_map {
  26        uint16_t node_id;
  27};
  28
  29struct cpu_map {
  30        unsigned int socket_count;
  31        unsigned int lcore_count;
  32        struct lcore_map lcores[RTE_MAX_LCORE];
  33        struct socket_map sockets[RTE_MAX_NUMA_NODES];
  34};
  35
  36static struct cpu_map cpu_map = { 0 };
  37
  38/* eal_create_cpu_map() is called before logging is initialized */
  39static void
  40__rte_format_printf(1, 2)
  41log_early(const char *format, ...)
  42{
  43        va_list va;
  44
  45        va_start(va, format);
  46        vfprintf(stderr, format, va);
  47        va_end(va);
  48}
  49
  50int
  51eal_create_cpu_map(void)
  52{
  53        SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infos, *info;
  54        DWORD infos_size;
  55        bool full = false;
  56
  57        infos_size = 0;
  58        if (!GetLogicalProcessorInformationEx(
  59                        RelationNumaNode, NULL, &infos_size)) {
  60                DWORD error = GetLastError();
  61                if (error != ERROR_INSUFFICIENT_BUFFER) {
  62                        log_early("Cannot get NUMA node info size, error %lu\n",
  63                                GetLastError());
  64                        rte_errno = ENOMEM;
  65                        return -1;
  66                }
  67        }
  68
  69        infos = malloc(infos_size);
  70        if (infos == NULL) {
  71                log_early("Cannot allocate memory for NUMA node information\n");
  72                rte_errno = ENOMEM;
  73                return -1;
  74        }
  75
  76        if (!GetLogicalProcessorInformationEx(
  77                        RelationNumaNode, infos, &infos_size)) {
  78                log_early("Cannot get NUMA node information, error %lu\n",
  79                        GetLastError());
  80                rte_errno = EINVAL;
  81                return -1;
  82        }
  83
  84        info = infos;
  85        while ((uint8_t *)info - (uint8_t *)infos < infos_size) {
  86                unsigned int node_id = info->NumaNode.NodeNumber;
  87                GROUP_AFFINITY *cores = &info->NumaNode.GroupMask;
  88                struct lcore_map *lcore;
  89                unsigned int i, socket_id;
  90
  91                /* NUMA node may be reported multiple times if it includes
  92                 * cores from different processor groups, e. g. 80 cores
  93                 * of a physical processor comprise one NUMA node, but two
  94                 * processor groups, because group size is limited by 32/64.
  95                 */
  96                for (socket_id = 0; socket_id < cpu_map.socket_count;
  97                    socket_id++) {
  98                        if (cpu_map.sockets[socket_id].node_id == node_id)
  99                                break;
 100                }
 101
 102                if (socket_id == cpu_map.socket_count) {
 103                        if (socket_id == RTE_DIM(cpu_map.sockets)) {
 104                                full = true;
 105                                goto exit;
 106                        }
 107
 108                        cpu_map.sockets[socket_id].node_id = node_id;
 109                        cpu_map.socket_count++;
 110                }
 111
 112                for (i = 0; i < EAL_PROCESSOR_GROUP_SIZE; i++) {
 113                        if ((cores->Mask & ((KAFFINITY)1 << i)) == 0)
 114                                continue;
 115
 116                        if (cpu_map.lcore_count == RTE_DIM(cpu_map.lcores)) {
 117                                full = true;
 118                                goto exit;
 119                        }
 120
 121                        lcore = &cpu_map.lcores[cpu_map.lcore_count];
 122                        lcore->socket_id = socket_id;
 123                        lcore->core_id =
 124                                cores->Group * EAL_PROCESSOR_GROUP_SIZE + i;
 125                        cpu_map.lcore_count++;
 126                }
 127
 128                info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(
 129                        (uint8_t *)info + info->Size);
 130        }
 131
 132exit:
 133        if (full) {
 134                /* Not a fatal error, but important for troubleshooting. */
 135                log_early("Enumerated maximum of %u NUMA nodes and %u cores\n",
 136                        cpu_map.socket_count, cpu_map.lcore_count);
 137        }
 138
 139        free(infos);
 140
 141        return 0;
 142}
 143
 144int
 145eal_cpu_detected(unsigned int lcore_id)
 146{
 147        return lcore_id < cpu_map.lcore_count;
 148}
 149
 150unsigned
 151eal_cpu_socket_id(unsigned int lcore_id)
 152{
 153        return cpu_map.lcores[lcore_id].socket_id;
 154}
 155
 156unsigned
 157eal_cpu_core_id(unsigned int lcore_id)
 158{
 159        return cpu_map.lcores[lcore_id].core_id;
 160}
 161
 162unsigned int
 163eal_socket_numa_node(unsigned int socket_id)
 164{
 165        return cpu_map.sockets[socket_id].node_id;
 166}
 167