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 : 8743021 : 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 : 8743021 : saved_results = parms[n].cmplt->results;
28 : 8743021 : saved_priority = parms[n].cmplt->priority;
29 : :
30 : : /* results and priorities for completed trie */
31 : 8743021 : results = p[transition].results;
32 : 8743021 : priority = p[transition].priority;
33 : :
34 : : /* if this is not the first completed trie */
35 [ + + ]: 8743021 : if (parms[n].cmplt->count != ctx->num_tries) {
36 [ + + ]: 211755 : for (i = 0; i < categories; i += RTE_ACL_RESULTS_MULTIPLIER) {
37 : :
38 [ + + ]: 169404 : if (saved_priority[i] <= priority[i]) {
39 : 166483 : saved_priority[i] = priority[i];
40 : 166483 : saved_results[i] = results[i];
41 : : }
42 [ + + ]: 169404 : if (saved_priority[i + 1] <= priority[i + 1]) {
43 : 167777 : saved_priority[i + 1] = priority[i + 1];
44 : 167777 : saved_results[i + 1] = results[i + 1];
45 : : }
46 [ + - ]: 169404 : if (saved_priority[i + 2] <= priority[i + 2]) {
47 : 169404 : saved_priority[i + 2] = priority[i + 2];
48 : 169404 : saved_results[i + 2] = results[i + 2];
49 : : }
50 [ + - ]: 169404 : if (saved_priority[i + 3] <= priority[i + 3]) {
51 : 169404 : saved_priority[i + 3] = priority[i + 3];
52 : 169404 : saved_results[i + 3] = results[i + 3];
53 : : }
54 : : }
55 : : } else {
56 [ + + ]: 43503350 : for (i = 0; i < categories; i += RTE_ACL_RESULTS_MULTIPLIER) {
57 : 34802680 : saved_priority[i] = priority[i];
58 : 34802680 : saved_priority[i + 1] = priority[i + 1];
59 : 34802680 : saved_priority[i + 2] = priority[i + 2];
60 : 34802680 : saved_priority[i + 3] = priority[i + 3];
61 : :
62 : 34802680 : saved_results[i] = results[i];
63 : 34802680 : saved_results[i + 1] = results[i + 1];
64 : 34802680 : saved_results[i + 2] = results[i + 2];
65 : 34802680 : saved_results[i + 3] = results[i + 3];
66 : : }
67 : : }
68 : 8743021 : }
69 : :
70 : : static inline uint32_t
71 : : scan_forward(uint32_t input, uint32_t max)
72 : : {
73 : 97877728 : return (input == 0) ? max : rte_bsf32(input);
74 : : }
75 : :
76 : : static inline uint64_t
77 : 106688824 : 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 : 106688824 : ranges = transition >> (sizeof(index) * CHAR_BIT);
84 : 106688824 : index = transition & ~RTE_ACL_NODE_INDEX;
85 : 106688824 : addr = transition ^ index;
86 : :
87 [ + + ]: 106688824 : if (index != RTE_ACL_NODE_DFA) {
88 : : /* calc address for a QRANGE/SINGLE node */
89 : 97877728 : c = (uint32_t)input * SCALAR_QRANGE_MULT;
90 : 97877728 : a = ranges | SCALAR_QRANGE_MIN;
91 : 97877728 : a -= (c & SCALAR_QRANGE_MASK);
92 : 97877728 : b = c & SCALAR_QRANGE_MIN;
93 : 97877728 : a &= SCALAR_QRANGE_MIN;
94 [ + + ]: 97877728 : a ^= (ranges ^ b) & (a ^ b);
95 : 97877728 : x = scan_forward(a, 32) >> 3;
96 : : } else {
97 : : /* calc address for a DFA node */
98 : 8811096 : x = ranges >> (input /
99 : 8811096 : RTE_ACL_DFA_GR64_SIZE * RTE_ACL_DFA_GR64_BIT);
100 : 8811096 : x &= UINT8_MAX;
101 : 8811096 : x = input - x;
102 : : }
103 : :
104 : 106688824 : addr += x;
105 : :
106 : : /* pickup next transition */
107 : 106688824 : transition = *(trans_table + addr);
108 : 106688824 : return transition;
109 : : }
110 : :
111 : : RTE_EXPORT_SYMBOL(rte_acl_classify_scalar)
112 : : int
113 : 319295 : 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 : 319295 : categories, ctx->trans_table);
126 : :
127 [ + + ]: 957885 : for (n = 0; n < MAX_SEARCHES_SCALAR; n++)
128 : 638590 : index_array[n] = acl_start_next_trie(&flows, parms, n, ctx);
129 : :
130 : 319295 : transition0 = index_array[0];
131 : 319295 : transition1 = index_array[1];
132 : :
133 [ + + ]: 319296 : 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 [ + + ]: 13655398 : while (flows.started > 0) {
141 : :
142 : 13336103 : input0 = GET_NEXT_4BYTES(parms, 0);
143 : 13336103 : input1 = GET_NEXT_4BYTES(parms, 1);
144 : :
145 [ + + ]: 66680515 : for (n = 0; n < 4; n++) {
146 : :
147 : 53344412 : transition0 = scalar_transition(flows.trans,
148 : : transition0, (uint8_t)input0);
149 : 53344412 : input0 >>= CHAR_BIT;
150 : :
151 : 53344412 : transition1 = scalar_transition(flows.trans,
152 : : transition1, (uint8_t)input1);
153 : 53344412 : input1 >>= CHAR_BIT;
154 : : }
155 : :
156 [ + + ]: 17813046 : while ((transition0 | transition1) & RTE_ACL_NODE_MATCH) {
157 : 4476943 : transition0 = acl_match_check(transition0,
158 : : 0, ctx, parms, &flows, resolve_priority_scalar);
159 : 4476943 : transition1 = acl_match_check(transition1,
160 : : 1, ctx, parms, &flows, resolve_priority_scalar);
161 : : }
162 : : }
163 : 319295 : return 0;
164 : : }
|