diff options
Diffstat (limited to 'platform/linux-dpdk')
-rw-r--r-- | platform/linux-dpdk/Makefile.am | 17 | ||||
l--------- | platform/linux-dpdk/include/odp/api/deprecated.h | 1 | ||||
-rw-r--r-- | platform/linux-dpdk/include/odp/api/plat/packet_types.h | 2 | ||||
l---------[-rw-r--r--] | platform/linux-dpdk/include/odp/api/plat/time_types.h | 44 | ||||
-rw-r--r-- | platform/linux-dpdk/include/odp_packet_internal.h | 79 | ||||
-rw-r--r-- | platform/linux-dpdk/include/odp_time_internal.h | 44 | ||||
-rw-r--r-- | platform/linux-dpdk/m4/configure.m4 | 45 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_crypto.c | 230 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_packet.c | 341 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_packet_dpdk.c | 22 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_packet_flags.c | 114 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_pool.c | 8 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_time.c | 359 |
13 files changed, 634 insertions, 672 deletions
diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index dfbc57619..c1497f0f6 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -42,6 +42,7 @@ odpapiinclude_HEADERS = \ $(srcdir)/include/odp/api/cpumask.h \ $(srcdir)/include/odp/api/crypto.h \ $(srcdir)/include/odp/api/debug.h \ + $(srcdir)/include/odp/api/deprecated.h \ $(srcdir)/include/odp/api/errno.h \ $(srcdir)/include/odp/api/event.h \ $(srcdir)/include/odp/api/hash.h \ @@ -154,7 +155,7 @@ noinst_HEADERS = \ ${top_srcdir}/platform/linux-generic/include/odp_schedule_if.h \ ${top_srcdir}/platform/linux-generic/include/odp_sorted_list_internal.h \ ${top_srcdir}/platform/linux-generic/include/odp_shm_internal.h \ - ${srcdir}/include/odp_time_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_time_internal.h \ ${top_srcdir}/platform/linux-generic/include/odp_timer_internal.h \ ${top_srcdir}/platform/linux-generic/include/odp_timer_wheel_internal.h \ ${top_srcdir}/platform/linux-generic/include/odp_traffic_mngr_internal.h \ @@ -217,12 +218,18 @@ __LIB__libodp_dpdk_la_SOURCES = \ arch/@ARCH_DIR@/odp_cpu_arch.c \ arch/@ARCH_DIR@/odp_sysinfo_parse.c +__LIB__libodp_dpdk_la_LIBADD = $(ATOMIC_LIBS) + +if ARCH_IS_X86 +__LIB__libodp_dpdk_la_SOURCES += arch/@ARCH_DIR@/cpu_flags.c +endif + # Create symlink for ABI header files. Application does not need to use the arch # specific include path for installed files. install-data-hook: - if [ -h $(prefix)/include/odp/api/abi ]; then \ - : \ + if [ -h $(DESTDIR)$(prefix)/include/odp/api/abi ]; then \ + : ; \ else \ - $(LN_S) -rf $(prefix)/include/odp/arch/@ARCH_ABI@/odp/api/abi \ - $(prefix)/include/odp/api/abi; \ + $(LN_S) -rf $(DESTDIR)$(prefix)/include/odp/arch/@ARCH_ABI@/odp/api/abi \ + $(DESTDIR)$(prefix)/include/odp/api/abi; \ fi diff --git a/platform/linux-dpdk/include/odp/api/deprecated.h b/platform/linux-dpdk/include/odp/api/deprecated.h new file mode 120000 index 000000000..42bc7ef16 --- /dev/null +++ b/platform/linux-dpdk/include/odp/api/deprecated.h @@ -0,0 +1 @@ +../../../../linux-generic/include/odp/api/deprecated.h
\ No newline at end of file diff --git a/platform/linux-dpdk/include/odp/api/plat/packet_types.h b/platform/linux-dpdk/include/odp/api/plat/packet_types.h index c6ee3966f..5df0a41ec 100644 --- a/platform/linux-dpdk/include/odp/api/plat/packet_types.h +++ b/platform/linux-dpdk/include/odp/api/plat/packet_types.h @@ -99,8 +99,8 @@ typedef union { /** All input flags */ uint64_t all; + /** Individual input flags */ struct { - uint64_t parsed_l2:1; /**< L2 parsed */ uint64_t dst_queue:1; /**< Dst queue present */ uint64_t timestamp:1; /**< Timestamp present */ diff --git a/platform/linux-dpdk/include/odp/api/plat/time_types.h b/platform/linux-dpdk/include/odp/api/plat/time_types.h index e53ad2f97..b42bc83c2 100644..120000 --- a/platform/linux-dpdk/include/odp/api/plat/time_types.h +++ b/platform/linux-dpdk/include/odp/api/plat/time_types.h @@ -1,43 +1 @@ -/* Copyright (c) 2016, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP time service - */ - -#ifndef ODP_TIME_TYPES_H_ -#define ODP_TIME_TYPES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup odp_time - * @{ - **/ - -/** - * @internal Time structure used to isolate odp-linux implementation from - * the linux timespec structure, which is dependent on POSIX extension level. - */ -typedef struct odp_time_t { - int64_t tv_sec; /**< @internal Seconds or DPDK ticks */ - int64_t tv_nsec; /**< @internal Nanoseconds */ -} odp_time_t; - -#define ODP_TIME_NULL ((odp_time_t){0, 0}) - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +../../../../../linux-generic/include/odp/api/plat/time_types.h
\ No newline at end of file diff --git a/platform/linux-dpdk/include/odp_packet_internal.h b/platform/linux-dpdk/include/odp_packet_internal.h index d3f00847e..481e4afb1 100644 --- a/platform/linux-dpdk/include/odp_packet_internal.h +++ b/platform/linux-dpdk/include/odp_packet_internal.h @@ -84,18 +84,6 @@ ODP_STATIC_ASSERT(sizeof(output_flags_t) == sizeof(uint32_t), "OUTPUT_FLAGS_SIZE_ERROR"); /** - * Protocol stack layers - */ -typedef enum { - LAYER_NONE = 0, - LAYER_L1, - LAYER_L2, - LAYER_L3, - LAYER_L4, - LAYER_ALL -} layer_t; - -/** * Packet parser metadata */ typedef struct { @@ -106,14 +94,6 @@ typedef struct { uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */ uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */ uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also ICMP) */ - - uint32_t l3_len; /**< Layer 3 length */ - uint32_t l4_len; /**< Layer 4 length */ - - uint16_t ethtype; /**< EtherType */ - uint8_t ip_proto; /**< IP protocol */ - uint8_t parsed_layers; /**< Highest parsed protocol stack layer */ - } packet_parser_t; /** @@ -190,58 +170,25 @@ static inline void packet_set_len(odp_packet_hdr_t *pkt_hdr, uint32_t len) rte_pktmbuf_pkt_len(&pkt_hdr->buf_hdr.mb) = len; } -static inline int packet_parse_l2_not_done(packet_parser_t *prs) -{ - return !prs->input_flags.parsed_l2; -} - -static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr) -{ - return pkt_hdr->p.parsed_layers != LAYER_ALL; -} - /* Forward declarations */ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt); -/* Fill in parser metadata for L2 */ -static inline void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len) -{ - /* Packet alloc or reset have already init other offsets and flags */ - - /* We only support Ethernet for now */ - prs->input_flags.eth = 1; - - /* Detect jumbo frames */ - if (frame_len > _ODP_ETH_LEN_MAX) - prs->input_flags.jumbo = 1; - - /* Assume valid L2 header, no CRC/FCS check in SW */ - prs->input_flags.l2 = 1; - - prs->input_flags.parsed_l2 = 1; -} +/* Perform packet parse up to a given protocol layer */ +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer); -static inline void _odp_packet_reset_parse(odp_packet_t pkt) +/* Reset parser metadata for a new parse */ +static inline void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) { - odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - - uint32_t frame_len = rte_pktmbuf_pkt_len(&pkt_hdr->buf_hdr.mb); - - pkt_hdr->p.parsed_layers = LAYER_NONE; - pkt_hdr->p.input_flags.all = 0; + /* Reset parser metadata before new parse */ + pkt_hdr->p.error_flags.all = 0; + pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; - pkt_hdr->p.error_flags.all = 0; - pkt_hdr->p.l2_offset = 0; - - packet_parse_l2(&pkt_hdr->p, frame_len); + pkt_hdr->p.l2_offset = 0; + pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID; + pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID; } -/* Perform packet parse up to a given protocol layer */ -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer); - -/* Reset parser metadata for a new parse */ -void packet_parse_reset(odp_packet_hdr_t *pkt_hdr); - /* Convert a packet handle to a buffer handle */ odp_buffer_t _odp_packet_to_buffer(odp_packet_t pkt); @@ -277,7 +224,9 @@ static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts) } int packet_parse_common(packet_parser_t *pkt_hdr, const uint8_t *ptr, - uint32_t pkt_len, uint32_t seg_len, layer_t layer); + uint32_t pkt_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer); + /* We can't enforce tailroom reservation for received packets */ ODP_STATIC_ASSERT(CONFIG_PACKET_TAILROOM == 0, diff --git a/platform/linux-dpdk/include/odp_time_internal.h b/platform/linux-dpdk/include/odp_time_internal.h deleted file mode 100644 index 8cbf81419..000000000 --- a/platform/linux-dpdk/include/odp_time_internal.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2016, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP time service - */ - -#ifndef ODP_TIME_INTERNAL_H_ -#define ODP_TIME_INTERNAL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef uint64_t (*time_to_ns_fn) (odp_time_t time); -typedef odp_time_t (*time_diff_fn) (odp_time_t t2, odp_time_t t1); -typedef odp_time_t (*time_curr_fn)(void); -typedef int (*time_cmp_fn) (odp_time_t t2, odp_time_t t1); -typedef odp_time_t (*time_sum_fn) (odp_time_t t1, odp_time_t t2); -typedef odp_time_t (*time_local_from_ns_fn) (uint64_t ns); -typedef uint64_t (*time_local_res_fn)(void); -typedef uint64_t (*time_to_u64_fn) (odp_time_t time); - -typedef struct time_handler_ { - time_to_ns_fn time_to_ns; - time_diff_fn time_diff; - time_curr_fn time_curr; - time_cmp_fn time_cmp; - time_sum_fn time_sum; - time_local_from_ns_fn time_local_from_ns; - time_local_res_fn time_local_res; - time_to_u64_fn time_to_u64; -} time_handler_t; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/linux-dpdk/m4/configure.m4 b/platform/linux-dpdk/m4/configure.m4 index fb9a91399..230ef6eff 100644 --- a/platform/linux-dpdk/m4/configure.m4 +++ b/platform/linux-dpdk/m4/configure.m4 @@ -28,6 +28,51 @@ AC_LINK_IFELSE( echo "Use newer version. For gcc > 4.7.0" exit -1) +dnl Check whether -latomic is needed +use_libatomic=no + +AC_MSG_CHECKING(whether -latomic is needed for 64-bit atomic built-ins) +AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ + static int loc; + int main(void) + { + int prev = __atomic_exchange_n(&loc, 7, __ATOMIC_RELAXED); + return 0; + } + ]])], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(yes) + AC_CHECK_LIB( + [atomic], [__atomic_exchange_8], + [use_libatomic=yes], + [AC_MSG_CHECKING([__atomic_exchange_8 is not available])]) + ]) + +AC_MSG_CHECKING(whether -latomic is needed for 128-bit atomic built-ins) +AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ + static __int128 loc; + int main(void) + { + __int128 prev; + prev = __atomic_exchange_n(&loc, 7, __ATOMIC_RELAXED); + return 0; + } + ]])], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(yes) + AC_CHECK_LIB( + [atomic], [__atomic_exchange_16], + [use_libatomic=yes], + [AC_MSG_CHECKING([cannot detect support for 128-bit atomics])]) + ]) + +if test "x$use_libatomic" = "xyes"; then + ATOMIC_LIBS="-latomic" +fi +AC_SUBST([ATOMIC_LIBS]) + # linux-generic PCAP support is not relevant as the code doesn't use # linux-generic pktio at all. And DPDK has its own PCAP support anyway AM_CONDITIONAL([HAVE_PCAP], [false]) diff --git a/platform/linux-dpdk/odp_crypto.c b/platform/linux-dpdk/odp_crypto.c index e1f7026ed..d95b15780 100644 --- a/platform/linux-dpdk/odp_crypto.c +++ b/platform/linux-dpdk/odp_crypto.c @@ -94,13 +94,15 @@ static int cipher_alg_odp_to_rte(odp_cipher_alg_t cipher_alg, cipher_xform->cipher.algo = RTE_CRYPTO_CIPHER_3DES_CBC; break; case ODP_CIPHER_ALG_AES_CBC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_CBC: +#endif cipher_xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; break; case ODP_CIPHER_ALG_AES_GCM: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_GCM: +#endif cipher_xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_GCM; break; default: @@ -121,20 +123,31 @@ static int auth_alg_odp_to_rte(odp_auth_alg_t auth_alg, auth_xform->auth.algo = RTE_CRYPTO_AUTH_NULL; break; case ODP_AUTH_ALG_MD5_HMAC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_MD5_96: +#endif auth_xform->auth.algo = RTE_CRYPTO_AUTH_MD5_HMAC; auth_xform->auth.digest_length = 12; break; case ODP_AUTH_ALG_SHA256_HMAC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_SHA256_128: +#endif auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA256_HMAC; auth_xform->auth.digest_length = 16; break; + case ODP_AUTH_ALG_SHA1_HMAC: + auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; + auth_xform->auth.digest_length = 20; + break; + case ODP_AUTH_ALG_SHA512_HMAC: + auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC; + auth_xform->auth.digest_length = 64; + break; case ODP_AUTH_ALG_AES_GCM: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_AES128_GCM: +#endif auth_xform->auth.algo = RTE_CRYPTO_AUTH_AES_GCM; auth_xform->auth.digest_length = 16; break; @@ -151,8 +164,10 @@ static crypto_session_entry_t *alloc_session(void) odp_spinlock_lock(&global->lock); session = global->free; - if (session) + if (session) { global->free = session->next; + session->next = NULL; + } odp_spinlock_unlock(&global->lock); return session; @@ -349,14 +364,16 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) if (cap_cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC) { hw_ciphers->bit.aes_cbc = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_ciphers->bit.aes128_cbc = 1; +#endif } if (cap_cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM) { hw_ciphers->bit.aes_gcm = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_ciphers->bit.aes128_gcm = 1; +#endif } } @@ -373,20 +390,31 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) if (cap_auth_algo == RTE_CRYPTO_AUTH_AES_GCM) { hw_auths->bit.aes_gcm = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_auths->bit.aes128_gcm = 1; +#endif } if (cap_auth_algo == RTE_CRYPTO_AUTH_MD5_HMAC) { hw_auths->bit.md5_hmac = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_auths->bit.md5_96 = 1; +#endif } if (cap_auth_algo == RTE_CRYPTO_AUTH_SHA256_HMAC) { hw_auths->bit.sha256_hmac = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_auths->bit.sha256_128 = 1; +#endif + } + if (cap_auth_algo == + RTE_CRYPTO_AUTH_SHA1_HMAC) { + hw_auths->bit.sha1_hmac = 1; + } + if (cap_auth_algo == + RTE_CRYPTO_AUTH_SHA512_HMAC) { + hw_auths->bit.sha512_hmac = 1; } } cap = &dev_info.capabilities[++i]; @@ -411,14 +439,16 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) if (cap_cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC) { ciphers->bit.aes_cbc = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API ciphers->bit.aes128_cbc = 1; +#endif } if (cap_cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM) { ciphers->bit.aes_gcm = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API ciphers->bit.aes128_gcm = 1; +#endif } } @@ -435,20 +465,31 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) if (cap_auth_algo == RTE_CRYPTO_AUTH_AES_GCM) { auths->bit.aes_gcm = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API auths->bit.aes128_gcm = 1; +#endif } if (cap_auth_algo == RTE_CRYPTO_AUTH_MD5_HMAC) { auths->bit.md5_hmac = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API auths->bit.md5_96 = 1; +#endif } if (cap_auth_algo == RTE_CRYPTO_AUTH_SHA256_HMAC) { auths->bit.sha256_hmac = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API auths->bit.sha256_128 = 1; +#endif + } + if (cap_auth_algo == + RTE_CRYPTO_AUTH_SHA1_HMAC) { + auths->bit.sha1_hmac = 1; + } + if (cap_auth_algo == + RTE_CRYPTO_AUTH_SHA512_HMAC) { + auths->bit.sha512_hmac = 1; } } cap = &dev_info.capabilities[++i]; @@ -547,7 +588,7 @@ int odp_crypto_cipher_capability(odp_cipher_alg_t cipher, int odp_crypto_auth_capability(odp_auth_alg_t auth, odp_crypto_auth_capability_t dst[], - int num_copy) + int num_copy) { odp_crypto_auth_capability_t src[num_copy]; int idx = 0, rc = 0; @@ -740,7 +781,7 @@ static int get_crypto_dev(struct rte_crypto_sym_xform *cipher_xform, return -1; } -int odp_crypto_session_create(odp_crypto_session_params_t *params, +int odp_crypto_session_create(odp_crypto_session_param_t *param, odp_crypto_session_t *session_out, odp_crypto_ses_create_err_t *status) { @@ -771,7 +812,7 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, /* Cipher Data */ cipher_xform.cipher.key.data = rte_malloc("crypto key", - params->cipher_key.length, 0); + param->cipher_key.length, 0); if (cipher_xform.cipher.key.data == NULL) { ODP_ERR("Failed to allocate memory for cipher key\n"); /* remove the crypto_session_entry_t */ @@ -782,14 +823,14 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; cipher_xform.next = NULL; - cipher_xform.cipher.key.length = params->cipher_key.length; + cipher_xform.cipher.key.length = param->cipher_key.length; memcpy(cipher_xform.cipher.key.data, - params->cipher_key.data, - params->cipher_key.length); + param->cipher_key.data, + param->cipher_key.length); /* Authentication Data */ auth_xform.auth.key.data = rte_malloc("auth key", - params->auth_key.length, 0); + param->auth_key.length, 0); if (auth_xform.auth.key.data == NULL) { ODP_ERR("Failed to allocate memory for auth key\n"); /* remove the crypto_session_entry_t */ @@ -799,16 +840,16 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, } auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; auth_xform.next = NULL; - auth_xform.auth.key.length = params->auth_key.length; + auth_xform.auth.key.length = param->auth_key.length; memcpy(auth_xform.auth.key.data, - params->auth_key.data, - params->auth_key.length); + param->auth_key.data, + param->auth_key.length); /* Derive order */ - if (ODP_CRYPTO_OP_ENCODE == params->op) - entry->do_cipher_first = params->auth_cipher_text; + if (ODP_CRYPTO_OP_ENCODE == param->op) + entry->do_cipher_first = param->auth_cipher_text; else - entry->do_cipher_first = !params->auth_cipher_text; + entry->do_cipher_first = !param->auth_cipher_text; /* Process based on cipher */ /* Derive order */ @@ -824,7 +865,7 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, first_xform->next = &cipher_xform; } - rc = cipher_alg_odp_to_rte(params->cipher_alg, &cipher_xform); + rc = cipher_alg_odp_to_rte(param->cipher_alg, &cipher_xform); /* Check result */ if (rc) { @@ -832,7 +873,7 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, return -1; } - rc = auth_alg_odp_to_rte(params->auth_alg, &auth_xform); + rc = auth_alg_odp_to_rte(param->auth_alg, &auth_xform); /* Check result */ if (rc) { @@ -845,7 +886,7 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, rc = get_crypto_dev(&cipher_xform, &auth_xform, - params->iv.length, + param->iv.length, &cdev_id); if (rc) { @@ -868,10 +909,10 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, entry->rte_session = (intptr_t)session; entry->cipher_xform = cipher_xform; entry->auth_xform = auth_xform; - entry->iv.length = params->iv.length; - entry->iv.data = params->iv.data; - entry->output_pool = params->output_pool; - entry->compl_queue = params->compl_queue; + entry->iv.length = param->iv.length; + entry->iv.data = param->iv.data; + entry->output_pool = param->output_pool; + entry->compl_queue = param->compl_queue; /* We're happy */ *session_out = (intptr_t)entry; @@ -903,7 +944,7 @@ int odp_crypto_session_destroy(odp_crypto_session_t session) return 0; } -int odp_crypto_operation(odp_crypto_op_params_t *params, +int odp_crypto_operation(odp_crypto_op_param_t *param, odp_bool_t *posted, odp_crypto_op_result_t *result) { @@ -917,10 +958,10 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, uint8_t *data_addr, *aad_head; struct rte_crypto_op *op; uint16_t rc; - uint32_t plain_len, aad_len; - odp_bool_t pkt_allocated = 0; + uint32_t aad_len; + odp_bool_t allocated = false; - entry = (crypto_session_entry_t *)(intptr_t)params->session; + entry = (crypto_session_entry_t *)(intptr_t)param->session; if (entry == NULL) return -1; @@ -935,71 +976,71 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, auth_xform = entry->auth_xform; /* Resolve output buffer */ - if (ODP_PACKET_INVALID == params->out_pkt && + if (ODP_PACKET_INVALID == param->out_pkt && ODP_POOL_INVALID != entry->output_pool) { - params->out_pkt = odp_packet_alloc(entry->output_pool, - odp_packet_len(params->pkt)); - pkt_allocated = 1; + param->out_pkt = odp_packet_alloc(entry->output_pool, + odp_packet_len(param->pkt)); + allocated = true; } - if (params->pkt != params->out_pkt) { - if (odp_unlikely(ODP_PACKET_INVALID == params->out_pkt)) + if (param->pkt != param->out_pkt) { + if (odp_unlikely(ODP_PACKET_INVALID == param->out_pkt)) ODP_ABORT(); - (void)odp_packet_copy_from_pkt(params->out_pkt, + int ret; + + ret = odp_packet_copy_from_pkt(param->out_pkt, 0, - params->pkt, + param->pkt, 0, - odp_packet_len(params->pkt)); - _odp_packet_copy_md_to_packet(params->pkt, params->out_pkt); - odp_packet_free(params->pkt); - params->pkt = ODP_PACKET_INVALID; + odp_packet_len(param->pkt)); + if (odp_unlikely(ret < 0)) + goto err; + + _odp_packet_copy_md_to_packet(param->pkt, param->out_pkt); + odp_packet_free(param->pkt); + param->pkt = ODP_PACKET_INVALID; } - data_addr = odp_packet_data(params->out_pkt); + data_addr = odp_packet_data(param->out_pkt); odp_spinlock_init(&global->lock); odp_spinlock_lock(&global->lock); op = rte_crypto_op_alloc(global->crypto_op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); if (op == NULL) { - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to allocate crypto operation"); - return -1; + goto err; } odp_spinlock_unlock(&global->lock); /* Set crypto operation data parameters */ rte_crypto_op_attach_sym_session(op, rte_session); - op->sym->auth.digest.data = data_addr + params->hash_result_offset; + op->sym->auth.digest.data = data_addr + param->hash_result_offset; op->sym->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset((struct rte_mbuf *)params->out_pkt, - odp_packet_len(params->out_pkt) - + rte_pktmbuf_mtophys_offset((struct rte_mbuf *)param->out_pkt, + odp_packet_len(param->out_pkt) - auth_xform.auth.digest_length); op->sym->auth.digest.length = auth_xform.auth.digest_length; /* For SNOW3G algorithms, offset/length must be in bits */ if (auth_xform.auth.algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2) { - op->sym->auth.data.offset = params->auth_range.offset << 3; - op->sym->auth.data.length = params->auth_range.length << 3; + op->sym->auth.data.offset = param->auth_range.offset << 3; + op->sym->auth.data.length = param->auth_range.length << 3; } else { - op->sym->auth.data.offset = params->auth_range.offset; - op->sym->auth.data.length = params->auth_range.length; + op->sym->auth.data.offset = param->auth_range.offset; + op->sym->auth.data.length = param->auth_range.length; } - aad_head = data_addr + params->auth_range.offset; - plain_len = params->cipher_range.length; - aad_len = params->auth_range.length - plain_len; + aad_head = param->aad.ptr; + aad_len = param->aad.length; if (aad_len > 0) { op->sym->auth.aad.data = rte_malloc("aad", aad_len, 0); if (op->sym->auth.aad.data == NULL) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to allocate memory for AAD"); - return -1; + goto err; } memcpy(op->sym->auth.aad.data, aad_head, aad_len); @@ -1010,24 +1051,20 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, if (entry->iv.length == 0) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Wrong IV length"); - return -1; + goto err; } op->sym->cipher.iv.data = rte_malloc("iv", entry->iv.length, 0); if (op->sym->cipher.iv.data == NULL) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to allocate memory for IV"); - return -1; + goto err; } - if (params->override_iv_ptr) { + if (param->override_iv_ptr) { memcpy(op->sym->cipher.iv.data, - params->override_iv_ptr, + param->override_iv_ptr, entry->iv.length); } else if (entry->iv.data) { memcpy(op->sym->cipher.iv.data, @@ -1043,27 +1080,25 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, /* For SNOW3G algorithms, offset/length must be in bits */ if (cipher_xform.cipher.algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2) { - op->sym->cipher.data.offset = params->cipher_range.offset << 3; - op->sym->cipher.data.length = params->cipher_range.length << 3; + op->sym->cipher.data.offset = param->cipher_range.offset << 3; + op->sym->cipher.data.length = param->cipher_range.length << 3; } else { - op->sym->cipher.data.offset = params->cipher_range.offset; - op->sym->cipher.data.length = params->cipher_range.length; + op->sym->cipher.data.offset = param->cipher_range.offset; + op->sym->cipher.data.length = param->cipher_range.length; } if (rc_cipher == ODP_CRYPTO_ALG_ERR_NONE && rc_auth == ODP_CRYPTO_ALG_ERR_NONE) { int queue_pair = odp_cpu_id(); - op->sym->m_src = (struct rte_mbuf *)params->out_pkt; + op->sym->m_src = (struct rte_mbuf *)param->out_pkt; rc = rte_cryptodev_enqueue_burst(rte_session->dev_id, queue_pair, &op, 1); if (rc == 0) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to enqueue packet"); - return -1; + goto err; } rc = rte_cryptodev_dequeue_burst(rte_session->dev_id, @@ -1071,18 +1106,16 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, if (rc == 0) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to dequeue packet"); - return -1; + goto err; } - params->out_pkt = (odp_packet_t)op->sym->m_src; + param->out_pkt = (odp_packet_t)op->sym->m_src; } /* Fill in result */ - local_result.ctx = params->ctx; - local_result.pkt = params->out_pkt; + local_result.ctx = param->ctx; + local_result.pkt = param->out_pkt; local_result.cipher_status.alg_err = rc_cipher; local_result.cipher_status.hw_err = ODP_CRYPTO_HW_ERR_NONE; local_result.auth_status.alg_err = rc_auth; @@ -1098,7 +1131,7 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, odp_event_t completion_event; odp_crypto_generic_op_result_t *op_result; - completion_event = odp_packet_to_event(params->out_pkt); + completion_event = odp_packet_to_event(param->out_pkt); _odp_buffer_event_type_set( odp_buffer_from_event(completion_event), ODP_EVENT_CRYPTO_COMPL); @@ -1108,7 +1141,7 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, op_result->result = local_result; if (odp_queue_enq(entry->compl_queue, completion_event)) { odp_event_free(completion_event); - return -1; + goto err; } /* Indicate to caller operation was async */ @@ -1116,14 +1149,21 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, } else { /* Synchronous, simply return results */ if (!result) - return -1; + goto err; *result = local_result; /* Indicate to caller operation was sync */ *posted = 0; } - return 0; + +err: + if (allocated) { + odp_packet_free(param->out_pkt); + param->out_pkt = ODP_PACKET_INVALID; + } + + return -1; } int odp_crypto_term_global(void) diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c index 68ad26b29..0d05e23f2 100644 --- a/platform/linux-dpdk/odp_packet.c +++ b/platform/linux-dpdk/odp_packet.c @@ -21,6 +21,8 @@ #include <stddef.h> #include <inttypes.h> +#include <odp/visibility_begin.h> + /* Fill in packet header field offsets for inline functions */ const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = { @@ -49,6 +51,8 @@ const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = { .rss_flag = PKT_RX_RSS_HASH }; +#include <odp/visibility_end.h> + struct rte_mbuf dummy; ODP_STATIC_ASSERT(sizeof(dummy.data_off) == sizeof(uint16_t), "data_off should be uint16_t"); @@ -77,24 +81,6 @@ static inline odp_packet_hdr_t *buf_to_packet_hdr(odp_buffer_t buf) return (odp_packet_hdr_t *)buf_hdl_to_hdr(buf); } -static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr) -{ - pkt_hdr->p.input_flags.parsed_l2 = 1; - pkt_hdr->p.parsed_layers = LAYER_ALL; -} - -void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) -{ - /* Reset parser metadata before new parse */ - pkt_hdr->p.parsed_layers = LAYER_NONE; - pkt_hdr->p.error_flags.all = 0; - pkt_hdr->p.input_flags.all = 0; - pkt_hdr->p.output_flags.all = 0; - pkt_hdr->p.l2_offset = 0; - pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID; - pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID; -} - static odp_packet_t packet_alloc(pool_entry_t* pool, uint32_t len) { odp_packet_t pkt; @@ -194,7 +180,6 @@ int odp_packet_reset(odp_packet_t pkt, uint32_t len) return -1; } - pkt_hdr->p.parsed_layers = LAYER_NONE; pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; pkt_hdr->p.error_flags.all = 0; @@ -207,9 +192,6 @@ int odp_packet_reset(odp_packet_t pkt, uint32_t len) pkt_hdr->input = ODP_PKTIO_INVALID; - /* Disable lazy parsing on user allocated packets */ - packet_parse_disable(pkt_hdr); - mb->port = 0xff; mb->pkt_len = len; mb->data_off = RTE_PKTMBUF_HEADROOM; @@ -623,8 +605,6 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); return packet_offset_to_ptr(pkt, len, pkt_hdr->p.l3_offset); } @@ -632,8 +612,6 @@ uint32_t odp_packet_l3_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); return pkt_hdr->p.l3_offset; } @@ -644,8 +622,6 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset) if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1))) return -1; - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); pkt_hdr->p.l3_offset = offset; return 0; } @@ -654,8 +630,6 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); return packet_offset_to_ptr(pkt, len, pkt_hdr->p.l4_offset); } @@ -663,8 +637,6 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); return pkt_hdr->p.l4_offset; } @@ -675,8 +647,6 @@ int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset) if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1))) return -1; - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); pkt_hdr->p.l4_offset = offset; return 0; } @@ -1148,12 +1118,11 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr, uint8_t ihl = _ODP_IPV4HDR_IHL(ipv4->ver_ihl); uint16_t frag_offset; uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr); - - prs->l3_len = odp_be_to_cpu_16(ipv4->tot_len); + uint32_t l3_len = odp_be_to_cpu_16(ipv4->tot_len); if (odp_unlikely(ihl < _ODP_IPV4HDR_IHL_MIN) || odp_unlikely(ver != 4) || - (prs->l3_len > frame_len - *offset)) { + (l3_len > frame_len - *offset)) { prs->error_flags.ip_err = 1; return 0; } @@ -1190,13 +1159,12 @@ static inline uint8_t parse_ipv6(packet_parser_t *prs, const uint8_t **parseptr, const _odp_ipv6hdr_t *ipv6 = (const _odp_ipv6hdr_t *)*parseptr; const _odp_ipv6hdr_ext_t *ipv6ext; uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr.u8[0]); - - prs->l3_len = odp_be_to_cpu_16(ipv6->payload_len) + - _ODP_IPV6HDR_LEN; + uint32_t l3_len = odp_be_to_cpu_16(ipv6->payload_len) + + _ODP_IPV6HDR_LEN; /* Basic sanity checks on IPv6 header */ if ((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 || - prs->l3_len > frame_len - *offset) { + l3_len > frame_len - *offset) { prs->error_flags.ip_err = 1; return 0; } @@ -1257,9 +1225,6 @@ static inline void parse_tcp(packet_parser_t *prs, else if ((uint32_t)tcp->hl * 4 > sizeof(_odp_tcphdr_t)) prs->input_flags.tcpopt = 1; - prs->l4_len = prs->l3_len + - prs->l3_offset - prs->l4_offset; - if (offset) *offset += (uint32_t)tcp->hl * 4; *parseptr += (uint32_t)tcp->hl * 4; @@ -1274,13 +1239,8 @@ static inline void parse_udp(packet_parser_t *prs, const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr; uint32_t udplen = odp_be_to_cpu_16(udp->length); - if (udplen < sizeof(_odp_udphdr_t) || - udplen > (prs->l3_len + - prs->l4_offset - prs->l3_offset)) { + if (odp_unlikely(udplen < sizeof(_odp_udphdr_t))) prs->error_flags.udp_err = 1; - } - - prs->l4_len = udplen; if (offset) *offset += sizeof(_odp_udphdr_t); @@ -1294,197 +1254,172 @@ static inline void parse_udp(packet_parser_t *prs, * available from the ptr. */ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, - uint32_t frame_len, uint32_t seg_len, layer_t layer) + uint32_t frame_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer) { uint32_t offset; + uint16_t ethtype; const uint8_t *parseptr; + uint8_t ip_proto; + const _odp_ethhdr_t *eth; + uint16_t macaddr0, macaddr2, macaddr4; + const _odp_vlanhdr_t *vlan; - switch (prs->parsed_layers) { - case LAYER_NONE: - /* Fall through */ + if (layer == ODP_PKTIO_PARSER_LAYER_NONE) + return 0; - case LAYER_L2: - { - const _odp_ethhdr_t *eth; - uint16_t macaddr0, macaddr2, macaddr4; - const _odp_vlanhdr_t *vlan; - - offset = sizeof(_odp_ethhdr_t); - if (packet_parse_l2_not_done(prs)) - packet_parse_l2(prs, frame_len); - - eth = (const _odp_ethhdr_t *)ptr; - - /* Handle Ethernet broadcast/multicast addresses */ - macaddr0 = odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth)); - prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; - - if (macaddr0 == 0xffff) { - macaddr2 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 1)); - macaddr4 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 2)); - prs->input_flags.eth_bcast = - (macaddr2 == 0xffff) && (macaddr4 == 0xffff); - } else { - prs->input_flags.eth_bcast = 0; - } + /* We only support Ethernet for now */ + prs->input_flags.eth = 1; + /* Assume valid L2 header, no CRC/FCS check in SW */ + prs->input_flags.l2 = 1; + /* Detect jumbo frames */ + if (frame_len > _ODP_ETH_LEN_MAX) + prs->input_flags.jumbo = 1; + + offset = sizeof(_odp_ethhdr_t); + eth = (const _odp_ethhdr_t *)ptr; + + /* Handle Ethernet broadcast/multicast addresses */ + macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); + prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; + + if (macaddr0 == 0xffff) { + macaddr2 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 1)); + macaddr4 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 2)); + prs->input_flags.eth_bcast = + (macaddr2 == 0xffff) && (macaddr4 == 0xffff); + } else { + prs->input_flags.eth_bcast = 0; + } - /* Get Ethertype */ - prs->ethtype = odp_be_to_cpu_16(eth->type); - parseptr = (const uint8_t *)(eth + 1); + /* Get Ethertype */ + ethtype = odp_be_to_cpu_16(eth->type); + parseptr = (const uint8_t *)(eth + 1); - /* Check for SNAP vs. DIX */ - if (prs->ethtype < _ODP_ETH_LEN_MAX) { - prs->input_flags.snap = 1; - if (prs->ethtype > frame_len - offset) { - prs->error_flags.snap_len = 1; - goto parse_exit; - } - prs->ethtype = odp_be_to_cpu_16(*((const uint16_t *) - (uintptr_t) - (parseptr + 6))); - offset += 8; - parseptr += 8; + /* Check for SNAP vs. DIX */ + if (ethtype < _ODP_ETH_LEN_MAX) { + prs->input_flags.snap = 1; + if (ethtype > frame_len - offset) { + prs->error_flags.snap_len = 1; + goto parse_exit; } + ethtype = odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) + (parseptr + 6))); + offset += 8; + parseptr += 8; + } - /* Parse the VLAN header(s), if present */ - if (prs->ethtype == _ODP_ETHTYPE_VLAN_OUTER) { - prs->input_flags.vlan_qinq = 1; - prs->input_flags.vlan = 1; - - vlan = (const _odp_vlanhdr_t *)parseptr; - prs->ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } + /* Parse the VLAN header(s), if present */ + if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { + prs->input_flags.vlan_qinq = 1; + prs->input_flags.vlan = 1; - if (prs->ethtype == _ODP_ETHTYPE_VLAN) { - prs->input_flags.vlan = 1; - vlan = (const _odp_vlanhdr_t *)parseptr; - prs->ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + } - prs->l3_offset = offset; - prs->parsed_layers = LAYER_L2; - if (layer == LAYER_L2) - return prs->error_flags.all != 0; + if (ethtype == _ODP_ETHTYPE_VLAN) { + prs->input_flags.vlan = 1; + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); } - /* Fall through */ - case LAYER_L3: - { - offset = prs->l3_offset; - parseptr = (const uint8_t *)(ptr + offset); - /* Set l3_offset+flag only for known ethtypes */ - prs->input_flags.l3 = 1; - - /* Parse Layer 3 headers */ - switch (prs->ethtype) { - case _ODP_ETHTYPE_IPV4: - prs->input_flags.ipv4 = 1; - prs->ip_proto = parse_ipv4(prs, &parseptr, &offset, - frame_len); - break; + if (layer == ODP_PKTIO_PARSER_LAYER_L2) + return prs->error_flags.all != 0; - case _ODP_ETHTYPE_IPV6: - prs->input_flags.ipv6 = 1; - prs->ip_proto = parse_ipv6(prs, &parseptr, &offset, - frame_len, seg_len); - break; + /* Set l3_offset+flag only for known ethtypes */ + prs->l3_offset = offset; + prs->input_flags.l3 = 1; - case _ODP_ETHTYPE_ARP: - prs->input_flags.arp = 1; - prs->ip_proto = 255; /* Reserved invalid by IANA */ - break; + /* Parse Layer 3 headers */ + switch (ethtype) { + case _ODP_ETHTYPE_IPV4: + prs->input_flags.ipv4 = 1; + ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len); + break; - default: - prs->input_flags.l3 = 0; - prs->l3_offset = ODP_PACKET_OFFSET_INVALID; - prs->ip_proto = 255; /* Reserved invalid by IANA */ - } + case _ODP_ETHTYPE_IPV6: + prs->input_flags.ipv6 = 1; + ip_proto = parse_ipv6(prs, &parseptr, &offset, frame_len, + seg_len); + break; - /* Set l4_offset+flag only for known ip_proto */ - prs->l4_offset = offset; - prs->parsed_layers = LAYER_L3; - if (layer == LAYER_L3) - return prs->error_flags.all != 0; - } - /* Fall through */ + case _ODP_ETHTYPE_ARP: + prs->input_flags.arp = 1; + ip_proto = 255; /* Reserved invalid by IANA */ + break; - case LAYER_L4: - { - offset = prs->l4_offset; - parseptr = (const uint8_t *)(ptr + offset); - prs->input_flags.l4 = 1; + default: + prs->input_flags.l3 = 0; + prs->l3_offset = ODP_PACKET_OFFSET_INVALID; + ip_proto = 255; /* Reserved invalid by IANA */ + } - /* Parse Layer 4 headers */ - switch (prs->ip_proto) { - case _ODP_IPPROTO_ICMP: - prs->input_flags.icmp = 1; - break; + if (layer == ODP_PKTIO_PARSER_LAYER_L3) + return prs->error_flags.all != 0; - case _ODP_IPPROTO_TCP: - if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) - return -1; - prs->input_flags.tcp = 1; - parse_tcp(prs, &parseptr, NULL); - break; + /* Set l4_offset+flag only for known ip_proto */ + prs->l4_offset = offset; + prs->input_flags.l4 = 1; - case _ODP_IPPROTO_UDP: - if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) - return -1; - prs->input_flags.udp = 1; - parse_udp(prs, &parseptr, NULL); - break; + /* Parse Layer 4 headers */ + switch (ip_proto) { + case _ODP_IPPROTO_ICMPv4: + /* Fall through */ - case _ODP_IPPROTO_AH: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_ah = 1; - break; + case _ODP_IPPROTO_ICMPv6: + prs->input_flags.icmp = 1; + break; - case _ODP_IPPROTO_ESP: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_esp = 1; - break; + case _ODP_IPPROTO_TCP: + if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) + return -1; + prs->input_flags.tcp = 1; + parse_tcp(prs, &parseptr, NULL); + break; - case _ODP_IPPROTO_SCTP: - prs->input_flags.sctp = 1; - break; + case _ODP_IPPROTO_UDP: + if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) + return -1; + prs->input_flags.udp = 1; + parse_udp(prs, &parseptr, NULL); + break; - default: - prs->input_flags.l4 = 0; - prs->l4_offset = ODP_PACKET_OFFSET_INVALID; - break; - } + case _ODP_IPPROTO_AH: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_ah = 1; + break; - prs->parsed_layers = LAYER_L4; + case _ODP_IPPROTO_ESP: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_esp = 1; break; - } - case LAYER_ALL: + case _ODP_IPPROTO_SCTP: + prs->input_flags.sctp = 1; break; default: - ODP_ERR("Invalid parse layer: %d\n", (int)layer); - return -1; + prs->input_flags.l4 = 0; + prs->l4_offset = ODP_PACKET_OFFSET_INVALID; + break; } - - prs->parsed_layers = LAYER_ALL; - parse_exit: return prs->error_flags.all != 0; } - /** * Simple packet parser */ -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer) +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer) { uint32_t seg_len = odp_packet_seg_len((odp_packet_t)pkt_hdr); uint32_t len = packet_len(pkt_hdr); diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c index 26d32370b..d056a8242 100644 --- a/platform/linux-dpdk/odp_packet_dpdk.c +++ b/platform/linux-dpdk/odp_packet_dpdk.c @@ -369,6 +369,12 @@ static int recv_pkt_dpdk(pktio_entry_t *pktio_entry, int index, (struct rte_mbuf **)pkt_table, (uint16_t)RTE_MAX(len, min)); + if (pktio_entry->s.config.pktin.bit.ts_all || + pktio_entry->s.config.pktin.bit.ts_ptp) { + ts_val = odp_time_global(); + ts = &ts_val; + } + if (nb_rx == 0 && !pkt_dpdk->lockless_tx) { pool_entry_t *pool_entry = get_pool_entry(_odp_typeval(pktio_entry->s.pool)); @@ -382,14 +388,16 @@ static int recv_pkt_dpdk(pktio_entry_t *pktio_entry, int index, odp_ticketlock_unlock(&pkt_dpdk->rx_lock[index]); for (i = 0; i < nb_rx; ++i) { - _odp_packet_reset_parse(pkt_table[i]); - odp_packet_hdr(pkt_table[i])->input = pktio_entry->s.handle; - } + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt_table[i]); - if (pktio_entry->s.config.pktin.bit.ts_all || - pktio_entry->s.config.pktin.bit.ts_ptp) { - ts_val = odp_time_global(); - ts = &ts_val; + packet_parse_reset(pkt_hdr); + pkt_hdr->input = pktio_entry->s.handle; + + if (!pktio_cls_enabled(pktio_entry) && + pktio_entry->s.config.parser.layer) + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); + packet_set_ts(pkt_hdr, ts); } if (odp_unlikely(min > len)) { diff --git a/platform/linux-dpdk/odp_packet_flags.c b/platform/linux-dpdk/odp_packet_flags.c index 20517e164..d8c68f021 100644 --- a/platform/linux-dpdk/odp_packet_flags.c +++ b/platform/linux-dpdk/odp_packet_flags.c @@ -8,26 +8,21 @@ #include <odp/api/packet_flags.h> #include <odp_packet_internal.h> -#define retflag(pkt, x, layer) do { \ +#define retflag(pkt, x) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (pkt_hdr->p.parsed_layers < layer) \ - packet_parse_layer(pkt_hdr, layer); \ return pkt_hdr->p.x; \ } while (0) -#define setflag(pkt, x, v, layer) do { \ +#define setflag(pkt, x, v) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (pkt_hdr->p.parsed_layers < layer) \ - packet_parse_layer(pkt_hdr, layer); \ - pkt_hdr->p.x = v & 1; \ + pkt_hdr->p.x = (v) & 1; \ } while (0) int odp_packet_has_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return odp_packet_hdr(pkt)->p.error_flags.all != 0; + + return pkt_hdr->p.error_flags.all != 0; } /* Get Input Flags */ @@ -44,126 +39,117 @@ int odp_packet_has_l2_error(odp_packet_t pkt) int odp_packet_has_l3(odp_packet_t pkt) { - retflag(pkt, input_flags.l3, LAYER_L3); + retflag(pkt, input_flags.l3); } int odp_packet_has_l3_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return pkt_hdr->p.error_flags.ip_err; } int odp_packet_has_l4(odp_packet_t pkt) { - retflag(pkt, input_flags.l4, LAYER_L4); + retflag(pkt, input_flags.l4); } int odp_packet_has_l4_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); - return pkt_hdr->p.error_flags.tcp_err | pkt_hdr->p.error_flags.udp_err; } int odp_packet_has_eth_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_bcast, LAYER_L2); + retflag(pkt, input_flags.eth_bcast); } int odp_packet_has_eth_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_mcast, LAYER_L2); + retflag(pkt, input_flags.eth_mcast); } int odp_packet_has_vlan(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan, LAYER_L2); + retflag(pkt, input_flags.vlan); } int odp_packet_has_vlan_qinq(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan_qinq, LAYER_L2); + retflag(pkt, input_flags.vlan_qinq); } int odp_packet_has_arp(odp_packet_t pkt) { - retflag(pkt, input_flags.arp, LAYER_L3); + retflag(pkt, input_flags.arp); } int odp_packet_has_ipv4(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv4, LAYER_L3); + retflag(pkt, input_flags.ipv4); } int odp_packet_has_ipv6(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv6, LAYER_L3); + retflag(pkt, input_flags.ipv6); } int odp_packet_has_ip_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_bcast, LAYER_L3); + retflag(pkt, input_flags.ip_bcast); } int odp_packet_has_ip_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_mcast, LAYER_L3); + retflag(pkt, input_flags.ip_mcast); } int odp_packet_has_ipfrag(odp_packet_t pkt) { - retflag(pkt, input_flags.ipfrag, LAYER_L3); + retflag(pkt, input_flags.ipfrag); } int odp_packet_has_ipopt(odp_packet_t pkt) { - retflag(pkt, input_flags.ipopt, LAYER_L3); + retflag(pkt, input_flags.ipopt); } int odp_packet_has_ipsec(odp_packet_t pkt) { - retflag(pkt, input_flags.ipsec, LAYER_L4); + retflag(pkt, input_flags.ipsec); } int odp_packet_has_udp(odp_packet_t pkt) { - retflag(pkt, input_flags.udp, LAYER_L4); + retflag(pkt, input_flags.udp); } int odp_packet_has_tcp(odp_packet_t pkt) { - retflag(pkt, input_flags.tcp, LAYER_L4); + retflag(pkt, input_flags.tcp); } int odp_packet_has_sctp(odp_packet_t pkt) { - retflag(pkt, input_flags.sctp, LAYER_L4); + retflag(pkt, input_flags.sctp); } int odp_packet_has_icmp(odp_packet_t pkt) { - retflag(pkt, input_flags.icmp, LAYER_L4); + retflag(pkt, input_flags.icmp); } odp_packet_color_t odp_packet_color(odp_packet_t pkt) { - retflag(pkt, input_flags.color, LAYER_ALL); + retflag(pkt, input_flags.color); } void odp_packet_color_set(odp_packet_t pkt, odp_packet_color_t color) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - pkt_hdr->p.input_flags.color = color; } @@ -171,29 +157,23 @@ odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return !pkt_hdr->p.input_flags.nodrop; } void odp_packet_drop_eligible_set(odp_packet_t pkt, odp_bool_t drop) { - setflag(pkt, input_flags.nodrop, !drop, LAYER_ALL); + setflag(pkt, input_flags.nodrop, !drop); } int8_t odp_packet_shaper_len_adjust(odp_packet_t pkt) { - retflag(pkt, output_flags.shaper_len_adj, LAYER_ALL); + retflag(pkt, output_flags.shaper_len_adj); } void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - pkt_hdr->p.output_flags.shaper_len_adj = adj; } @@ -201,107 +181,107 @@ void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj) void odp_packet_has_l2_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l2, val, LAYER_L2); + setflag(pkt, input_flags.l2, val); } void odp_packet_has_l3_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l3, val, LAYER_L3); + setflag(pkt, input_flags.l3, val); } void odp_packet_has_l4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l4, val, LAYER_L4); + setflag(pkt, input_flags.l4, val); } void odp_packet_has_eth_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth, val, LAYER_L2); + setflag(pkt, input_flags.eth, val); } void odp_packet_has_eth_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_bcast, val, LAYER_L2); + setflag(pkt, input_flags.eth_bcast, val); } void odp_packet_has_eth_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_mcast, val, LAYER_L2); + setflag(pkt, input_flags.eth_mcast, val); } void odp_packet_has_jumbo_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.jumbo, val, LAYER_L2); + setflag(pkt, input_flags.jumbo, val); } void odp_packet_has_vlan_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan, val, LAYER_L2); + setflag(pkt, input_flags.vlan, val); } void odp_packet_has_vlan_qinq_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan_qinq, val, LAYER_L2); + setflag(pkt, input_flags.vlan_qinq, val); } void odp_packet_has_arp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.arp, val, LAYER_L3); + setflag(pkt, input_flags.arp, val); } void odp_packet_has_ipv4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv4, val, LAYER_L3); + setflag(pkt, input_flags.ipv4, val); } void odp_packet_has_ipv6_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv6, val, LAYER_L3); + setflag(pkt, input_flags.ipv6, val); } void odp_packet_has_ip_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_bcast, val, LAYER_L3); + setflag(pkt, input_flags.ip_bcast, val); } void odp_packet_has_ip_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_mcast, val, LAYER_L3); + setflag(pkt, input_flags.ip_mcast, val); } void odp_packet_has_ipfrag_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipfrag, val, LAYER_L3); + setflag(pkt, input_flags.ipfrag, val); } void odp_packet_has_ipopt_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipopt, val, LAYER_L3); + setflag(pkt, input_flags.ipopt, val); } void odp_packet_has_ipsec_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipsec, val, LAYER_L4); + setflag(pkt, input_flags.ipsec, val); } void odp_packet_has_udp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.udp, val, LAYER_L4); + setflag(pkt, input_flags.udp, val); } void odp_packet_has_tcp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.tcp, val, LAYER_L4); + setflag(pkt, input_flags.tcp, val); } void odp_packet_has_sctp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.sctp, val, LAYER_L4); + setflag(pkt, input_flags.sctp, val); } void odp_packet_has_icmp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.icmp, val, LAYER_L4); + setflag(pkt, input_flags.icmp, val); } void odp_packet_has_ts_clr(odp_packet_t pkt) diff --git a/platform/linux-dpdk/odp_pool.c b/platform/linux-dpdk/odp_pool.c index e6d415954..0821cdcac 100644 --- a/platform/linux-dpdk/odp_pool.c +++ b/platform/linux-dpdk/odp_pool.c @@ -240,7 +240,8 @@ static int check_params(odp_pool_param_t *params) { odp_pool_capability_t capa; - odp_pool_capability(&capa); + if (odp_pool_capability(&capa) < 0) + return -1; switch (params->type) { case ODP_POOL_BUFFER: @@ -552,6 +553,8 @@ static odp_buffer_t buffer_alloc(pool_entry_t *pool) odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl) { + ODP_ASSERT(ODP_POOL_INVALID != pool_hdl); + pool_entry_t *pool = odp_pool_to_entry(pool_hdl); return buffer_alloc(pool); @@ -560,6 +563,9 @@ odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl) int odp_buffer_alloc_multi(odp_pool_t pool_hdl, odp_buffer_t buf[], int num) { int i; + + ODP_ASSERT(ODP_POOL_INVALID != pool_hdl); + pool_entry_t *pool = odp_pool_to_entry(pool_hdl); for (i = 0; i < num; i++) { diff --git a/platform/linux-dpdk/odp_time.c b/platform/linux-dpdk/odp_time.c index c1ad973cc..6c066a5b5 100644 --- a/platform/linux-dpdk/odp_time.c +++ b/platform/linux-dpdk/odp_time.c @@ -13,105 +13,182 @@ #include <odp_time_internal.h> #include <rte_cycles.h> #include <string.h> +#include <inttypes.h> + +typedef uint64_t (*time_to_ns_fn) (odp_time_t time); +typedef odp_time_t (*time_cur_fn)(void); +typedef odp_time_t (*time_from_ns_fn) (uint64_t ns); +typedef uint64_t (*time_res_fn)(void); + +typedef struct time_handler_ { + time_to_ns_fn time_to_ns; + time_cur_fn time_cur; + time_from_ns_fn time_from_ns; + time_res_fn time_res; +} time_handler_t; + +typedef struct time_global_t { + struct timespec spec_start; + int use_hw; + uint64_t hw_start; + uint64_t hw_freq_hz; + /* DPDK specific */ + time_handler_t handler; + double tick_per_nsec; + double nsec_per_tick; +} time_global_t; + +static time_global_t global; + +/* + * Posix timespec based functions + */ + +static inline uint64_t time_spec_diff_nsec(struct timespec *t2, + struct timespec *t1) +{ + struct timespec diff; + uint64_t nsec; + + diff.tv_sec = t2->tv_sec - t1->tv_sec; + diff.tv_nsec = t2->tv_nsec - t1->tv_nsec; -typedef union { - odp_time_t ex; - struct timespec in; -} _odp_time_t; + if (diff.tv_nsec < 0) { + diff.tv_nsec += ODP_TIME_SEC_IN_NS; + diff.tv_sec -= 1; + } + + nsec = (diff.tv_sec * ODP_TIME_SEC_IN_NS) + diff.tv_nsec; -static odp_time_t start_time; -static time_handler_t time_handler; -double tick_per_nsec; -double nsec_per_tick; + return nsec; +} -static inline uint64_t time_local_res_dpdk(void) +static inline odp_time_t time_spec_cur(void) { - return rte_get_timer_hz(); + int ret; + odp_time_t time; + struct timespec sys_time; + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time); + if (odp_unlikely(ret != 0)) + ODP_ABORT("clock_gettime failed\n"); + + time.nsec = time_spec_diff_nsec(&sys_time, &global.spec_start); + + return time; } -static inline -uint64_t time_to_ns(odp_time_t time) +static inline uint64_t time_spec_res(void) { - uint64_t ns; + int ret; + struct timespec tres; - ns = time.tv_sec * ODP_TIME_SEC_IN_NS; - ns += time.tv_nsec; + ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); + if (odp_unlikely(ret != 0)) + ODP_ABORT("clock_getres failed\n"); - return ns; + return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; } -static inline uint64_t time_to_ns_dpdk(odp_time_t time) +static inline uint64_t time_spec_to_ns(odp_time_t time) { - return (time.tv_sec * nsec_per_tick); + return time.nsec; } -static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1) +static inline odp_time_t time_spec_from_ns(uint64_t ns) { odp_time_t time; - time.tv_sec = t2.tv_sec - t1.tv_sec; - time.tv_nsec = t2.tv_nsec - t1.tv_nsec; - - if (time.tv_nsec < 0) { - time.tv_nsec += ODP_TIME_SEC_IN_NS; - --time.tv_sec; - } + time.nsec = ns; return time; } -static inline odp_time_t time_diff_dpdk(odp_time_t t2, odp_time_t t1) +/* + * HW time counter based functions + */ + +static inline odp_time_t time_hw_cur(void) { odp_time_t time; - time.tv_sec = t2.tv_sec - t1.tv_sec; + time.count = cpu_global_time() - global.hw_start; + return time; } -static inline odp_time_t time_curr(void) +static inline uint64_t time_hw_res(void) { - int ret; - _odp_time_t time; + /* Promise a bit lower resolution than average cycle counter + * frequency */ + return global.hw_freq_hz / 10; +} - ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time.in); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_gettime failed\n"); - return time.ex; +static inline uint64_t time_hw_to_ns(odp_time_t time) +{ + uint64_t nsec; + uint64_t freq_hz = global.hw_freq_hz; + uint64_t count = time.count; + uint64_t sec = 0; + + if (count >= freq_hz) { + sec = count / freq_hz; + count = count - sec * freq_hz; + } + + nsec = (ODP_TIME_SEC_IN_NS * count) / freq_hz; + + return (sec * ODP_TIME_SEC_IN_NS) + nsec; } -static inline odp_time_t time_curr_dpdk(void) +static inline odp_time_t time_hw_from_ns(uint64_t ns) { odp_time_t time; + uint64_t count; + uint64_t freq_hz = global.hw_freq_hz; + uint64_t sec = 0; + + if (ns >= ODP_TIME_SEC_IN_NS) { + sec = ns / ODP_TIME_SEC_IN_NS; + ns = ns - sec * ODP_TIME_SEC_IN_NS; + } + + count = sec * freq_hz; + count += (ns * freq_hz) / ODP_TIME_SEC_IN_NS; + + time.count = count; - time.tv_sec = rte_get_timer_cycles(); return time; } -static inline odp_time_t time_local(void) +/* + * Common functions + */ + +static inline odp_time_t time_cur(void) { - odp_time_t time; + if (global.use_hw) + return time_hw_cur(); - time = time_handler.time_curr(); - return time_handler.time_diff(time, start_time); + return time_spec_cur(); } -static inline int time_cmp(odp_time_t t2, odp_time_t t1) +static inline uint64_t time_res(void) { - if (t2.tv_sec < t1.tv_sec) - return -1; - - if (t2.tv_sec > t1.tv_sec) - return 1; + if (global.use_hw) + return time_hw_res(); - return t2.tv_nsec - t1.tv_nsec; + return time_spec_res(); } -static inline int time_cmp_dpdk(odp_time_t t2, odp_time_t t1) +static inline int time_cmp(odp_time_t t2, odp_time_t t1) { - if (t2.tv_sec < t1.tv_sec) - return -1; - if (t2.tv_sec > t1.tv_sec) + if (odp_likely(t2.u64 > t1.u64)) return 1; + + if (t2.u64 < t1.u64) + return -1; + return 0; } @@ -119,61 +196,67 @@ static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2) { odp_time_t time; - time.tv_sec = t2.tv_sec + t1.tv_sec; - time.tv_nsec = t2.tv_nsec + t1.tv_nsec; - - if (time.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) { - time.tv_nsec -= ODP_TIME_SEC_IN_NS; - ++time.tv_sec; - } + time.u64 = t1.u64 + t2.u64; return time; } -static inline odp_time_t time_sum_dpdk(odp_time_t t1, odp_time_t t2) +static inline uint64_t time_to_ns(odp_time_t time) { - odp_time_t time; + if (global.use_hw) + return time_hw_to_ns(time); - time.tv_sec = t2.tv_sec + t1.tv_sec; - return time; + return time_spec_to_ns(time); +} + +static inline odp_time_t time_from_ns(uint64_t ns) +{ + if (global.use_hw) + return time_hw_from_ns(ns); + + return time_spec_from_ns(ns); +} + +static inline uint64_t time_res_dpdk(void) +{ + return rte_get_timer_hz(); } -static inline odp_time_t time_local_from_ns(uint64_t ns) +static inline uint64_t time_to_ns_dpdk(odp_time_t time) +{ + return (time.u64 * global.nsec_per_tick); +} + +static inline odp_time_t time_cur_dpdk(void) { odp_time_t time; - time.tv_sec = ns / ODP_TIME_SEC_IN_NS; - time.tv_nsec = ns - time.tv_sec * ODP_TIME_SEC_IN_NS; + time.u64 = rte_get_timer_cycles() - global.hw_start; return time; } -static inline odp_time_t time_local_from_ns_dpdk(uint64_t ns) +static inline odp_time_t time_from_ns_dpdk(uint64_t ns) { odp_time_t time; - time.tv_sec = ns * tick_per_nsec; + + time.u64 = ns * global.tick_per_nsec; + return time; } +static inline odp_time_t time_local(void) +{ + return global.handler.time_cur(); +} + static inline void time_wait_until(odp_time_t time) { odp_time_t cur; do { cur = time_local(); - } while (time_handler.time_cmp(time, cur) > 0); -} - -static inline uint64_t time_local_res(void) -{ - int ret; - struct timespec tres; - - ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_getres failed\n"); - - return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; + } while (time_cmp(time, cur) > 0); } odp_time_t odp_time_local(void) @@ -188,49 +271,53 @@ odp_time_t odp_time_global(void) odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1) { - return time_handler.time_diff(t2, t1); + odp_time_t time; + + time.u64 = t2.u64 - t1.u64; + + return time; } uint64_t odp_time_to_ns(odp_time_t time) { - return time_handler.time_to_ns(time); + return global.handler.time_to_ns(time); } odp_time_t odp_time_local_from_ns(uint64_t ns) { - return time_handler.time_local_from_ns(ns); + return global.handler.time_from_ns(ns); } odp_time_t odp_time_global_from_ns(uint64_t ns) { - return time_handler.time_local_from_ns(ns); + return global.handler.time_from_ns(ns); } int odp_time_cmp(odp_time_t t2, odp_time_t t1) { - return time_handler.time_cmp(t2, t1); + return time_cmp(t2, t1); } odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2) { - return time_handler.time_sum(t1, t2); + return time_sum(t1, t2); } uint64_t odp_time_local_res(void) { - return time_handler.time_local_res(); + return global.handler.time_res(); } uint64_t odp_time_global_res(void) { - return time_handler.time_local_res(); + return global.handler.time_res(); } void odp_time_wait_ns(uint64_t ns) { odp_time_t cur = time_local(); - odp_time_t wait = time_handler.time_local_from_ns(ns); - odp_time_t end_time = time_handler.time_sum(cur, wait); + odp_time_t wait = global.handler.time_from_ns(ns); + odp_time_t end_time = time_sum(cur, wait); time_wait_until(end_time); } @@ -240,31 +327,6 @@ void odp_time_wait_until(odp_time_t time) return time_wait_until(time); } -static uint64_t time_to_u64(odp_time_t time) -{ - int ret; - struct timespec tres; - uint64_t resolution; - - ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_getres failed\n"); - - resolution = (uint64_t)tres.tv_nsec; - - return time_handler.time_to_ns(time) / resolution; -} - -static uint64_t time_to_u64_dpdk(odp_time_t time) -{ - return time.tv_sec; -} - -uint64_t odp_time_to_u64(odp_time_t time) -{ - return time_handler.time_to_u64(time); -} - static odp_bool_t is_invariant_tsc_supported(void) { FILE *file; @@ -311,37 +373,52 @@ static inline odp_bool_t is_dpdk_timer_cycles_support(void) int odp_time_init_global(void) { + int ret = 0; + + memset(&global, 0, sizeof(time_global_t)); + if (is_dpdk_timer_cycles_support()) { - time_handler.time_to_ns = time_to_ns_dpdk; - time_handler.time_diff = time_diff_dpdk; - time_handler.time_curr = time_curr_dpdk; - time_handler.time_cmp = time_cmp_dpdk; - time_handler.time_sum = time_sum_dpdk; - time_handler.time_local_from_ns = time_local_from_ns_dpdk; - time_handler.time_local_res = time_local_res_dpdk; - time_handler.time_to_u64 = time_to_u64_dpdk; - tick_per_nsec = (double)time_local_res_dpdk() / + global.handler.time_to_ns = time_to_ns_dpdk; + global.handler.time_cur = time_cur_dpdk; + global.handler.time_from_ns = time_from_ns_dpdk; + global.handler.time_res = time_res_dpdk; + global.tick_per_nsec = (double)time_res_dpdk() / (double)ODP_TIME_SEC_IN_NS; - nsec_per_tick = (double)ODP_TIME_SEC_IN_NS / - (double)time_local_res_dpdk(); - } else { - time_handler.time_to_ns = time_to_ns; - time_handler.time_diff = time_diff; - time_handler.time_curr = time_curr; - time_handler.time_cmp = time_cmp; - time_handler.time_sum = time_sum; - time_handler.time_local_from_ns = time_local_from_ns; - time_handler.time_local_res = time_local_res; - time_handler.time_to_u64 = time_to_u64; + global.nsec_per_tick = (double)ODP_TIME_SEC_IN_NS / + (double)time_res_dpdk(); + + global.hw_start = rte_get_timer_cycles(); + if (global.hw_start == 0) + return -1; + else + return 0; } - start_time = time_handler.time_curr(); - if (time_handler.time_cmp(start_time, ODP_TIME_NULL) == 0) { - ODP_ABORT("initiate odp time failed\n"); - return -1; - } else { + global.handler.time_to_ns = time_to_ns; + global.handler.time_cur = time_cur; + global.handler.time_from_ns = time_from_ns; + global.handler.time_res = time_res; + + if (cpu_has_global_time()) { + global.use_hw = 1; + global.hw_freq_hz = cpu_global_time_freq(); + + if (global.hw_freq_hz == 0) + return -1; + + printf("HW time counter freq: %" PRIu64 " hz\n\n", + global.hw_freq_hz); + + global.hw_start = cpu_global_time(); return 0; } + + global.spec_start.tv_sec = 0; + global.spec_start.tv_nsec = 0; + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &global.spec_start); + + return ret; } int odp_time_term_global(void) |