Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #include "acl_run.h"
6 : :
7 : : #include <eal_export.h>
8 : :
9 : : /*
10 : : * Resolve priority for multiple results (scalar version).
11 : : * This consists comparing the priority of the current traversal with the
12 : : * running set of results for the packet.
13 : : * For each result, keep a running array of the result (rule number) and
14 : : * its priority for each category.
15 : : */
16 : : static inline void
17 : 8778685 : resolve_priority_scalar(uint64_t transition, int n,
18 : : const struct rte_acl_ctx *ctx, struct parms *parms,
19 : : const struct rte_acl_match_results *p, uint32_t categories)
20 : : {
21 : : uint32_t i;
22 : : int32_t *saved_priority;
23 : : uint32_t *saved_results;
24 : : const int32_t *priority;
25 : : const uint32_t *results;
26 : :
27 : 8778685 : saved_results = parms[n].cmplt->results;
28 : 8778685 : saved_priority = parms[n].cmplt->priority;
29 : :
30 : : /* results and priorities for completed trie */
31 : 8778685 : results = p[transition].results;
32 : 8778685 : priority = p[transition].priority;
33 : :
34 : : /* if this is not the first completed trie */
35 [ + + ]: 8778685 : if (parms[n].cmplt->count != ctx->num_tries) {
36 [ + + ]: 300915 : for (i = 0; i < categories; i += RTE_ACL_RESULTS_MULTIPLIER) {
37 : :
38 [ + + ]: 240732 : if (saved_priority[i] <= priority[i]) {
39 : 236411 : saved_priority[i] = priority[i];
40 : 236411 : saved_results[i] = results[i];
41 : : }
42 [ + + ]: 240732 : if (saved_priority[i + 1] <= priority[i + 1]) {
43 : 238353 : saved_priority[i + 1] = priority[i + 1];
44 : 238353 : saved_results[i + 1] = results[i + 1];
45 : : }
46 [ + - ]: 240732 : if (saved_priority[i + 2] <= priority[i + 2]) {
47 : 240732 : saved_priority[i + 2] = priority[i + 2];
48 : 240732 : saved_results[i + 2] = results[i + 2];
49 : : }
50 [ + - ]: 240732 : if (saved_priority[i + 3] <= priority[i + 3]) {
51 : 240732 : saved_priority[i + 3] = priority[i + 3];
52 : 240732 : saved_results[i + 3] = results[i + 3];
53 : : }
54 : : }
55 : : } else {
56 [ + + ]: 43592510 : for (i = 0; i < categories; i += RTE_ACL_RESULTS_MULTIPLIER) {
57 : 34874008 : saved_priority[i] = priority[i];
58 : 34874008 : saved_priority[i + 1] = priority[i + 1];
59 : 34874008 : saved_priority[i + 2] = priority[i + 2];
60 : 34874008 : saved_priority[i + 3] = priority[i + 3];
61 : :
62 : 34874008 : saved_results[i] = results[i];
63 : 34874008 : saved_results[i + 1] = results[i + 1];
64 : 34874008 : saved_results[i + 2] = results[i + 2];
65 : 34874008 : saved_results[i + 3] = results[i + 3];
66 : : }
67 : : }
68 : 8778685 : }
69 : :
70 : : static inline uint32_t
71 : : scan_forward(uint32_t input, uint32_t max)
72 : : {
73 : 98214768 : return (input == 0) ? max : rte_bsf32(input);
74 : : }
75 : :
76 : : static inline uint64_t
77 : 107093240 : scalar_transition(const uint64_t *trans_table, uint64_t transition,
78 : : uint8_t input)
79 : : {
80 : : uint32_t addr, index, ranges, x, a, b, c;
81 : :
82 : : /* break transition into component parts */
83 : 107093240 : ranges = transition >> (sizeof(index) * CHAR_BIT);
84 : 107093240 : index = transition & ~RTE_ACL_NODE_INDEX;
85 : 107093240 : addr = transition ^ index;
86 : :
87 [ + + ]: 107093240 : if (index != RTE_ACL_NODE_DFA) {
88 : : /* calc address for a QRANGE/SINGLE node */
89 : 98214768 : c = (uint32_t)input * SCALAR_QRANGE_MULT;
90 : 98214768 : a = ranges | SCALAR_QRANGE_MIN;
91 : 98214768 : a -= (c & SCALAR_QRANGE_MASK);
92 : 98214768 : b = c & SCALAR_QRANGE_MIN;
93 : 98214768 : a &= SCALAR_QRANGE_MIN;
94 [ + + ]: 98214768 : a ^= (ranges ^ b) & (a ^ b);
95 : 98214768 : x = scan_forward(a, 32) >> 3;
96 : : } else {
97 : : /* calc address for a DFA node */
98 : 8878472 : x = ranges >> (input /
99 : 8878472 : RTE_ACL_DFA_GR64_SIZE * RTE_ACL_DFA_GR64_BIT);
100 : 8878472 : x &= UINT8_MAX;
101 : 8878472 : x = input - x;
102 : : }
103 : :
104 : 107093240 : addr += x;
105 : :
106 : : /* pickup next transition */
107 : 107093240 : transition = *(trans_table + addr);
108 : 107093240 : return transition;
109 : : }
110 : :
111 : : RTE_EXPORT_SYMBOL(rte_acl_classify_scalar)
112 : : int
113 : 319927 : rte_acl_classify_scalar(const struct rte_acl_ctx *ctx, const uint8_t **data,
114 : : uint32_t *results, uint32_t num, uint32_t categories)
115 : : {
116 : : int n;
117 : : uint64_t transition0, transition1;
118 : : uint32_t input0, input1;
119 : : struct acl_flow_data flows;
120 : : uint64_t index_array[MAX_SEARCHES_SCALAR];
121 : : struct completion cmplt[MAX_SEARCHES_SCALAR];
122 : : struct parms parms[MAX_SEARCHES_SCALAR];
123 : :
124 : : acl_set_flow(&flows, cmplt, RTE_DIM(cmplt), data, results, num,
125 : 319927 : categories, ctx->trans_table);
126 : :
127 [ + + ]: 959781 : for (n = 0; n < MAX_SEARCHES_SCALAR; n++)
128 : 639854 : index_array[n] = acl_start_next_trie(&flows, parms, n, ctx);
129 : :
130 : 319927 : transition0 = index_array[0];
131 : 319927 : transition1 = index_array[1];
132 : :
133 [ + + ]: 319928 : while ((transition0 | transition1) & RTE_ACL_NODE_MATCH) {
134 : 1 : transition0 = acl_match_check(transition0,
135 : : 0, ctx, parms, &flows, resolve_priority_scalar);
136 : 1 : transition1 = acl_match_check(transition1,
137 : : 1, ctx, parms, &flows, resolve_priority_scalar);
138 : : }
139 : :
140 [ + + ]: 13706582 : while (flows.started > 0) {
141 : :
142 : 13386655 : input0 = GET_NEXT_4BYTES(parms, 0);
143 : 13386655 : input1 = GET_NEXT_4BYTES(parms, 1);
144 : :
145 [ + + ]: 66933275 : for (n = 0; n < 4; n++) {
146 : :
147 : 53546620 : transition0 = scalar_transition(flows.trans,
148 : : transition0, (uint8_t)input0);
149 : 53546620 : input0 >>= CHAR_BIT;
150 : :
151 : 53546620 : transition1 = scalar_transition(flows.trans,
152 : : transition1, (uint8_t)input1);
153 : 53546620 : input1 >>= CHAR_BIT;
154 : : }
155 : :
156 [ + + ]: 17893406 : while ((transition0 | transition1) & RTE_ACL_NODE_MATCH) {
157 : 4506751 : transition0 = acl_match_check(transition0,
158 : : 0, ctx, parms, &flows, resolve_priority_scalar);
159 : 4506751 : transition1 = acl_match_check(transition1,
160 : : 1, ctx, parms, &flows, resolve_priority_scalar);
161 : : }
162 : : }
163 : 319927 : return 0;
164 : : }
|