diff options
Diffstat (limited to 'src/dpdk_lib18/librte_acl/acl_gen.c')
-rwxr-xr-x | src/dpdk_lib18/librte_acl/acl_gen.c | 475 |
1 files changed, 0 insertions, 475 deletions
diff --git a/src/dpdk_lib18/librte_acl/acl_gen.c b/src/dpdk_lib18/librte_acl/acl_gen.c deleted file mode 100755 index b1f766bb..00000000 --- a/src/dpdk_lib18/librte_acl/acl_gen.c +++ /dev/null @@ -1,475 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <rte_acl.h> -#include "acl_vect.h" -#include "acl.h" - -#define QRANGE_MIN ((uint8_t)INT8_MIN) - -#define RTE_ACL_VERIFY(exp) do { \ - if (!(exp)) \ - rte_panic("line %d\tassert \"" #exp "\" failed\n", __LINE__); \ -} while (0) - -struct acl_node_counters { - int match; - int match_used; - int single; - int quad; - int quad_vectors; - int dfa; - int smallest_match; -}; - -struct rte_acl_indices { - int dfa_index; - int quad_index; - int single_index; - int match_index; -}; - -static void -acl_gen_log_stats(const struct rte_acl_ctx *ctx, - const struct acl_node_counters *counts) -{ - RTE_LOG(DEBUG, ACL, "Gen phase for ACL \"%s\":\n" - "runtime memory footprint on socket %d:\n" - "single nodes/bytes used: %d/%zu\n" - "quad nodes/bytes used: %d/%zu\n" - "DFA nodes/bytes used: %d/%zu\n" - "match nodes/bytes used: %d/%zu\n" - "total: %zu bytes\n", - ctx->name, ctx->socket_id, - counts->single, counts->single * sizeof(uint64_t), - counts->quad, counts->quad_vectors * sizeof(uint64_t), - counts->dfa, counts->dfa * RTE_ACL_DFA_SIZE * sizeof(uint64_t), - counts->match, - counts->match * sizeof(struct rte_acl_match_results), - ctx->mem_sz); -} - -/* -* Counts the number of groups of sequential bits that are -* either 0 or 1, as specified by the zero_one parameter. This is used to -* calculate the number of ranges in a node to see if it fits in a quad range -* node. -*/ -static int -acl_count_sequential_groups(struct rte_acl_bitset *bits, int zero_one) -{ - int n, ranges, last_bit; - - ranges = 0; - last_bit = zero_one ^ 1; - - for (n = QRANGE_MIN; n < UINT8_MAX + 1; n++) { - if (bits->bits[n / (sizeof(bits_t) * 8)] & - (1 << (n % (sizeof(bits_t) * 8)))) { - if (zero_one == 1 && last_bit != 1) - ranges++; - last_bit = 1; - } else { - if (zero_one == 0 && last_bit != 0) - ranges++; - last_bit = 0; - } - } - for (n = 0; n < QRANGE_MIN; n++) { - if (bits->bits[n / (sizeof(bits_t) * 8)] & - (1 << (n % (sizeof(bits_t) * 8)))) { - if (zero_one == 1 && last_bit != 1) - ranges++; - last_bit = 1; - } else { - if (zero_one == 0 && last_bit != 0) - ranges++; - last_bit = 0; - } - } - - return ranges; -} - -/* - * Count number of ranges spanned by the node's pointers - */ -static int -acl_count_fanout(struct rte_acl_node *node) -{ - uint32_t n; - int ranges; - - if (node->fanout != 0) - return node->fanout; - - ranges = acl_count_sequential_groups(&node->values, 0); - - for (n = 0; n < node->num_ptrs; n++) { - if (node->ptrs[n].ptr != NULL) - ranges += acl_count_sequential_groups( - &node->ptrs[n].values, 1); - } - - node->fanout = ranges; - return node->fanout; -} - -/* - * Determine the type of nodes and count each type - */ -static int -acl_count_trie_types(struct acl_node_counters *counts, - struct rte_acl_node *node, int match, int force_dfa) -{ - uint32_t n; - int num_ptrs; - - /* skip if this node has been counted */ - if (node->node_type != (uint32_t)RTE_ACL_NODE_UNDEFINED) - return match; - - if (node->match_flag != 0 || node->num_ptrs == 0) { - counts->match++; - if (node->match_flag == -1) - node->match_flag = match++; - node->node_type = RTE_ACL_NODE_MATCH; - if (counts->smallest_match > node->match_flag) - counts->smallest_match = node->match_flag; - return match; - } - - num_ptrs = acl_count_fanout(node); - - /* Force type to dfa */ - if (force_dfa) - num_ptrs = RTE_ACL_DFA_SIZE; - - /* determine node type based on number of ranges */ - if (num_ptrs == 1) { - counts->single++; - node->node_type = RTE_ACL_NODE_SINGLE; - } else if (num_ptrs <= RTE_ACL_QUAD_MAX) { - counts->quad++; - counts->quad_vectors += node->fanout; - node->node_type = RTE_ACL_NODE_QRANGE; - } else { - counts->dfa++; - node->node_type = RTE_ACL_NODE_DFA; - } - - /* - * recursively count the types of all children - */ - for (n = 0; n < node->num_ptrs; n++) { - if (node->ptrs[n].ptr != NULL) - match = acl_count_trie_types(counts, node->ptrs[n].ptr, - match, 0); - } - - return match; -} - -static void -acl_add_ptrs(struct rte_acl_node *node, uint64_t *node_array, uint64_t no_match, - int resolved) -{ - uint32_t n, x; - int m, ranges, last_bit; - struct rte_acl_node *child; - struct rte_acl_bitset *bits; - uint64_t *node_a, index, dfa[RTE_ACL_DFA_SIZE]; - - ranges = 0; - last_bit = 0; - - for (n = 0; n < RTE_DIM(dfa); n++) - dfa[n] = no_match; - - for (x = 0; x < node->num_ptrs; x++) { - - child = node->ptrs[x].ptr; - if (child == NULL) - continue; - - bits = &node->ptrs[x].values; - for (n = 0; n < RTE_DIM(dfa); n++) { - - if (bits->bits[n / (sizeof(bits_t) * CHAR_BIT)] & - (1 << (n % (sizeof(bits_t) * CHAR_BIT)))) { - - dfa[n] = resolved ? child->node_index : x; - ranges += (last_bit == 0); - last_bit = 1; - } else { - last_bit = 0; - } - } - } - - /* - * Rather than going from 0 to 256, the range count and - * the layout are from 80-ff then 0-7f due to signed compare - * for SSE (cmpgt). - */ - if (node->node_type == RTE_ACL_NODE_QRANGE) { - - m = 0; - node_a = node_array; - index = dfa[QRANGE_MIN]; - *node_a++ = index; - - for (x = QRANGE_MIN + 1; x < UINT8_MAX + 1; x++) { - if (dfa[x] != index) { - index = dfa[x]; - *node_a++ = index; - node->transitions[m++] = (uint8_t)(x - 1); - } - } - - for (x = 0; x < INT8_MAX + 1; x++) { - if (dfa[x] != index) { - index = dfa[x]; - *node_a++ = index; - node->transitions[m++] = (uint8_t)(x - 1); - } - } - - /* fill unused locations with max value - nothing is greater */ - for (; m < RTE_ACL_QUAD_SIZE; m++) - node->transitions[m] = INT8_MAX; - - RTE_ACL_VERIFY(m <= RTE_ACL_QUAD_SIZE); - - } else if (node->node_type == RTE_ACL_NODE_DFA && resolved) { - for (n = 0; n < RTE_DIM(dfa); n++) - node_array[n] = dfa[n]; - } -} - -/* - * Routine that allocates space for this node and recursively calls - * to allocate space for each child. Once all the children are allocated, - * then resolve all transitions for this node. - */ -static void -acl_gen_node(struct rte_acl_node *node, uint64_t *node_array, - uint64_t no_match, struct rte_acl_indices *index, int num_categories) -{ - uint32_t n, *qtrp; - uint64_t *array_ptr; - struct rte_acl_match_results *match; - - if (node->node_index != RTE_ACL_NODE_UNDEFINED) - return; - - array_ptr = NULL; - - switch (node->node_type) { - case RTE_ACL_NODE_DFA: - node->node_index = index->dfa_index | node->node_type; - array_ptr = &node_array[index->dfa_index]; - index->dfa_index += RTE_ACL_DFA_SIZE; - for (n = 0; n < RTE_ACL_DFA_SIZE; n++) - array_ptr[n] = no_match; - break; - case RTE_ACL_NODE_SINGLE: - node->node_index = RTE_ACL_QUAD_SINGLE | index->single_index | - node->node_type; - array_ptr = &node_array[index->single_index]; - index->single_index += 1; - array_ptr[0] = no_match; - break; - case RTE_ACL_NODE_QRANGE: - array_ptr = &node_array[index->quad_index]; - acl_add_ptrs(node, array_ptr, no_match, 0); - qtrp = (uint32_t *)node->transitions; - node->node_index = qtrp[0]; - node->node_index <<= sizeof(index->quad_index) * CHAR_BIT; - node->node_index |= index->quad_index | node->node_type; - index->quad_index += node->fanout; - break; - case RTE_ACL_NODE_MATCH: - match = ((struct rte_acl_match_results *) - (node_array + index->match_index)); - memcpy(match + node->match_flag, node->mrt, sizeof(*node->mrt)); - node->node_index = node->match_flag | node->node_type; - break; - case RTE_ACL_NODE_UNDEFINED: - RTE_ACL_VERIFY(node->node_type != - (uint32_t)RTE_ACL_NODE_UNDEFINED); - break; - } - - /* recursively allocate space for all children */ - for (n = 0; n < node->num_ptrs; n++) { - if (node->ptrs[n].ptr != NULL) - acl_gen_node(node->ptrs[n].ptr, - node_array, - no_match, - index, - num_categories); - } - - /* All children are resolved, resolve this node's pointers */ - switch (node->node_type) { - case RTE_ACL_NODE_DFA: - acl_add_ptrs(node, array_ptr, no_match, 1); - break; - case RTE_ACL_NODE_SINGLE: - for (n = 0; n < node->num_ptrs; n++) { - if (node->ptrs[n].ptr != NULL) - array_ptr[0] = node->ptrs[n].ptr->node_index; - } - break; - case RTE_ACL_NODE_QRANGE: - acl_add_ptrs(node, array_ptr, no_match, 1); - break; - case RTE_ACL_NODE_MATCH: - break; - case RTE_ACL_NODE_UNDEFINED: - RTE_ACL_VERIFY(node->node_type != - (uint32_t)RTE_ACL_NODE_UNDEFINED); - break; - } -} - -static int -acl_calc_counts_indices(struct acl_node_counters *counts, - struct rte_acl_indices *indices, struct rte_acl_trie *trie, - struct rte_acl_bld_trie *node_bld_trie, uint32_t num_tries, - int match_num) -{ - uint32_t n; - - memset(indices, 0, sizeof(*indices)); - memset(counts, 0, sizeof(*counts)); - - /* Get stats on nodes */ - for (n = 0; n < num_tries; n++) { - counts->smallest_match = INT32_MAX; - match_num = acl_count_trie_types(counts, node_bld_trie[n].trie, - match_num, 1); - trie[n].smallest = counts->smallest_match; - } - - indices->dfa_index = RTE_ACL_DFA_SIZE + 1; - indices->quad_index = indices->dfa_index + - counts->dfa * RTE_ACL_DFA_SIZE; - indices->single_index = indices->quad_index + counts->quad_vectors; - indices->match_index = indices->single_index + counts->single + 1; - indices->match_index = RTE_ALIGN(indices->match_index, - (XMM_SIZE / sizeof(uint64_t))); - - return match_num; -} - -/* - * Generate the runtime structure using build structure - */ -int -rte_acl_gen(struct rte_acl_ctx *ctx, struct rte_acl_trie *trie, - struct rte_acl_bld_trie *node_bld_trie, uint32_t num_tries, - uint32_t num_categories, uint32_t data_index_sz, int match_num) -{ - void *mem; - size_t total_size; - uint64_t *node_array, no_match; - uint32_t n, match_index; - struct rte_acl_match_results *match; - struct acl_node_counters counts; - struct rte_acl_indices indices; - - /* Fill counts and indices arrays from the nodes. */ - match_num = acl_calc_counts_indices(&counts, &indices, trie, - node_bld_trie, num_tries, match_num); - - /* Allocate runtime memory (align to cache boundary) */ - total_size = RTE_ALIGN(data_index_sz, RTE_CACHE_LINE_SIZE) + - indices.match_index * sizeof(uint64_t) + - (match_num + 2) * sizeof(struct rte_acl_match_results) + - XMM_SIZE; - - mem = rte_zmalloc_socket(ctx->name, total_size, RTE_CACHE_LINE_SIZE, - ctx->socket_id); - if (mem == NULL) { - RTE_LOG(ERR, ACL, - "allocation of %zu bytes on socket %d for %s failed\n", - total_size, ctx->socket_id, ctx->name); - return -ENOMEM; - } - - /* Fill the runtime structure */ - match_index = indices.match_index; - node_array = (uint64_t *)((uintptr_t)mem + - RTE_ALIGN(data_index_sz, RTE_CACHE_LINE_SIZE)); - - /* - * Setup the NOMATCH node (a SINGLE at the - * highest index, that points to itself) - */ - - node_array[RTE_ACL_DFA_SIZE] = RTE_ACL_DFA_SIZE | RTE_ACL_NODE_SINGLE; - no_match = RTE_ACL_NODE_MATCH; - - for (n = 0; n < RTE_ACL_DFA_SIZE; n++) - node_array[n] = no_match; - - match = ((struct rte_acl_match_results *)(node_array + match_index)); - memset(match, 0, sizeof(*match)); - - for (n = 0; n < num_tries; n++) { - - acl_gen_node(node_bld_trie[n].trie, node_array, no_match, - &indices, num_categories); - - if (node_bld_trie[n].trie->node_index == no_match) - trie[n].root_index = 0; - else - trie[n].root_index = node_bld_trie[n].trie->node_index; - } - - ctx->mem = mem; - ctx->mem_sz = total_size; - ctx->data_indexes = mem; - ctx->num_tries = num_tries; - ctx->num_categories = num_categories; - ctx->match_index = match_index; - ctx->no_match = no_match; - ctx->idle = node_array[RTE_ACL_DFA_SIZE]; - ctx->trans_table = node_array; - memcpy(ctx->trie, trie, sizeof(ctx->trie)); - - acl_gen_log_stats(ctx, &counts); - return 0; -} |