1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2021 Intel Corporation
9 #include <rte_hexdump.h>
11 #include "rte_swx_port_ring.h"
18 #define TRACE(...) printf(__VA_ARGS__)
28 struct rte_ring *ring;
32 struct rte_swx_port_in_stats stats;
33 struct rte_mbuf **pkts;
39 reader_create(void *args)
41 struct rte_swx_port_ring_reader_params *params = args;
42 struct rte_ring *ring;
43 struct reader *p = NULL;
45 /* Check input parameters. */
46 if (!params || !params->name || !params->burst_size)
49 ring = rte_ring_lookup(params->name);
53 /* Memory allocation. */
54 p = calloc(1, sizeof(struct reader));
58 p->params.name = strdup(params->name);
62 p->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));
67 p->params.ring = ring;
68 p->params.burst_size = params->burst_size;
83 reader_pkt_rx(void *port, struct rte_swx_pkt *pkt)
85 struct reader *p = port;
88 if (p->pos == p->n_pkts) {
91 n_pkts = rte_ring_sc_dequeue_burst(p->params.ring,
100 TRACE("[Ring %s] %d packets in\n",
108 m = p->pkts[p->pos++];
110 pkt->pkt = m->buf_addr;
111 pkt->offset = m->data_off;
112 pkt->length = m->pkt_len;
114 TRACE("[Ring %s] Pkt %d (%u bytes at offset %u)\n",
115 (uint32_t)p->params.name,
122 &((uint8_t *)m->buf_addr)[m->data_off],
126 p->stats.n_bytes += pkt->length;
132 reader_free(void *port)
134 struct reader *p = port;
140 for (i = 0; i < p->n_pkts; i++) {
141 struct rte_mbuf *pkt = p->pkts[i];
143 rte_pktmbuf_free(pkt);
147 free(p->params.name);
152 reader_stats_read(void *port, struct rte_swx_port_in_stats *stats)
154 struct reader *p = port;
159 memcpy(stats, &p->stats, sizeof(p->stats));
167 struct rte_ring *ring;
171 struct rte_swx_port_out_stats stats;
173 struct rte_mbuf **pkts;
178 writer_create(void *args)
180 struct rte_swx_port_ring_writer_params *params = args;
181 struct rte_ring *ring;
182 struct writer *p = NULL;
184 /* Check input parameters. */
185 if (!params || !params->name || !params->burst_size)
188 ring = rte_ring_lookup(params->name);
192 /* Memory allocation. */
193 p = calloc(1, sizeof(struct writer));
197 p->params.name = strdup(params->name);
201 p->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));
205 /* Initialization. */
206 p->params.ring = ring;
207 p->params.burst_size = params->burst_size;
215 free(p->params.name);
222 __writer_flush(struct writer *p)
226 for (n_pkts = 0; ; ) {
227 n_pkts += rte_ring_sp_enqueue_burst(p->params.ring,
228 (void **)p->pkts + n_pkts,
232 TRACE("[Ring %s] %d packets out\n", p->params.name, n_pkts);
234 if (n_pkts == p->n_pkts)
242 writer_pkt_tx(void *port, struct rte_swx_pkt *pkt)
244 struct writer *p = port;
245 struct rte_mbuf *m = pkt->handle;
247 TRACE("[Ring %s] Pkt %d (%u bytes at offset %u)\n",
253 rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
255 m->data_len = (uint16_t)(pkt->length + m->data_len - m->pkt_len);
256 m->pkt_len = pkt->length;
257 m->data_off = (uint16_t)pkt->offset;
260 p->stats.n_bytes += pkt->length;
262 p->pkts[p->n_pkts++] = m;
263 if (p->n_pkts == (int)p->params.burst_size)
268 writer_pkt_fast_clone_tx(void *port, struct rte_swx_pkt *pkt)
270 struct writer *p = port;
271 struct rte_mbuf *m = pkt->handle;
273 TRACE("[Ring %s] Pkt %d (%u bytes at offset %u) (fast clone)\n",
279 rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
281 m->data_len = (uint16_t)(pkt->length + m->data_len - m->pkt_len);
282 m->pkt_len = pkt->length;
283 m->data_off = (uint16_t)pkt->offset;
284 rte_pktmbuf_refcnt_update(m, 1);
287 p->stats.n_bytes += pkt->length;
288 p->stats.n_pkts_clone++;
290 p->pkts[p->n_pkts++] = m;
291 if (p->n_pkts == (int)p->params.burst_size)
296 writer_pkt_clone_tx(void *port, struct rte_swx_pkt *pkt, uint32_t truncation_length)
298 struct writer *p = port;
299 struct rte_mbuf *m = pkt->handle, *m_clone;
301 TRACE("[Ring %s] Pkt %d (%u bytes at offset %u) (clone)\n",
307 rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
309 m->data_len = (uint16_t)(pkt->length + m->data_len - m->pkt_len);
310 m->pkt_len = pkt->length;
311 m->data_off = (uint16_t)pkt->offset;
313 m_clone = rte_pktmbuf_copy(m, m->pool, 0, truncation_length);
315 p->stats.n_pkts_clone_err++;
320 p->stats.n_bytes += pkt->length;
321 p->stats.n_pkts_clone++;
323 p->pkts[p->n_pkts++] = m_clone;
324 if (p->n_pkts == (int)p->params.burst_size)
329 writer_flush(void *port)
331 struct writer *p = port;
338 writer_free(void *port)
340 struct writer *p = port;
347 free(p->params.name);
352 writer_stats_read(void *port, struct rte_swx_port_out_stats *stats)
354 struct writer *p = port;
359 memcpy(stats, &p->stats, sizeof(p->stats));
363 * Summary of port operations
365 struct rte_swx_port_in_ops rte_swx_port_ring_reader_ops = {
366 .create = reader_create,
368 .pkt_rx = reader_pkt_rx,
369 .stats_read = reader_stats_read,
372 struct rte_swx_port_out_ops rte_swx_port_ring_writer_ops = {
373 .create = writer_create,
375 .pkt_tx = writer_pkt_tx,
376 .pkt_fast_clone_tx = writer_pkt_fast_clone_tx,
377 .pkt_clone_tx = writer_pkt_clone_tx,
378 .flush = writer_flush,
379 .stats_read = writer_stats_read,