| 491 | } |
| 492 | |
| 493 | struct rte_efd_table * |
| 494 | rte_efd_create(const char *name, uint32_t max_num_rules, uint32_t key_len, |
| 495 | uint64_t online_cpu_socket_bitmask, uint8_t offline_cpu_socket) |
| 496 | { |
| 497 | struct rte_efd_table *table = NULL; |
| 498 | uint8_t *key_array = NULL; |
| 499 | uint32_t num_chunks, num_chunks_shift; |
| 500 | uint8_t socket_id; |
| 501 | struct rte_efd_list *efd_list = NULL; |
| 502 | struct rte_tailq_entry *te; |
| 503 | uint64_t offline_table_size; |
| 504 | char ring_name[RTE_RING_NAMESIZE]; |
| 505 | struct rte_ring *r = NULL; |
| 506 | unsigned int i; |
| 507 | |
| 508 | efd_list = RTE_TAILQ_CAST(rte_efd_tailq.head, rte_efd_list); |
| 509 | |
| 510 | if (online_cpu_socket_bitmask == 0) { |
| 511 | RTE_LOG(ERR, EFD, "At least one CPU socket must be enabled " |
| 512 | "in the bitmask\n"); |
| 513 | return NULL; |
| 514 | } |
| 515 | |
| 516 | if (max_num_rules == 0) { |
| 517 | RTE_LOG(ERR, EFD, "Max num rules must be higher than 0\n"); |
| 518 | return NULL; |
| 519 | } |
| 520 | |
| 521 | /* |
| 522 | * Compute the minimum number of chunks (smallest power of 2) |
| 523 | * that can hold all of the rules |
| 524 | */ |
| 525 | if (max_num_rules % EFD_TARGET_CHUNK_NUM_RULES == 0) |
| 526 | num_chunks = rte_align32pow2(max_num_rules / |
| 527 | EFD_TARGET_CHUNK_NUM_RULES); |
| 528 | else |
| 529 | num_chunks = rte_align32pow2((max_num_rules / |
| 530 | EFD_TARGET_CHUNK_NUM_RULES) + 1); |
| 531 | |
| 532 | num_chunks_shift = rte_bsf32(num_chunks); |
| 533 | |
| 534 | rte_mcfg_tailq_write_lock(); |
| 535 | |
| 536 | /* |
| 537 | * Guarantee there's no existing: this is normally already checked |
| 538 | * by ring creation above |
| 539 | */ |
| 540 | TAILQ_FOREACH(te, efd_list, next) |
| 541 | { |
| 542 | table = (struct rte_efd_table *) te->data; |
| 543 | if (strncmp(name, table->name, RTE_EFD_NAMESIZE) == 0) |
| 544 | break; |
| 545 | } |
| 546 | |
| 547 | table = NULL; |
| 548 | if (te != NULL) { |
| 549 | rte_errno = EEXIST; |
| 550 | te = NULL; |