199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * 399a2dd95SBruce Richardson * Copyright (c) 2020 Arm Limited 499a2dd95SBruce Richardson * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org 599a2dd95SBruce Richardson * All rights reserved. 699a2dd95SBruce Richardson * Derived from FreeBSD's bufring.h 799a2dd95SBruce Richardson * Used as BSD-3 Licensed with permission from Kip Macy. 899a2dd95SBruce Richardson */ 999a2dd95SBruce Richardson 1099a2dd95SBruce Richardson #ifndef _RTE_RING_PEEK_ZC_H_ 1199a2dd95SBruce Richardson #define _RTE_RING_PEEK_ZC_H_ 1299a2dd95SBruce Richardson 1399a2dd95SBruce Richardson /** 1499a2dd95SBruce Richardson * @file 1599a2dd95SBruce Richardson * It is not recommended to include this file directly. 1699a2dd95SBruce Richardson * Please include <rte_ring_elem.h> instead. 1799a2dd95SBruce Richardson * 1899a2dd95SBruce Richardson * Ring Peek Zero Copy APIs 1999a2dd95SBruce Richardson * These APIs make it possible to split public enqueue/dequeue API 2099a2dd95SBruce Richardson * into 3 parts: 2199a2dd95SBruce Richardson * - enqueue/dequeue start 2299a2dd95SBruce Richardson * - copy data to/from the ring 2399a2dd95SBruce Richardson * - enqueue/dequeue finish 2499a2dd95SBruce Richardson * Along with the advantages of the peek APIs, these APIs provide the ability 2599a2dd95SBruce Richardson * to avoid copying of the data to temporary area (for ex: array of mbufs 2699a2dd95SBruce Richardson * on the stack). 2799a2dd95SBruce Richardson * 2899a2dd95SBruce Richardson * Note that currently these APIs are available only for two sync modes: 2999a2dd95SBruce Richardson * 1) Single Producer/Single Consumer (RTE_RING_SYNC_ST) 3099a2dd95SBruce Richardson * 2) Serialized Producer/Serialized Consumer (RTE_RING_SYNC_MT_HTS). 3199a2dd95SBruce Richardson * It is user's responsibility to create/init ring with appropriate sync 3299a2dd95SBruce Richardson * modes selected. 3399a2dd95SBruce Richardson * 3499a2dd95SBruce Richardson * Following are some examples showing the API usage. 3599a2dd95SBruce Richardson * 1) 3699a2dd95SBruce Richardson * struct elem_obj {uint64_t a; uint32_t b, c;}; 3799a2dd95SBruce Richardson * struct elem_obj *obj; 3899a2dd95SBruce Richardson * 3999a2dd95SBruce Richardson * // Create ring with sync type RTE_RING_SYNC_ST or RTE_RING_SYNC_MT_HTS 4099a2dd95SBruce Richardson * // Reserve space on the ring 4199a2dd95SBruce Richardson * n = rte_ring_enqueue_zc_bulk_elem_start(r, sizeof(elem_obj), 1, &zcd, NULL); 4299a2dd95SBruce Richardson * 4399a2dd95SBruce Richardson * // Produce the data directly on the ring memory 4499a2dd95SBruce Richardson * obj = (struct elem_obj *)zcd->ptr1; 4599a2dd95SBruce Richardson * obj->a = rte_get_a(); 4699a2dd95SBruce Richardson * obj->b = rte_get_b(); 4799a2dd95SBruce Richardson * obj->c = rte_get_c(); 4899a2dd95SBruce Richardson * rte_ring_enqueue_zc_elem_finish(ring, n); 4999a2dd95SBruce Richardson * 5099a2dd95SBruce Richardson * 2) 5199a2dd95SBruce Richardson * // Create ring with sync type RTE_RING_SYNC_ST or RTE_RING_SYNC_MT_HTS 5299a2dd95SBruce Richardson * // Reserve space on the ring 5399a2dd95SBruce Richardson * n = rte_ring_enqueue_zc_burst_start(r, 32, &zcd, NULL); 5499a2dd95SBruce Richardson * 5599a2dd95SBruce Richardson * // Pkt I/O core polls packets from the NIC 5699a2dd95SBruce Richardson * if (n != 0) { 5799a2dd95SBruce Richardson * nb_rx = rte_eth_rx_burst(portid, queueid, zcd->ptr1, zcd->n1); 5899a2dd95SBruce Richardson * if (nb_rx == zcd->n1 && n != zcd->n1) 5999a2dd95SBruce Richardson * nb_rx = rte_eth_rx_burst(portid, queueid, 6099a2dd95SBruce Richardson * zcd->ptr2, n - zcd->n1); 6199a2dd95SBruce Richardson * 6299a2dd95SBruce Richardson * // Provide packets to the packet processing cores 6399a2dd95SBruce Richardson * rte_ring_enqueue_zc_finish(r, nb_rx); 6499a2dd95SBruce Richardson * } 6599a2dd95SBruce Richardson * 6699a2dd95SBruce Richardson * Note that between _start_ and _finish_ none other thread can proceed 6799a2dd95SBruce Richardson * with enqueue/dequeue operation till _finish_ completes. 6899a2dd95SBruce Richardson */ 6999a2dd95SBruce Richardson 70*719834a6SMattias Rönnblom #include <rte_ring_peek_elem_pvt.h> 71*719834a6SMattias Rönnblom 7299a2dd95SBruce Richardson #ifdef __cplusplus 7399a2dd95SBruce Richardson extern "C" { 7499a2dd95SBruce Richardson #endif 7599a2dd95SBruce Richardson 7699a2dd95SBruce Richardson /** 7799a2dd95SBruce Richardson * Ring zero-copy information structure. 7899a2dd95SBruce Richardson * 7999a2dd95SBruce Richardson * This structure contains the pointers and length of the space 8099a2dd95SBruce Richardson * reserved on the ring storage. 8199a2dd95SBruce Richardson */ 82c6552d9aSTyler Retzlaff struct __rte_cache_aligned rte_ring_zc_data { 8399a2dd95SBruce Richardson /* Pointer to the first space in the ring */ 8499a2dd95SBruce Richardson void *ptr1; 8599a2dd95SBruce Richardson /* Pointer to the second space in the ring if there is wrap-around. 8699a2dd95SBruce Richardson * It contains valid value only if wrap-around happens. 8799a2dd95SBruce Richardson */ 8899a2dd95SBruce Richardson void *ptr2; 8999a2dd95SBruce Richardson /* Number of elements in the first pointer. If this is equal to 9099a2dd95SBruce Richardson * the number of elements requested, then ptr2 is NULL. 9199a2dd95SBruce Richardson * Otherwise, subtracting n1 from number of elements requested 9299a2dd95SBruce Richardson * will give the number of elements available at ptr2. 9399a2dd95SBruce Richardson */ 9499a2dd95SBruce Richardson unsigned int n1; 95c6552d9aSTyler Retzlaff }; 9699a2dd95SBruce Richardson 9799a2dd95SBruce Richardson static __rte_always_inline void 9899a2dd95SBruce Richardson __rte_ring_get_elem_addr(struct rte_ring *r, uint32_t head, 9999a2dd95SBruce Richardson uint32_t esize, uint32_t num, void **dst1, uint32_t *n1, void **dst2) 10099a2dd95SBruce Richardson { 10199a2dd95SBruce Richardson uint32_t idx, scale, nr_idx; 10299a2dd95SBruce Richardson uint32_t *ring = (uint32_t *)&r[1]; 10399a2dd95SBruce Richardson 10499a2dd95SBruce Richardson /* Normalize to uint32_t */ 10599a2dd95SBruce Richardson scale = esize / sizeof(uint32_t); 10699a2dd95SBruce Richardson idx = head & r->mask; 10799a2dd95SBruce Richardson nr_idx = idx * scale; 10899a2dd95SBruce Richardson 10999a2dd95SBruce Richardson *dst1 = ring + nr_idx; 11099a2dd95SBruce Richardson *n1 = num; 11199a2dd95SBruce Richardson 11299a2dd95SBruce Richardson if (idx + num > r->size) { 11399a2dd95SBruce Richardson *n1 = r->size - idx; 11499a2dd95SBruce Richardson *dst2 = ring; 11599a2dd95SBruce Richardson } else { 11699a2dd95SBruce Richardson *dst2 = NULL; 11799a2dd95SBruce Richardson } 11899a2dd95SBruce Richardson } 11999a2dd95SBruce Richardson 12099a2dd95SBruce Richardson /** 12199a2dd95SBruce Richardson * @internal This function moves prod head value. 12299a2dd95SBruce Richardson */ 12399a2dd95SBruce Richardson static __rte_always_inline unsigned int 12499a2dd95SBruce Richardson __rte_ring_do_enqueue_zc_elem_start(struct rte_ring *r, unsigned int esize, 12599a2dd95SBruce Richardson uint32_t n, enum rte_ring_queue_behavior behavior, 12699a2dd95SBruce Richardson struct rte_ring_zc_data *zcd, unsigned int *free_space) 12799a2dd95SBruce Richardson { 12899a2dd95SBruce Richardson uint32_t free, head, next; 12999a2dd95SBruce Richardson 13099a2dd95SBruce Richardson switch (r->prod.sync_type) { 13199a2dd95SBruce Richardson case RTE_RING_SYNC_ST: 13299a2dd95SBruce Richardson n = __rte_ring_move_prod_head(r, RTE_RING_SYNC_ST, n, 13399a2dd95SBruce Richardson behavior, &head, &next, &free); 13499a2dd95SBruce Richardson break; 13599a2dd95SBruce Richardson case RTE_RING_SYNC_MT_HTS: 13699a2dd95SBruce Richardson n = __rte_ring_hts_move_prod_head(r, n, behavior, &head, &free); 13799a2dd95SBruce Richardson break; 13899a2dd95SBruce Richardson case RTE_RING_SYNC_MT: 13999a2dd95SBruce Richardson case RTE_RING_SYNC_MT_RTS: 14099a2dd95SBruce Richardson default: 14199a2dd95SBruce Richardson /* unsupported mode, shouldn't be here */ 14299a2dd95SBruce Richardson RTE_ASSERT(0); 14399a2dd95SBruce Richardson n = 0; 14499a2dd95SBruce Richardson free = 0; 14599a2dd95SBruce Richardson return n; 14699a2dd95SBruce Richardson } 14799a2dd95SBruce Richardson 14899a2dd95SBruce Richardson __rte_ring_get_elem_addr(r, head, esize, n, &zcd->ptr1, 14999a2dd95SBruce Richardson &zcd->n1, &zcd->ptr2); 15099a2dd95SBruce Richardson 15199a2dd95SBruce Richardson if (free_space != NULL) 15299a2dd95SBruce Richardson *free_space = free - n; 15399a2dd95SBruce Richardson return n; 15499a2dd95SBruce Richardson } 15599a2dd95SBruce Richardson 15699a2dd95SBruce Richardson /** 15799a2dd95SBruce Richardson * Start to enqueue several objects on the ring. 15899a2dd95SBruce Richardson * Note that no actual objects are put in the queue by this function, 15999a2dd95SBruce Richardson * it just reserves space for the user on the ring. 16099a2dd95SBruce Richardson * User has to copy objects into the queue using the returned pointers. 16199a2dd95SBruce Richardson * User should call rte_ring_enqueue_zc_elem_finish to complete the 16299a2dd95SBruce Richardson * enqueue operation. 16399a2dd95SBruce Richardson * 16499a2dd95SBruce Richardson * @param r 16599a2dd95SBruce Richardson * A pointer to the ring structure. 16699a2dd95SBruce Richardson * @param esize 16799a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 16899a2dd95SBruce Richardson * @param n 16999a2dd95SBruce Richardson * The number of objects to add in the ring. 17099a2dd95SBruce Richardson * @param zcd 17199a2dd95SBruce Richardson * Structure containing the pointers and length of the space 17299a2dd95SBruce Richardson * reserved on the ring storage. 17399a2dd95SBruce Richardson * @param free_space 17499a2dd95SBruce Richardson * If non-NULL, returns the amount of space in the ring after the 17599a2dd95SBruce Richardson * reservation operation has finished. 17699a2dd95SBruce Richardson * @return 17799a2dd95SBruce Richardson * The number of objects that can be enqueued, either 0 or n 17899a2dd95SBruce Richardson */ 17999a2dd95SBruce Richardson static __rte_always_inline unsigned int 18099a2dd95SBruce Richardson rte_ring_enqueue_zc_bulk_elem_start(struct rte_ring *r, unsigned int esize, 18199a2dd95SBruce Richardson unsigned int n, struct rte_ring_zc_data *zcd, unsigned int *free_space) 18299a2dd95SBruce Richardson { 18399a2dd95SBruce Richardson return __rte_ring_do_enqueue_zc_elem_start(r, esize, n, 18499a2dd95SBruce Richardson RTE_RING_QUEUE_FIXED, zcd, free_space); 18599a2dd95SBruce Richardson } 18699a2dd95SBruce Richardson 18799a2dd95SBruce Richardson /** 18899a2dd95SBruce Richardson * Start to enqueue several pointers to objects on the ring. 18999a2dd95SBruce Richardson * Note that no actual pointers are put in the queue by this function, 19099a2dd95SBruce Richardson * it just reserves space for the user on the ring. 19199a2dd95SBruce Richardson * User has to copy pointers to objects into the queue using the 19299a2dd95SBruce Richardson * returned pointers. 19399a2dd95SBruce Richardson * User should call rte_ring_enqueue_zc_finish to complete the 19499a2dd95SBruce Richardson * enqueue operation. 19599a2dd95SBruce Richardson * 19699a2dd95SBruce Richardson * @param r 19799a2dd95SBruce Richardson * A pointer to the ring structure. 19899a2dd95SBruce Richardson * @param n 19999a2dd95SBruce Richardson * The number of objects to add in the ring. 20099a2dd95SBruce Richardson * @param zcd 20199a2dd95SBruce Richardson * Structure containing the pointers and length of the space 20299a2dd95SBruce Richardson * reserved on the ring storage. 20399a2dd95SBruce Richardson * @param free_space 20499a2dd95SBruce Richardson * If non-NULL, returns the amount of space in the ring after the 20599a2dd95SBruce Richardson * reservation operation has finished. 20699a2dd95SBruce Richardson * @return 20799a2dd95SBruce Richardson * The number of objects that can be enqueued, either 0 or n 20899a2dd95SBruce Richardson */ 20999a2dd95SBruce Richardson static __rte_always_inline unsigned int 21099a2dd95SBruce Richardson rte_ring_enqueue_zc_bulk_start(struct rte_ring *r, unsigned int n, 21199a2dd95SBruce Richardson struct rte_ring_zc_data *zcd, unsigned int *free_space) 21299a2dd95SBruce Richardson { 21399a2dd95SBruce Richardson return rte_ring_enqueue_zc_bulk_elem_start(r, sizeof(uintptr_t), n, 21499a2dd95SBruce Richardson zcd, free_space); 21599a2dd95SBruce Richardson } 21699a2dd95SBruce Richardson 21799a2dd95SBruce Richardson /** 21899a2dd95SBruce Richardson * Start to enqueue several objects on the ring. 21999a2dd95SBruce Richardson * Note that no actual objects are put in the queue by this function, 22099a2dd95SBruce Richardson * it just reserves space for the user on the ring. 22199a2dd95SBruce Richardson * User has to copy objects into the queue using the returned pointers. 22299a2dd95SBruce Richardson * User should call rte_ring_enqueue_zc_elem_finish to complete the 22399a2dd95SBruce Richardson * enqueue operation. 22499a2dd95SBruce Richardson * 22599a2dd95SBruce Richardson * @param r 22699a2dd95SBruce Richardson * A pointer to the ring structure. 22799a2dd95SBruce Richardson * @param esize 22899a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 22999a2dd95SBruce Richardson * @param n 23099a2dd95SBruce Richardson * The number of objects to add in the ring. 23199a2dd95SBruce Richardson * @param zcd 23299a2dd95SBruce Richardson * Structure containing the pointers and length of the space 23399a2dd95SBruce Richardson * reserved on the ring storage. 23499a2dd95SBruce Richardson * @param free_space 23599a2dd95SBruce Richardson * If non-NULL, returns the amount of space in the ring after the 23699a2dd95SBruce Richardson * reservation operation has finished. 23799a2dd95SBruce Richardson * @return 23899a2dd95SBruce Richardson * The number of objects that can be enqueued, either 0 or n 23999a2dd95SBruce Richardson */ 24099a2dd95SBruce Richardson static __rte_always_inline unsigned int 24199a2dd95SBruce Richardson rte_ring_enqueue_zc_burst_elem_start(struct rte_ring *r, unsigned int esize, 24299a2dd95SBruce Richardson unsigned int n, struct rte_ring_zc_data *zcd, unsigned int *free_space) 24399a2dd95SBruce Richardson { 24499a2dd95SBruce Richardson return __rte_ring_do_enqueue_zc_elem_start(r, esize, n, 24599a2dd95SBruce Richardson RTE_RING_QUEUE_VARIABLE, zcd, free_space); 24699a2dd95SBruce Richardson } 24799a2dd95SBruce Richardson 24899a2dd95SBruce Richardson /** 24999a2dd95SBruce Richardson * Start to enqueue several pointers to objects on the ring. 25099a2dd95SBruce Richardson * Note that no actual pointers are put in the queue by this function, 25199a2dd95SBruce Richardson * it just reserves space for the user on the ring. 25299a2dd95SBruce Richardson * User has to copy pointers to objects into the queue using the 25399a2dd95SBruce Richardson * returned pointers. 25499a2dd95SBruce Richardson * User should call rte_ring_enqueue_zc_finish to complete the 25599a2dd95SBruce Richardson * enqueue operation. 25699a2dd95SBruce Richardson * 25799a2dd95SBruce Richardson * @param r 25899a2dd95SBruce Richardson * A pointer to the ring structure. 25999a2dd95SBruce Richardson * @param n 26099a2dd95SBruce Richardson * The number of objects to add in the ring. 26199a2dd95SBruce Richardson * @param zcd 26299a2dd95SBruce Richardson * Structure containing the pointers and length of the space 26399a2dd95SBruce Richardson * reserved on the ring storage. 26499a2dd95SBruce Richardson * @param free_space 26599a2dd95SBruce Richardson * If non-NULL, returns the amount of space in the ring after the 26699a2dd95SBruce Richardson * reservation operation has finished. 26799a2dd95SBruce Richardson * @return 26899a2dd95SBruce Richardson * The number of objects that can be enqueued, either 0 or n. 26999a2dd95SBruce Richardson */ 27099a2dd95SBruce Richardson static __rte_always_inline unsigned int 27199a2dd95SBruce Richardson rte_ring_enqueue_zc_burst_start(struct rte_ring *r, unsigned int n, 27299a2dd95SBruce Richardson struct rte_ring_zc_data *zcd, unsigned int *free_space) 27399a2dd95SBruce Richardson { 27499a2dd95SBruce Richardson return rte_ring_enqueue_zc_burst_elem_start(r, sizeof(uintptr_t), n, 27599a2dd95SBruce Richardson zcd, free_space); 27699a2dd95SBruce Richardson } 27799a2dd95SBruce Richardson 27899a2dd95SBruce Richardson /** 27999a2dd95SBruce Richardson * Complete enqueuing several objects on the ring. 28099a2dd95SBruce Richardson * Note that number of objects to enqueue should not exceed previous 28199a2dd95SBruce Richardson * enqueue_start return value. 28299a2dd95SBruce Richardson * 28399a2dd95SBruce Richardson * @param r 28499a2dd95SBruce Richardson * A pointer to the ring structure. 28599a2dd95SBruce Richardson * @param n 28699a2dd95SBruce Richardson * The number of objects to add to the ring. 28799a2dd95SBruce Richardson */ 28899a2dd95SBruce Richardson static __rte_always_inline void 28999a2dd95SBruce Richardson rte_ring_enqueue_zc_elem_finish(struct rte_ring *r, unsigned int n) 29099a2dd95SBruce Richardson { 29199a2dd95SBruce Richardson uint32_t tail; 29299a2dd95SBruce Richardson 29399a2dd95SBruce Richardson switch (r->prod.sync_type) { 29499a2dd95SBruce Richardson case RTE_RING_SYNC_ST: 29599a2dd95SBruce Richardson n = __rte_ring_st_get_tail(&r->prod, &tail, n); 29699a2dd95SBruce Richardson __rte_ring_st_set_head_tail(&r->prod, tail, n, 1); 29799a2dd95SBruce Richardson break; 29899a2dd95SBruce Richardson case RTE_RING_SYNC_MT_HTS: 29999a2dd95SBruce Richardson n = __rte_ring_hts_get_tail(&r->hts_prod, &tail, n); 30099a2dd95SBruce Richardson __rte_ring_hts_set_head_tail(&r->hts_prod, tail, n, 1); 30199a2dd95SBruce Richardson break; 30299a2dd95SBruce Richardson case RTE_RING_SYNC_MT: 30399a2dd95SBruce Richardson case RTE_RING_SYNC_MT_RTS: 30499a2dd95SBruce Richardson default: 30599a2dd95SBruce Richardson /* unsupported mode, shouldn't be here */ 30699a2dd95SBruce Richardson RTE_ASSERT(0); 30799a2dd95SBruce Richardson } 30899a2dd95SBruce Richardson } 30999a2dd95SBruce Richardson 31099a2dd95SBruce Richardson /** 31199a2dd95SBruce Richardson * Complete enqueuing several pointers to objects on the ring. 31299a2dd95SBruce Richardson * Note that number of objects to enqueue should not exceed previous 31399a2dd95SBruce Richardson * enqueue_start return value. 31499a2dd95SBruce Richardson * 31599a2dd95SBruce Richardson * @param r 31699a2dd95SBruce Richardson * A pointer to the ring structure. 31799a2dd95SBruce Richardson * @param n 31899a2dd95SBruce Richardson * The number of pointers to objects to add to the ring. 31999a2dd95SBruce Richardson */ 32099a2dd95SBruce Richardson static __rte_always_inline void 32199a2dd95SBruce Richardson rte_ring_enqueue_zc_finish(struct rte_ring *r, unsigned int n) 32299a2dd95SBruce Richardson { 32399a2dd95SBruce Richardson rte_ring_enqueue_zc_elem_finish(r, n); 32499a2dd95SBruce Richardson } 32599a2dd95SBruce Richardson 32699a2dd95SBruce Richardson /** 32799a2dd95SBruce Richardson * @internal This function moves cons head value and copies up to *n* 32899a2dd95SBruce Richardson * objects from the ring to the user provided obj_table. 32999a2dd95SBruce Richardson */ 33099a2dd95SBruce Richardson static __rte_always_inline unsigned int 33199a2dd95SBruce Richardson __rte_ring_do_dequeue_zc_elem_start(struct rte_ring *r, 33299a2dd95SBruce Richardson uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior, 33399a2dd95SBruce Richardson struct rte_ring_zc_data *zcd, unsigned int *available) 33499a2dd95SBruce Richardson { 33599a2dd95SBruce Richardson uint32_t avail, head, next; 33699a2dd95SBruce Richardson 33799a2dd95SBruce Richardson switch (r->cons.sync_type) { 33899a2dd95SBruce Richardson case RTE_RING_SYNC_ST: 33999a2dd95SBruce Richardson n = __rte_ring_move_cons_head(r, RTE_RING_SYNC_ST, n, 34099a2dd95SBruce Richardson behavior, &head, &next, &avail); 34199a2dd95SBruce Richardson break; 34299a2dd95SBruce Richardson case RTE_RING_SYNC_MT_HTS: 34399a2dd95SBruce Richardson n = __rte_ring_hts_move_cons_head(r, n, behavior, 34499a2dd95SBruce Richardson &head, &avail); 34599a2dd95SBruce Richardson break; 34699a2dd95SBruce Richardson case RTE_RING_SYNC_MT: 34799a2dd95SBruce Richardson case RTE_RING_SYNC_MT_RTS: 34899a2dd95SBruce Richardson default: 34999a2dd95SBruce Richardson /* unsupported mode, shouldn't be here */ 35099a2dd95SBruce Richardson RTE_ASSERT(0); 35199a2dd95SBruce Richardson n = 0; 35299a2dd95SBruce Richardson avail = 0; 35399a2dd95SBruce Richardson return n; 35499a2dd95SBruce Richardson } 35599a2dd95SBruce Richardson 35699a2dd95SBruce Richardson __rte_ring_get_elem_addr(r, head, esize, n, &zcd->ptr1, 35799a2dd95SBruce Richardson &zcd->n1, &zcd->ptr2); 35899a2dd95SBruce Richardson 35999a2dd95SBruce Richardson if (available != NULL) 36099a2dd95SBruce Richardson *available = avail - n; 36199a2dd95SBruce Richardson return n; 36299a2dd95SBruce Richardson } 36399a2dd95SBruce Richardson 36499a2dd95SBruce Richardson /** 36599a2dd95SBruce Richardson * Start to dequeue several objects from the ring. 36699a2dd95SBruce Richardson * Note that no actual objects are copied from the queue by this function. 36799a2dd95SBruce Richardson * User has to copy objects from the queue using the returned pointers. 36899a2dd95SBruce Richardson * User should call rte_ring_dequeue_zc_elem_finish to complete the 36999a2dd95SBruce Richardson * dequeue operation. 37099a2dd95SBruce Richardson * 37199a2dd95SBruce Richardson * @param r 37299a2dd95SBruce Richardson * A pointer to the ring structure. 37399a2dd95SBruce Richardson * @param esize 37499a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 37599a2dd95SBruce Richardson * @param n 37699a2dd95SBruce Richardson * The number of objects to remove from the ring. 37799a2dd95SBruce Richardson * @param zcd 37899a2dd95SBruce Richardson * Structure containing the pointers and length of the space 37999a2dd95SBruce Richardson * reserved on the ring storage. 38099a2dd95SBruce Richardson * @param available 38199a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 38299a2dd95SBruce Richardson * dequeue has finished. 38399a2dd95SBruce Richardson * @return 38499a2dd95SBruce Richardson * The number of objects that can be dequeued, either 0 or n. 38599a2dd95SBruce Richardson */ 38699a2dd95SBruce Richardson static __rte_always_inline unsigned int 38799a2dd95SBruce Richardson rte_ring_dequeue_zc_bulk_elem_start(struct rte_ring *r, unsigned int esize, 38899a2dd95SBruce Richardson unsigned int n, struct rte_ring_zc_data *zcd, unsigned int *available) 38999a2dd95SBruce Richardson { 39099a2dd95SBruce Richardson return __rte_ring_do_dequeue_zc_elem_start(r, esize, n, 39199a2dd95SBruce Richardson RTE_RING_QUEUE_FIXED, zcd, available); 39299a2dd95SBruce Richardson } 39399a2dd95SBruce Richardson 39499a2dd95SBruce Richardson /** 39599a2dd95SBruce Richardson * Start to dequeue several pointers to objects from the ring. 39699a2dd95SBruce Richardson * Note that no actual pointers are removed from the queue by this function. 39799a2dd95SBruce Richardson * User has to copy pointers to objects from the queue using the 39899a2dd95SBruce Richardson * returned pointers. 39999a2dd95SBruce Richardson * User should call rte_ring_dequeue_zc_finish to complete the 40099a2dd95SBruce Richardson * dequeue operation. 40199a2dd95SBruce Richardson * 40299a2dd95SBruce Richardson * @param r 40399a2dd95SBruce Richardson * A pointer to the ring structure. 40499a2dd95SBruce Richardson * @param n 40599a2dd95SBruce Richardson * The number of objects to remove from the ring. 40699a2dd95SBruce Richardson * @param zcd 40799a2dd95SBruce Richardson * Structure containing the pointers and length of the space 40899a2dd95SBruce Richardson * reserved on the ring storage. 40999a2dd95SBruce Richardson * @param available 41099a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 41199a2dd95SBruce Richardson * dequeue has finished. 41299a2dd95SBruce Richardson * @return 41399a2dd95SBruce Richardson * The number of objects that can be dequeued, either 0 or n. 41499a2dd95SBruce Richardson */ 41599a2dd95SBruce Richardson static __rte_always_inline unsigned int 41699a2dd95SBruce Richardson rte_ring_dequeue_zc_bulk_start(struct rte_ring *r, unsigned int n, 41799a2dd95SBruce Richardson struct rte_ring_zc_data *zcd, unsigned int *available) 41899a2dd95SBruce Richardson { 41999a2dd95SBruce Richardson return rte_ring_dequeue_zc_bulk_elem_start(r, sizeof(uintptr_t), 42099a2dd95SBruce Richardson n, zcd, available); 42199a2dd95SBruce Richardson } 42299a2dd95SBruce Richardson 42399a2dd95SBruce Richardson /** 42499a2dd95SBruce Richardson * Start to dequeue several objects from the ring. 42599a2dd95SBruce Richardson * Note that no actual objects are copied from the queue by this function. 42699a2dd95SBruce Richardson * User has to copy objects from the queue using the returned pointers. 42799a2dd95SBruce Richardson * User should call rte_ring_dequeue_zc_elem_finish to complete the 42899a2dd95SBruce Richardson * dequeue operation. 42999a2dd95SBruce Richardson * 43099a2dd95SBruce Richardson * @param r 43199a2dd95SBruce Richardson * A pointer to the ring structure. 43299a2dd95SBruce Richardson * @param esize 43399a2dd95SBruce Richardson * The size of ring element, in bytes. It must be a multiple of 4. 43499a2dd95SBruce Richardson * This must be the same value used while creating the ring. Otherwise 43599a2dd95SBruce Richardson * the results are undefined. 43699a2dd95SBruce Richardson * @param n 43799a2dd95SBruce Richardson * The number of objects to dequeue from the ring. 43899a2dd95SBruce Richardson * @param zcd 43999a2dd95SBruce Richardson * Structure containing the pointers and length of the space 44099a2dd95SBruce Richardson * reserved on the ring storage. 44199a2dd95SBruce Richardson * @param available 44299a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 44399a2dd95SBruce Richardson * dequeue has finished. 44499a2dd95SBruce Richardson * @return 44599a2dd95SBruce Richardson * The number of objects that can be dequeued, either 0 or n. 44699a2dd95SBruce Richardson */ 44799a2dd95SBruce Richardson static __rte_always_inline unsigned int 44899a2dd95SBruce Richardson rte_ring_dequeue_zc_burst_elem_start(struct rte_ring *r, unsigned int esize, 44999a2dd95SBruce Richardson unsigned int n, struct rte_ring_zc_data *zcd, unsigned int *available) 45099a2dd95SBruce Richardson { 45199a2dd95SBruce Richardson return __rte_ring_do_dequeue_zc_elem_start(r, esize, n, 45299a2dd95SBruce Richardson RTE_RING_QUEUE_VARIABLE, zcd, available); 45399a2dd95SBruce Richardson } 45499a2dd95SBruce Richardson 45599a2dd95SBruce Richardson /** 45699a2dd95SBruce Richardson * Start to dequeue several pointers to objects from the ring. 45799a2dd95SBruce Richardson * Note that no actual pointers are removed from the queue by this function. 45899a2dd95SBruce Richardson * User has to copy pointers to objects from the queue using the 45999a2dd95SBruce Richardson * returned pointers. 46099a2dd95SBruce Richardson * User should call rte_ring_dequeue_zc_finish to complete the 46199a2dd95SBruce Richardson * dequeue operation. 46299a2dd95SBruce Richardson * 46399a2dd95SBruce Richardson * @param r 46499a2dd95SBruce Richardson * A pointer to the ring structure. 46599a2dd95SBruce Richardson * @param n 46699a2dd95SBruce Richardson * The number of objects to remove from the ring. 46799a2dd95SBruce Richardson * @param zcd 46899a2dd95SBruce Richardson * Structure containing the pointers and length of the space 46999a2dd95SBruce Richardson * reserved on the ring storage. 47099a2dd95SBruce Richardson * @param available 47199a2dd95SBruce Richardson * If non-NULL, returns the number of remaining ring entries after the 47299a2dd95SBruce Richardson * dequeue has finished. 47399a2dd95SBruce Richardson * @return 47499a2dd95SBruce Richardson * The number of objects that can be dequeued, either 0 or n. 47599a2dd95SBruce Richardson */ 47699a2dd95SBruce Richardson static __rte_always_inline unsigned int 47799a2dd95SBruce Richardson rte_ring_dequeue_zc_burst_start(struct rte_ring *r, unsigned int n, 47899a2dd95SBruce Richardson struct rte_ring_zc_data *zcd, unsigned int *available) 47999a2dd95SBruce Richardson { 48099a2dd95SBruce Richardson return rte_ring_dequeue_zc_burst_elem_start(r, sizeof(uintptr_t), n, 48199a2dd95SBruce Richardson zcd, available); 48299a2dd95SBruce Richardson } 48399a2dd95SBruce Richardson 48499a2dd95SBruce Richardson /** 48599a2dd95SBruce Richardson * Complete dequeuing several objects from the ring. 48699a2dd95SBruce Richardson * Note that number of objects to dequeued should not exceed previous 48799a2dd95SBruce Richardson * dequeue_start return value. 48899a2dd95SBruce Richardson * 48999a2dd95SBruce Richardson * @param r 49099a2dd95SBruce Richardson * A pointer to the ring structure. 49199a2dd95SBruce Richardson * @param n 49299a2dd95SBruce Richardson * The number of objects to remove from the ring. 49399a2dd95SBruce Richardson */ 49499a2dd95SBruce Richardson static __rte_always_inline void 49599a2dd95SBruce Richardson rte_ring_dequeue_zc_elem_finish(struct rte_ring *r, unsigned int n) 49699a2dd95SBruce Richardson { 49799a2dd95SBruce Richardson uint32_t tail; 49899a2dd95SBruce Richardson 49999a2dd95SBruce Richardson switch (r->cons.sync_type) { 50099a2dd95SBruce Richardson case RTE_RING_SYNC_ST: 50199a2dd95SBruce Richardson n = __rte_ring_st_get_tail(&r->cons, &tail, n); 50299a2dd95SBruce Richardson __rte_ring_st_set_head_tail(&r->cons, tail, n, 0); 50399a2dd95SBruce Richardson break; 50499a2dd95SBruce Richardson case RTE_RING_SYNC_MT_HTS: 50599a2dd95SBruce Richardson n = __rte_ring_hts_get_tail(&r->hts_cons, &tail, n); 50699a2dd95SBruce Richardson __rte_ring_hts_set_head_tail(&r->hts_cons, tail, n, 0); 50799a2dd95SBruce Richardson break; 50899a2dd95SBruce Richardson case RTE_RING_SYNC_MT: 50999a2dd95SBruce Richardson case RTE_RING_SYNC_MT_RTS: 51099a2dd95SBruce Richardson default: 51199a2dd95SBruce Richardson /* unsupported mode, shouldn't be here */ 51299a2dd95SBruce Richardson RTE_ASSERT(0); 51399a2dd95SBruce Richardson } 51499a2dd95SBruce Richardson } 51599a2dd95SBruce Richardson 51699a2dd95SBruce Richardson /** 51799a2dd95SBruce Richardson * Complete dequeuing several objects from the ring. 51899a2dd95SBruce Richardson * Note that number of objects to dequeued should not exceed previous 51999a2dd95SBruce Richardson * dequeue_start return value. 52099a2dd95SBruce Richardson * 52199a2dd95SBruce Richardson * @param r 52299a2dd95SBruce Richardson * A pointer to the ring structure. 52399a2dd95SBruce Richardson * @param n 52499a2dd95SBruce Richardson * The number of objects to remove from the ring. 52599a2dd95SBruce Richardson */ 52699a2dd95SBruce Richardson static __rte_always_inline void 52799a2dd95SBruce Richardson rte_ring_dequeue_zc_finish(struct rte_ring *r, unsigned int n) 52899a2dd95SBruce Richardson { 52999a2dd95SBruce Richardson rte_ring_dequeue_elem_finish(r, n); 53099a2dd95SBruce Richardson } 53199a2dd95SBruce Richardson 53299a2dd95SBruce Richardson #ifdef __cplusplus 53399a2dd95SBruce Richardson } 53499a2dd95SBruce Richardson #endif 53599a2dd95SBruce Richardson 53699a2dd95SBruce Richardson #endif /* _RTE_RING_PEEK_ZC_H_ */ 537