diff options
author | Bill Fischofer <bill.fischofer@linaro.org> | 2014-12-16 14:30:35 +0200 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2014-12-16 19:03:39 +0300 |
commit | a834a53925baa7196ed07ad8e0cd990979c33f19 (patch) | |
tree | 5b5c08c108ec393adf85fe871e5f5d4f088e54ce /platform/linux-generic | |
parent | 8822ad6c22f6d135c43829e043c675a779bbd005 (diff) |
api: packet: change alloc/free
Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org>
Reviewed-and-tested-by: Bill Fischofer <bill.fischofer@linaro.org>
Reviewed-by: Petri Savolainen <petri.savolainen@linaro.org>
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform/linux-generic')
-rw-r--r-- | platform/linux-generic/include/api/odp_packet.h | 65 | ||||
-rw-r--r-- | platform/linux-generic/include/odp_packet_internal.h | 1 | ||||
-rw-r--r-- | platform/linux-generic/odp_packet.c | 64 | ||||
-rw-r--r-- | platform/linux-generic/odp_packet_socket.c | 10 |
4 files changed, 110 insertions, 30 deletions
diff --git a/platform/linux-generic/include/api/odp_packet.h b/platform/linux-generic/include/api/odp_packet.h index 9e2e542ae..9a151146c 100644 --- a/platform/linux-generic/include/api/odp_packet.h +++ b/platform/linux-generic/include/api/odp_packet.h @@ -19,6 +19,7 @@ extern "C" { #endif #include <odp_buffer.h> +#include <odp_platform_types.h> /** @defgroup odp_packet ODP PACKET * Operations on a packet. @@ -26,33 +27,73 @@ extern "C" { */ +/* + * Packet API v0.5 notes + * - Push/pull operations only on packet level + * - Push/pull within limits of segment headroom/tailroom/data lengths + * - Segment data length must be always at least one byte (i.e. there are no + * empty segments) + * - Head/tailroom content belong to packet content (in addition to data + * and meta-data) and thus is preserved over packet ownership changes. + * - _addr refer to a fixed address, which operations do not modify + * - _ptr refer to pointer to data, which may be modified by operations + */ + + +/* + * + * Alloc and free + * ******************************************************** + * + */ + /** - * Allocate and initialize a packet buffer from a packet pool + * Allocate a packet from a buffer pool * - * @param pool_id Pool handle + * Allocates a packet of the requested length from the specified buffer pool. + * Pool must have been created with buffer type ODP_BUFFER_TYPE_PACKET. The + * packet is initialized with data pointers and lengths set according to the + * specified len, and the default headroom and tailroom length settings. All + * other packet metadata are set to their default values. * - * @note The pool must have been created with 'buf_type=ODP_BUFFER_TYPE_PACKET' + * @param pool Pool handle + * @param len Packet data length * - * @return Packet handle or ODP_PACKET_INVALID + * @return Handle of allocated packet + * @retval ODP_PACKET_INVALID Packet could not be allocated + * + * @note The default headroom and tailroom used for packets is specified by + * the ODP_CONFIG_PACKET_HEADROOM and ODP_CONFIG_PACKET_TAILROOM defines in + * odp_config.h. */ -odp_packet_t odp_packet_alloc(odp_buffer_pool_t pool_id); +odp_packet_t odp_packet_alloc(odp_buffer_pool_t pool, uint32_t len); /** - * Free a packet buffer back into the packet pool + * Free packet * - * @param pkt Packet handle + * Frees the packet into the buffer pool it was allocated from. + * + * @param pkt Packet handle */ void odp_packet_free(odp_packet_t pkt); /** - * Initialize the packet + * Reset packet * - * Needs to be called if the user allocates a packet buffer, i.e. the packet - * has not been received from I/O through ODP. + * Resets all packet meta-data to their default values. Packet length is used + * to initialize pointers and lengths. It must be less than the total buffer + * length of the packet minus the default headroom length. Packet is not + * modified on failure. * - * @param pkt Packet handle + * @param pkt Packet handle + * @param len Packet data length + * + * @retval 0 Success + * @retval Non-zero Failure + * + * @see odp_packet_buf_len() */ -void odp_packet_init(odp_packet_t pkt); +int odp_packet_reset(odp_packet_t pkt, uint32_t len); /** * Convert a buffer handle to a packet handle diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index e47364d0e..eecdfd7a6 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -173,6 +173,7 @@ static inline void packet_init(pool_entry_t *pool, (pool->s.headroom + size); } +odp_packet_t _odp_packet_alloc(odp_buffer_pool_t pool_hdl); #ifdef __cplusplus } diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 8a941ceca..a4ad3e858 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -21,34 +21,54 @@ static inline uint8_t parse_ipv4(odp_packet_hdr_t *pkt_hdr, static inline uint8_t parse_ipv6(odp_packet_hdr_t *pkt_hdr, odph_ipv6hdr_t *ipv6, size_t *offset_out); -odp_packet_t odp_packet_alloc(odp_buffer_pool_t pool_id) +/* + * + * Alloc and free + * ******************************************************** + * + */ + +odp_packet_t odp_packet_alloc(odp_buffer_pool_t pool_hdl, uint32_t len) { - odp_packet_t pkt; - odp_buffer_t buf; + pool_entry_t *pool = odp_pool_to_entry(pool_hdl); - buf = odp_buffer_alloc(pool_id); - if (odp_unlikely(!odp_buffer_is_valid(buf))) + if (pool->s.params.buf_type != ODP_BUFFER_TYPE_PACKET) return ODP_PACKET_INVALID; - pkt = odp_packet_from_buffer(buf); - odp_packet_init(pkt); + /* Handle special case for zero-length packets */ + if (len == 0) { + odp_packet_t pkt = + (odp_packet_t)buffer_alloc(pool_hdl, + pool->s.params.buf_size); + if (pkt != ODP_PACKET_INVALID) { + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + uint32_t buf_size = pool->s.params.buf_size; + pkt_hdr->tailroom += buf_size; + pkt_hdr->frame_len -= buf_size; + } - return pkt; + return pkt; + } + + return (odp_packet_t)buffer_alloc(pool_hdl, len); } void odp_packet_free(odp_packet_t pkt) { - odp_buffer_t buf = odp_packet_to_buffer(pkt); - - odp_buffer_free(buf); + odp_buffer_free((odp_buffer_t)pkt); } -void odp_packet_init(odp_packet_t pkt) +int odp_packet_reset(odp_packet_t pkt, uint32_t len) { odp_packet_hdr_t *const pkt_hdr = odp_packet_hdr(pkt); pool_entry_t *pool = odp_buf_to_pool(&pkt_hdr->buf_hdr); + uint32_t totsize = pool->s.headroom + len + pool->s.tailroom; + + if (totsize > pkt_hdr->buf_hdr.size) + return -1; - packet_init(pool, pkt_hdr, 0); + packet_init(pool, pkt_hdr, len); + return 0; } odp_packet_t odp_packet_from_buffer(odp_buffer_t buf) @@ -404,3 +424,21 @@ size_t odp_packet_buf_size(odp_packet_t pkt) return odp_buffer_size(buf); } + +/* + * + * Internal Use Routines + * ******************************************************** + * + */ + +odp_packet_t _odp_packet_alloc(odp_buffer_pool_t pool_hdl) +{ + pool_entry_t *pool = odp_pool_to_entry(pool_hdl); + + if (pool->s.params.buf_type != ODP_BUFFER_TYPE_PACKET) + return ODP_PACKET_INVALID; + + return (odp_packet_t)buffer_alloc(pool_hdl, + pool->s.params.buf_size); +} diff --git a/platform/linux-generic/odp_packet_socket.c b/platform/linux-generic/odp_packet_socket.c index b11aa1c27..76e437a8c 100644 --- a/platform/linux-generic/odp_packet_socket.c +++ b/platform/linux-generic/odp_packet_socket.c @@ -215,7 +215,7 @@ int setup_pkt_sock(pkt_sock_t *const pkt_sock, const char *netdev, return -1; pkt_sock->pool = pool; - pkt = odp_packet_alloc(pool); + pkt = _odp_packet_alloc(pool); if (!odp_packet_is_valid(pkt)) return -1; @@ -332,7 +332,7 @@ int recv_pkt_sock_basic(pkt_sock_t *const pkt_sock, for (i = 0; i < len; i++) { if (odp_likely(pkt == ODP_PACKET_INVALID)) { - pkt = odp_packet_alloc(pkt_sock->pool); + pkt = _odp_packet_alloc(pkt_sock->pool); if (odp_unlikely(pkt == ODP_PACKET_INVALID)) break; } @@ -430,7 +430,7 @@ int recv_pkt_sock_mmsg(pkt_sock_t *const pkt_sock, memset(msgvec, 0, sizeof(msgvec)); for (i = 0; i < (int)len; i++) { - pkt_table[i] = odp_packet_alloc(pkt_sock->pool); + pkt_table[i] = _odp_packet_alloc(pkt_sock->pool); if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID)) break; @@ -605,7 +605,7 @@ static inline unsigned pkt_mmap_v2_rx(int sock, struct ring *ring, continue; } - pkt_table[i] = odp_packet_alloc(pool); + pkt_table[i] = _odp_packet_alloc(pool); if (odp_unlikely(pkt_table[i] == ODP_PACKET_INVALID)) break; @@ -851,7 +851,7 @@ int setup_pkt_sock_mmap(pkt_sock_mmap_t *const pkt_sock, const char *netdev, if (pool == ODP_BUFFER_POOL_INVALID) return -1; - pkt = odp_packet_alloc(pool); + pkt = _odp_packet_alloc(pool); if (!odp_packet_is_valid(pkt)) return -1; |