dpdk/lib/eal/common/eal_common_interrupts.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(C) 2021 Marvell.
   3 */
   4
   5#include <stdlib.h>
   6#include <string.h>
   7
   8#include <rte_errno.h>
   9#include <rte_interrupts.h>
  10#include <rte_log.h>
  11#include <rte_malloc.h>
  12
  13#include "eal_interrupts.h"
  14
  15/* Macros to check for valid interrupt handle */
  16#define CHECK_VALID_INTR_HANDLE(intr_handle) do { \
  17        if (intr_handle == NULL) { \
  18                RTE_LOG(DEBUG, EAL, "Interrupt instance unallocated\n"); \
  19                rte_errno = EINVAL; \
  20                goto fail; \
  21        } \
  22} while (0)
  23
  24#define RTE_INTR_INSTANCE_KNOWN_FLAGS (RTE_INTR_INSTANCE_F_PRIVATE \
  25        | RTE_INTR_INSTANCE_F_SHARED \
  26        )
  27
  28#define RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags) \
  29        (!!(flags & RTE_INTR_INSTANCE_F_SHARED))
  30
  31struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags)
  32{
  33        struct rte_intr_handle *intr_handle;
  34        bool uses_rte_memory;
  35
  36        /* Check the flag passed by user, it should be part of the
  37         * defined flags.
  38         */
  39        if ((flags & ~RTE_INTR_INSTANCE_KNOWN_FLAGS) != 0) {
  40                RTE_LOG(DEBUG, EAL, "Invalid alloc flag passed 0x%x\n", flags);
  41                rte_errno = EINVAL;
  42                return NULL;
  43        }
  44
  45        uses_rte_memory = RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags);
  46        if (uses_rte_memory)
  47                intr_handle = rte_zmalloc(NULL, sizeof(*intr_handle), 0);
  48        else
  49                intr_handle = calloc(1, sizeof(*intr_handle));
  50        if (intr_handle == NULL) {
  51                RTE_LOG(ERR, EAL, "Failed to allocate intr_handle\n");
  52                rte_errno = ENOMEM;
  53                return NULL;
  54        }
  55
  56        if (uses_rte_memory) {
  57                intr_handle->efds = rte_zmalloc(NULL,
  58                        RTE_MAX_RXTX_INTR_VEC_ID * sizeof(int), 0);
  59        } else {
  60                intr_handle->efds = calloc(RTE_MAX_RXTX_INTR_VEC_ID,
  61                        sizeof(int));
  62        }
  63        if (intr_handle->efds == NULL) {
  64                RTE_LOG(ERR, EAL, "Fail to allocate event fd list\n");
  65                rte_errno = ENOMEM;
  66                goto fail;
  67        }
  68
  69        if (uses_rte_memory) {
  70                intr_handle->elist = rte_zmalloc(NULL,
  71                        RTE_MAX_RXTX_INTR_VEC_ID * sizeof(struct rte_epoll_event),
  72                        0);
  73        } else {
  74                intr_handle->elist = calloc(RTE_MAX_RXTX_INTR_VEC_ID,
  75                        sizeof(struct rte_epoll_event));
  76        }
  77        if (intr_handle->elist == NULL) {
  78                RTE_LOG(ERR, EAL, "fail to allocate event fd list\n");
  79                rte_errno = ENOMEM;
  80                goto fail;
  81        }
  82
  83        intr_handle->alloc_flags = flags;
  84        intr_handle->nb_intr = RTE_MAX_RXTX_INTR_VEC_ID;
  85
  86        return intr_handle;
  87fail:
  88        if (uses_rte_memory) {
  89                rte_free(intr_handle->efds);
  90                rte_free(intr_handle);
  91        } else {
  92                free(intr_handle->efds);
  93                free(intr_handle);
  94        }
  95        return NULL;
  96}
  97
  98struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src)
  99{
 100        struct rte_intr_handle *intr_handle;
 101
 102        if (src == NULL) {
 103                RTE_LOG(DEBUG, EAL, "Source interrupt instance unallocated\n");
 104                rte_errno = EINVAL;
 105                return NULL;
 106        }
 107
 108        intr_handle = rte_intr_instance_alloc(src->alloc_flags);
 109        if (intr_handle != NULL) {
 110                intr_handle->fd = src->fd;
 111                intr_handle->dev_fd = src->dev_fd;
 112                intr_handle->type = src->type;
 113                intr_handle->max_intr = src->max_intr;
 114                intr_handle->nb_efd = src->nb_efd;
 115                intr_handle->efd_counter_size = src->efd_counter_size;
 116                memcpy(intr_handle->efds, src->efds, src->nb_intr);
 117                memcpy(intr_handle->elist, src->elist, src->nb_intr);
 118        }
 119
 120        return intr_handle;
 121}
 122
 123int rte_intr_event_list_update(struct rte_intr_handle *intr_handle, int size)
 124{
 125        struct rte_epoll_event *tmp_elist;
 126        bool uses_rte_memory;
 127        int *tmp_efds;
 128
 129        CHECK_VALID_INTR_HANDLE(intr_handle);
 130
 131        if (size == 0) {
 132                RTE_LOG(DEBUG, EAL, "Size can't be zero\n");
 133                rte_errno = EINVAL;
 134                goto fail;
 135        }
 136
 137        uses_rte_memory =
 138                RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags);
 139        if (uses_rte_memory) {
 140                tmp_efds = rte_realloc(intr_handle->efds, size * sizeof(int),
 141                        0);
 142        } else {
 143                tmp_efds = realloc(intr_handle->efds, size * sizeof(int));
 144        }
 145        if (tmp_efds == NULL) {
 146                RTE_LOG(ERR, EAL, "Failed to realloc the efds list\n");
 147                rte_errno = ENOMEM;
 148                goto fail;
 149        }
 150        intr_handle->efds = tmp_efds;
 151
 152        if (uses_rte_memory) {
 153                tmp_elist = rte_realloc(intr_handle->elist,
 154                        size * sizeof(struct rte_epoll_event), 0);
 155        } else {
 156                tmp_elist = realloc(intr_handle->elist,
 157                        size * sizeof(struct rte_epoll_event));
 158        }
 159        if (tmp_elist == NULL) {
 160                RTE_LOG(ERR, EAL, "Failed to realloc the event list\n");
 161                rte_errno = ENOMEM;
 162                goto fail;
 163        }
 164        intr_handle->elist = tmp_elist;
 165
 166        intr_handle->nb_intr = size;
 167
 168        return 0;
 169fail:
 170        return -rte_errno;
 171}
 172
 173void rte_intr_instance_free(struct rte_intr_handle *intr_handle)
 174{
 175        if (intr_handle == NULL)
 176                return;
 177        if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) {
 178                rte_free(intr_handle->efds);
 179                rte_free(intr_handle->elist);
 180                rte_free(intr_handle);
 181        } else {
 182                free(intr_handle->efds);
 183                free(intr_handle->elist);
 184                free(intr_handle);
 185        }
 186}
 187
 188int rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd)
 189{
 190        CHECK_VALID_INTR_HANDLE(intr_handle);
 191
 192        intr_handle->fd = fd;
 193
 194        return 0;
 195fail:
 196        return -rte_errno;
 197}
 198
 199int rte_intr_fd_get(const struct rte_intr_handle *intr_handle)
 200{
 201        CHECK_VALID_INTR_HANDLE(intr_handle);
 202
 203        return intr_handle->fd;
 204fail:
 205        return -1;
 206}
 207
 208int rte_intr_type_set(struct rte_intr_handle *intr_handle,
 209        enum rte_intr_handle_type type)
 210{
 211        CHECK_VALID_INTR_HANDLE(intr_handle);
 212
 213        intr_handle->type = type;
 214
 215        return 0;
 216fail:
 217        return -rte_errno;
 218}
 219
 220enum rte_intr_handle_type rte_intr_type_get(
 221        const struct rte_intr_handle *intr_handle)
 222{
 223        CHECK_VALID_INTR_HANDLE(intr_handle);
 224
 225        return intr_handle->type;
 226fail:
 227        return RTE_INTR_HANDLE_UNKNOWN;
 228}
 229
 230int rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd)
 231{
 232        CHECK_VALID_INTR_HANDLE(intr_handle);
 233
 234        intr_handle->dev_fd = fd;
 235
 236        return 0;
 237fail:
 238        return -rte_errno;
 239}
 240
 241int rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle)
 242{
 243        CHECK_VALID_INTR_HANDLE(intr_handle);
 244
 245        return intr_handle->dev_fd;
 246fail:
 247        return -1;
 248}
 249
 250int rte_intr_max_intr_set(struct rte_intr_handle *intr_handle,
 251                                 int max_intr)
 252{
 253        CHECK_VALID_INTR_HANDLE(intr_handle);
 254
 255        if (max_intr > intr_handle->nb_intr) {
 256                RTE_LOG(DEBUG, EAL, "Maximum interrupt vector ID (%d) exceeds "
 257                        "the number of available events (%d)\n", max_intr,
 258                        intr_handle->nb_intr);
 259                rte_errno = ERANGE;
 260                goto fail;
 261        }
 262
 263        intr_handle->max_intr = max_intr;
 264
 265        return 0;
 266fail:
 267        return -rte_errno;
 268}
 269
 270int rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle)
 271{
 272        CHECK_VALID_INTR_HANDLE(intr_handle);
 273
 274        return intr_handle->max_intr;
 275fail:
 276        return -rte_errno;
 277}
 278
 279int rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd)
 280{
 281        CHECK_VALID_INTR_HANDLE(intr_handle);
 282
 283        intr_handle->nb_efd = nb_efd;
 284
 285        return 0;
 286fail:
 287        return -rte_errno;
 288}
 289
 290int rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle)
 291{
 292        CHECK_VALID_INTR_HANDLE(intr_handle);
 293
 294        return intr_handle->nb_efd;
 295fail:
 296        return -rte_errno;
 297}
 298
 299int rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle)
 300{
 301        CHECK_VALID_INTR_HANDLE(intr_handle);
 302
 303        return intr_handle->nb_intr;
 304fail:
 305        return -rte_errno;
 306}
 307
 308int rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle,
 309        uint8_t efd_counter_size)
 310{
 311        CHECK_VALID_INTR_HANDLE(intr_handle);
 312
 313        intr_handle->efd_counter_size = efd_counter_size;
 314
 315        return 0;
 316fail:
 317        return -rte_errno;
 318}
 319
 320int rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle)
 321{
 322        CHECK_VALID_INTR_HANDLE(intr_handle);
 323
 324        return intr_handle->efd_counter_size;
 325fail:
 326        return -rte_errno;
 327}
 328
 329int rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle,
 330        int index)
 331{
 332        CHECK_VALID_INTR_HANDLE(intr_handle);
 333
 334        if (index >= intr_handle->nb_intr) {
 335                RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
 336                        intr_handle->nb_intr);
 337                rte_errno = EINVAL;
 338                goto fail;
 339        }
 340
 341        return intr_handle->efds[index];
 342fail:
 343        return -rte_errno;
 344}
 345
 346int rte_intr_efds_index_set(struct rte_intr_handle *intr_handle,
 347        int index, int fd)
 348{
 349        CHECK_VALID_INTR_HANDLE(intr_handle);
 350
 351        if (index >= intr_handle->nb_intr) {
 352                RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
 353                        intr_handle->nb_intr);
 354                rte_errno = ERANGE;
 355                goto fail;
 356        }
 357
 358        intr_handle->efds[index] = fd;
 359
 360        return 0;
 361fail:
 362        return -rte_errno;
 363}
 364
 365struct rte_epoll_event *rte_intr_elist_index_get(
 366        struct rte_intr_handle *intr_handle, int index)
 367{
 368        CHECK_VALID_INTR_HANDLE(intr_handle);
 369
 370        if (index >= intr_handle->nb_intr) {
 371                RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
 372                        intr_handle->nb_intr);
 373                rte_errno = ERANGE;
 374                goto fail;
 375        }
 376
 377        return &intr_handle->elist[index];
 378fail:
 379        return NULL;
 380}
 381
 382int rte_intr_elist_index_set(struct rte_intr_handle *intr_handle,
 383        int index, struct rte_epoll_event elist)
 384{
 385        CHECK_VALID_INTR_HANDLE(intr_handle);
 386
 387        if (index >= intr_handle->nb_intr) {
 388                RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
 389                        intr_handle->nb_intr);
 390                rte_errno = ERANGE;
 391                goto fail;
 392        }
 393
 394        intr_handle->elist[index] = elist;
 395
 396        return 0;
 397fail:
 398        return -rte_errno;
 399}
 400
 401int rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle,
 402        const char *name, int size)
 403{
 404        CHECK_VALID_INTR_HANDLE(intr_handle);
 405
 406        /* Vector list already allocated */
 407        if (intr_handle->intr_vec != NULL)
 408                return 0;
 409
 410        if (size > intr_handle->nb_intr) {
 411                RTE_LOG(DEBUG, EAL, "Invalid size %d, max limit %d\n", size,
 412                        intr_handle->nb_intr);
 413                rte_errno = ERANGE;
 414                goto fail;
 415        }
 416
 417        if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
 418                intr_handle->intr_vec = rte_zmalloc(name, size * sizeof(int), 0);
 419        else
 420                intr_handle->intr_vec = calloc(size, sizeof(int));
 421        if (intr_handle->intr_vec == NULL) {
 422                RTE_LOG(ERR, EAL, "Failed to allocate %d intr_vec\n", size);
 423                rte_errno = ENOMEM;
 424                goto fail;
 425        }
 426
 427        intr_handle->vec_list_size = size;
 428
 429        return 0;
 430fail:
 431        return -rte_errno;
 432}
 433
 434int rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle,
 435                                int index)
 436{
 437        CHECK_VALID_INTR_HANDLE(intr_handle);
 438
 439        if (index >= intr_handle->vec_list_size) {
 440                RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n",
 441                        index, intr_handle->vec_list_size);
 442                rte_errno = ERANGE;
 443                goto fail;
 444        }
 445
 446        return intr_handle->intr_vec[index];
 447fail:
 448        return -rte_errno;
 449}
 450
 451int rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle,
 452                                int index, int vec)
 453{
 454        CHECK_VALID_INTR_HANDLE(intr_handle);
 455
 456        if (index >= intr_handle->vec_list_size) {
 457                RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n",
 458                        index, intr_handle->vec_list_size);
 459                rte_errno = ERANGE;
 460                goto fail;
 461        }
 462
 463        intr_handle->intr_vec[index] = vec;
 464
 465        return 0;
 466fail:
 467        return -rte_errno;
 468}
 469
 470void rte_intr_vec_list_free(struct rte_intr_handle *intr_handle)
 471{
 472        if (intr_handle == NULL)
 473                return;
 474        if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
 475                rte_free(intr_handle->intr_vec);
 476        else
 477                free(intr_handle->intr_vec);
 478        intr_handle->intr_vec = NULL;
 479        intr_handle->vec_list_size = 0;
 480}
 481
 482void *rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle)
 483{
 484        CHECK_VALID_INTR_HANDLE(intr_handle);
 485
 486        return intr_handle->windows_handle;
 487fail:
 488        return NULL;
 489}
 490
 491int rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle,
 492        void *windows_handle)
 493{
 494        CHECK_VALID_INTR_HANDLE(intr_handle);
 495
 496        intr_handle->windows_handle = windows_handle;
 497
 498        return 0;
 499fail:
 500        return -rte_errno;
 501}
 502