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 /* Macros to check for valid interrupt handle */ 14 #define CHECK_VALID_INTR_HANDLE(intr_handle) do { \ 15 if (intr_handle == NULL) { \ 16 RTE_LOG(DEBUG, EAL, "Interrupt instance unallocated\n"); \ 17 rte_errno = EINVAL; \ 18 goto fail; \ 19 } \ 20 } while (0) 21 22 #define RTE_INTR_INSTANCE_KNOWN_FLAGS (RTE_INTR_INSTANCE_F_PRIVATE \ 23 | RTE_INTR_INSTANCE_F_SHARED \ 24 ) 25 26 #define RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags) \ 27 (!!(flags & RTE_INTR_INSTANCE_F_SHARED)) 28 29 struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags) 30 { 31 struct rte_intr_handle *intr_handle; 32 bool uses_rte_memory; 33 34 /* Check the flag passed by user, it should be part of the 35 * defined flags. 36 */ 37 if ((flags & ~RTE_INTR_INSTANCE_KNOWN_FLAGS) != 0) { 38 RTE_LOG(DEBUG, EAL, "Invalid alloc flag passed 0x%x\n", flags); 39 rte_errno = EINVAL; 40 return NULL; 41 } 42 43 uses_rte_memory = RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags); 44 if (uses_rte_memory) 45 intr_handle = rte_zmalloc(NULL, sizeof(*intr_handle), 0); 46 else 47 intr_handle = calloc(1, sizeof(*intr_handle)); 48 if (intr_handle == NULL) { 49 RTE_LOG(ERR, EAL, "Failed to allocate intr_handle\n"); 50 rte_errno = ENOMEM; 51 return NULL; 52 } 53 54 intr_handle->alloc_flags = flags; 55 intr_handle->nb_intr = RTE_MAX_RXTX_INTR_VEC_ID; 56 57 return intr_handle; 58 } 59 60 struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src) 61 { 62 struct rte_intr_handle *intr_handle; 63 64 if (src == NULL) { 65 RTE_LOG(DEBUG, EAL, "Source interrupt instance unallocated\n"); 66 rte_errno = EINVAL; 67 return NULL; 68 } 69 70 intr_handle = rte_intr_instance_alloc(src->alloc_flags); 71 if (intr_handle != NULL) { 72 intr_handle->fd = src->fd; 73 intr_handle->vfio_dev_fd = src->vfio_dev_fd; 74 intr_handle->type = src->type; 75 intr_handle->max_intr = src->max_intr; 76 intr_handle->nb_efd = src->nb_efd; 77 intr_handle->efd_counter_size = src->efd_counter_size; 78 memcpy(intr_handle->efds, src->efds, src->nb_intr); 79 memcpy(intr_handle->elist, src->elist, src->nb_intr); 80 } 81 82 return intr_handle; 83 } 84 85 void rte_intr_instance_free(struct rte_intr_handle *intr_handle) 86 { 87 if (intr_handle == NULL) 88 return; 89 if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) 90 rte_free(intr_handle); 91 else 92 free(intr_handle); 93 } 94 95 int rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd) 96 { 97 CHECK_VALID_INTR_HANDLE(intr_handle); 98 99 intr_handle->fd = fd; 100 101 return 0; 102 fail: 103 return -rte_errno; 104 } 105 106 int rte_intr_fd_get(const struct rte_intr_handle *intr_handle) 107 { 108 CHECK_VALID_INTR_HANDLE(intr_handle); 109 110 return intr_handle->fd; 111 fail: 112 return -1; 113 } 114 115 int rte_intr_type_set(struct rte_intr_handle *intr_handle, 116 enum rte_intr_handle_type type) 117 { 118 CHECK_VALID_INTR_HANDLE(intr_handle); 119 120 intr_handle->type = type; 121 122 return 0; 123 fail: 124 return -rte_errno; 125 } 126 127 enum rte_intr_handle_type rte_intr_type_get( 128 const struct rte_intr_handle *intr_handle) 129 { 130 CHECK_VALID_INTR_HANDLE(intr_handle); 131 132 return intr_handle->type; 133 fail: 134 return RTE_INTR_HANDLE_UNKNOWN; 135 } 136 137 int rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd) 138 { 139 CHECK_VALID_INTR_HANDLE(intr_handle); 140 141 intr_handle->vfio_dev_fd = fd; 142 143 return 0; 144 fail: 145 return -rte_errno; 146 } 147 148 int rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle) 149 { 150 CHECK_VALID_INTR_HANDLE(intr_handle); 151 152 return intr_handle->vfio_dev_fd; 153 fail: 154 return -1; 155 } 156 157 int rte_intr_max_intr_set(struct rte_intr_handle *intr_handle, 158 int max_intr) 159 { 160 CHECK_VALID_INTR_HANDLE(intr_handle); 161 162 if (max_intr > intr_handle->nb_intr) { 163 RTE_LOG(DEBUG, EAL, "Maximum interrupt vector ID (%d) exceeds " 164 "the number of available events (%d)\n", max_intr, 165 intr_handle->nb_intr); 166 rte_errno = ERANGE; 167 goto fail; 168 } 169 170 intr_handle->max_intr = max_intr; 171 172 return 0; 173 fail: 174 return -rte_errno; 175 } 176 177 int rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle) 178 { 179 CHECK_VALID_INTR_HANDLE(intr_handle); 180 181 return intr_handle->max_intr; 182 fail: 183 return -rte_errno; 184 } 185 186 int rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd) 187 { 188 CHECK_VALID_INTR_HANDLE(intr_handle); 189 190 intr_handle->nb_efd = nb_efd; 191 192 return 0; 193 fail: 194 return -rte_errno; 195 } 196 197 int rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle) 198 { 199 CHECK_VALID_INTR_HANDLE(intr_handle); 200 201 return intr_handle->nb_efd; 202 fail: 203 return -rte_errno; 204 } 205 206 int rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle) 207 { 208 CHECK_VALID_INTR_HANDLE(intr_handle); 209 210 return intr_handle->nb_intr; 211 fail: 212 return -rte_errno; 213 } 214 215 int rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle, 216 uint8_t efd_counter_size) 217 { 218 CHECK_VALID_INTR_HANDLE(intr_handle); 219 220 intr_handle->efd_counter_size = efd_counter_size; 221 222 return 0; 223 fail: 224 return -rte_errno; 225 } 226 227 int rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle) 228 { 229 CHECK_VALID_INTR_HANDLE(intr_handle); 230 231 return intr_handle->efd_counter_size; 232 fail: 233 return -rte_errno; 234 } 235 236 int rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle, 237 int index) 238 { 239 CHECK_VALID_INTR_HANDLE(intr_handle); 240 241 if (index >= intr_handle->nb_intr) { 242 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index, 243 intr_handle->nb_intr); 244 rte_errno = EINVAL; 245 goto fail; 246 } 247 248 return intr_handle->efds[index]; 249 fail: 250 return -rte_errno; 251 } 252 253 int rte_intr_efds_index_set(struct rte_intr_handle *intr_handle, 254 int index, int fd) 255 { 256 CHECK_VALID_INTR_HANDLE(intr_handle); 257 258 if (index >= intr_handle->nb_intr) { 259 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index, 260 intr_handle->nb_intr); 261 rte_errno = ERANGE; 262 goto fail; 263 } 264 265 intr_handle->efds[index] = fd; 266 267 return 0; 268 fail: 269 return -rte_errno; 270 } 271 272 struct rte_epoll_event *rte_intr_elist_index_get( 273 struct rte_intr_handle *intr_handle, int index) 274 { 275 CHECK_VALID_INTR_HANDLE(intr_handle); 276 277 if (index >= intr_handle->nb_intr) { 278 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index, 279 intr_handle->nb_intr); 280 rte_errno = ERANGE; 281 goto fail; 282 } 283 284 return &intr_handle->elist[index]; 285 fail: 286 return NULL; 287 } 288 289 int rte_intr_elist_index_set(struct rte_intr_handle *intr_handle, 290 int index, struct rte_epoll_event elist) 291 { 292 CHECK_VALID_INTR_HANDLE(intr_handle); 293 294 if (index >= intr_handle->nb_intr) { 295 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index, 296 intr_handle->nb_intr); 297 rte_errno = ERANGE; 298 goto fail; 299 } 300 301 intr_handle->elist[index] = elist; 302 303 return 0; 304 fail: 305 return -rte_errno; 306 } 307 308 int rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle, 309 const char *name, int size) 310 { 311 CHECK_VALID_INTR_HANDLE(intr_handle); 312 313 /* Vector list already allocated */ 314 if (intr_handle->intr_vec != NULL) 315 return 0; 316 317 if (size > intr_handle->nb_intr) { 318 RTE_LOG(DEBUG, EAL, "Invalid size %d, max limit %d\n", size, 319 intr_handle->nb_intr); 320 rte_errno = ERANGE; 321 goto fail; 322 } 323 324 if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) 325 intr_handle->intr_vec = rte_zmalloc(name, size * sizeof(int), 0); 326 else 327 intr_handle->intr_vec = calloc(size, sizeof(int)); 328 if (intr_handle->intr_vec == NULL) { 329 RTE_LOG(ERR, EAL, "Failed to allocate %d intr_vec\n", size); 330 rte_errno = ENOMEM; 331 goto fail; 332 } 333 334 intr_handle->vec_list_size = size; 335 336 return 0; 337 fail: 338 return -rte_errno; 339 } 340 341 int rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle, 342 int index) 343 { 344 CHECK_VALID_INTR_HANDLE(intr_handle); 345 346 if (index >= intr_handle->vec_list_size) { 347 RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n", 348 index, intr_handle->vec_list_size); 349 rte_errno = ERANGE; 350 goto fail; 351 } 352 353 return intr_handle->intr_vec[index]; 354 fail: 355 return -rte_errno; 356 } 357 358 int rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle, 359 int index, int vec) 360 { 361 CHECK_VALID_INTR_HANDLE(intr_handle); 362 363 if (index >= intr_handle->vec_list_size) { 364 RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n", 365 index, intr_handle->vec_list_size); 366 rte_errno = ERANGE; 367 goto fail; 368 } 369 370 intr_handle->intr_vec[index] = vec; 371 372 return 0; 373 fail: 374 return -rte_errno; 375 } 376 377 void rte_intr_vec_list_free(struct rte_intr_handle *intr_handle) 378 { 379 if (intr_handle == NULL) 380 return; 381 if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) 382 rte_free(intr_handle->intr_vec); 383 else 384 free(intr_handle->intr_vec); 385 intr_handle->intr_vec = NULL; 386 intr_handle->vec_list_size = 0; 387 } 388 389 void *rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle) 390 { 391 CHECK_VALID_INTR_HANDLE(intr_handle); 392 393 return intr_handle->windows_handle; 394 fail: 395 return NULL; 396 } 397 398 int rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle, 399 void *windows_handle) 400 { 401 CHECK_VALID_INTR_HANDLE(intr_handle); 402 403 intr_handle->windows_handle = windows_handle; 404 405 return 0; 406 fail: 407 return -rte_errno; 408 } 409