2 // Copyright (c) 2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
16 #ifndef __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
17 #define __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
21 #include <rte_common.h>
22 #include <rte_cycles.h>
24 #include <rte_pipeline.h>
26 #define PIPELINE_PORT_IN_AH(f_ah, f_pkt_work, f_pkt4_work) \
29 __rte_unused struct rte_pipeline *p, \
30 struct rte_mbuf **pkts, \
36 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) \
37 f_pkt4_work(&pkts[i], arg); \
39 for ( ; i < n_pkts; i++) \
40 f_pkt_work(pkts[i], arg); \
45 #define PIPELINE_PORT_IN_AH_HIJACK_ALL(f_ah, f_pkt_work, f_pkt4_work) \
48 struct rte_pipeline *p, \
49 struct rte_mbuf **pkts, \
53 uint64_t pkt_mask = RTE_LEN2MASK(n_pkts, uint64_t); \
56 rte_pipeline_ah_packet_hijack(p, pkt_mask); \
58 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) \
59 f_pkt4_work(&pkts[i], arg); \
61 for ( ; i < n_pkts; i++) \
62 f_pkt_work(pkts[i], arg); \
67 #define PIPELINE_TABLE_AH_HIT(f_ah, f_pkt_work, f_pkt4_work) \
70 __rte_unused struct rte_pipeline *p, \
71 struct rte_mbuf **pkts, \
72 uint64_t pkts_in_mask, \
73 struct rte_pipeline_table_entry **entries, \
76 if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) { \
77 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask); \
80 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) \
81 f_pkt4_work(&pkts[i], &entries[i], arg); \
83 for ( ; i < n_pkts; i++) \
84 f_pkt_work(pkts[i], entries[i], arg); \
86 for ( ; pkts_in_mask; ) { \
87 uint32_t pos = __builtin_ctzll(pkts_in_mask); \
88 uint64_t pkt_mask = 1LLU << pos; \
90 pkts_in_mask &= ~pkt_mask; \
91 f_pkt_work(pkts[pos], entries[pos], arg); \
97 #define PIPELINE_TABLE_AH_MISS(f_ah, f_pkt_work, f_pkt4_work) \
100 __rte_unused struct rte_pipeline *p, \
101 struct rte_mbuf **pkts, \
102 uint64_t pkts_in_mask, \
103 struct rte_pipeline_table_entry *entry, \
106 if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) { \
107 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask); \
110 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) \
111 f_pkt4_work(&pkts[i], entry, arg); \
113 for ( ; i < n_pkts; i++) \
114 f_pkt_work(pkts[i], entry, arg); \
116 for ( ; pkts_in_mask; ) { \
117 uint32_t pos = __builtin_ctzll(pkts_in_mask); \
118 uint64_t pkt_mask = 1LLU << pos; \
120 pkts_in_mask &= ~pkt_mask; \
121 f_pkt_work(pkts[pos], entry, arg); \
127 #define PIPELINE_TABLE_AH_HIT_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work) \
130 struct rte_pipeline *p, \
131 struct rte_mbuf **pkts, \
132 uint64_t pkts_mask, \
133 struct rte_pipeline_table_entry **entries, \
136 uint64_t pkts_in_mask = pkts_mask; \
137 uint64_t pkts_out_mask = pkts_mask; \
138 uint64_t time = rte_rdtsc(); \
140 if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) { \
141 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask); \
144 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) { \
145 uint64_t mask = f_pkt4_work(&pkts[i], \
146 &entries[i], arg, time); \
147 pkts_out_mask ^= mask << i; \
150 for ( ; i < n_pkts; i++) { \
151 uint64_t mask = f_pkt_work(pkts[i], \
152 entries[i], arg, time); \
153 pkts_out_mask ^= mask << i; \
156 for ( ; pkts_in_mask; ) { \
157 uint32_t pos = __builtin_ctzll(pkts_in_mask); \
158 uint64_t pkt_mask = 1LLU << pos; \
159 uint64_t mask = f_pkt_work(pkts[pos], \
160 entries[pos], arg, time); \
162 pkts_in_mask &= ~pkt_mask; \
163 pkts_out_mask ^= mask << pos; \
166 rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask); \
171 #define PIPELINE_TABLE_AH_MISS_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work) \
174 struct rte_pipeline *p, \
175 struct rte_mbuf **pkts, \
176 uint64_t pkts_mask, \
177 struct rte_pipeline_table_entry *entry, \
180 uint64_t pkts_in_mask = pkts_mask; \
181 uint64_t pkts_out_mask = pkts_mask; \
182 uint64_t time = rte_rdtsc(); \
184 if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) { \
185 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask); \
188 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) { \
189 uint64_t mask = f_pkt4_work(&pkts[i], \
191 pkts_out_mask ^= mask << i; \
194 for ( ; i < n_pkts; i++) { \
195 uint64_t mask = f_pkt_work(pkts[i], entry, arg, time);\
196 pkts_out_mask ^= mask << i; \
199 for ( ; pkts_in_mask; ) { \
200 uint32_t pos = __builtin_ctzll(pkts_in_mask); \
201 uint64_t pkt_mask = 1LLU << pos; \
202 uint64_t mask = f_pkt_work(pkts[pos], \
205 pkts_in_mask &= ~pkt_mask; \
206 pkts_out_mask ^= mask << pos; \
209 rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask); \