From: Kumar Amber <kumar.am...@intel.com> This patch adds support for selecting the recirculation implementation based on the DPIF implementation.
Signed-off-by: Kumar Amber <kumar.am...@intel.com> Signed-off-by: Cian Ferriter <cian.ferri...@intel.com> Co-authored-by: Cian Ferriter <cian.ferri...@intel.com> Acked-by: Sunil Pai G <sunil.pa...@intel.com> --- lib/dpif-netdev-private-dpif.c | 73 +++++++++++++++++++++++--------- lib/dpif-netdev-private-dpif.h | 18 ++++++++ lib/dpif-netdev-private-thread.h | 3 ++ lib/dpif-netdev.c | 14 +++++- 4 files changed, 88 insertions(+), 20 deletions(-) diff --git a/lib/dpif-netdev-private-dpif.c b/lib/dpif-netdev-private-dpif.c index 07039b1c2..3c7218ca0 100644 --- a/lib/dpif-netdev-private-dpif.c +++ b/lib/dpif-netdev-private-dpif.c @@ -55,18 +55,39 @@ dp_netdev_input_avx512_probe(void) static struct dpif_netdev_impl_info_t dpif_impls[] = { /* The default scalar C code implementation. */ [DPIF_NETDEV_IMPL_SCALAR] = { .input_func = dp_netdev_input, + .recirc_func = dp_netdev_recirculate, .probe = NULL, .name = "dpif_scalar", }, #if DPIF_NETDEV_IMPL_AVX512_CHECK /* Only available on x86_64 bit builds with SSE 4.2 used for OVS core. */ [DPIF_NETDEV_IMPL_AVX512] = { .input_func = dp_netdev_input_avx512, + .recirc_func = dp_netdev_input_avx512_recirc, .probe = dp_netdev_input_avx512_probe, .name = "dpif_avx512", }, #endif }; static dp_netdev_input_func default_dpif_func; +static dp_netdev_recirc_func default_dpif_recirc_func; + +static inline int +dp_netdev_dpif_probe(int dpif_idx) +{ +/* Configure-time overriding to run test suite on all implementations. */ +#if DPIF_NETDEV_IMPL_AVX512_CHECK +#ifdef DPIF_AVX512_DEFAULT + dp_netdev_input_func_probe probe; + + /* Check if the compiled default is compatible. */ + probe = dpif_impls[DPIF_NETDEV_IMPL_AVX512].probe; + if (!probe || !probe()) { + dpif_idx = DPIF_NETDEV_IMPL_AVX512; + } +#endif +#endif + return dpif_idx; +} dp_netdev_input_func dp_netdev_impl_get_default(void) @@ -76,18 +97,7 @@ dp_netdev_impl_get_default(void) if (!default_dpif_func) { int dpif_idx = DPIF_NETDEV_IMPL_SCALAR; -/* Configure-time overriding to run test suite on all implementations. */ -#if DPIF_NETDEV_IMPL_AVX512_CHECK -#ifdef DPIF_AVX512_DEFAULT - dp_netdev_input_func_probe probe; - - /* Check if the compiled default is compatible. */ - probe = dpif_impls[DPIF_NETDEV_IMPL_AVX512].probe; - if (!probe || !probe()) { - dpif_idx = DPIF_NETDEV_IMPL_AVX512; - } -#endif -#endif + dpif_idx = dp_netdev_dpif_probe(dpif_idx); VLOG_INFO("Default DPIF implementation is %s.\n", dpif_impls[dpif_idx].name); @@ -97,6 +107,24 @@ dp_netdev_impl_get_default(void) return default_dpif_func; } +dp_netdev_recirc_func +dp_netdev_recirc_impl_get_default(void) +{ + /* For the first call, this will be NULL. Compute the compile time default. + */ + if (!default_dpif_recirc_func) { + int dpif_idx = DPIF_NETDEV_IMPL_SCALAR; + + dpif_idx = dp_netdev_dpif_probe(dpif_idx); + + VLOG_INFO("Default re-circulate DPIF implementation is %s.\n", + dpif_impls[dpif_idx].name); + default_dpif_recirc_func = dpif_impls[dpif_idx].recirc_func; + } + + return default_dpif_recirc_func; +} + void dp_netdev_impl_get(struct ds *reply, struct dp_netdev_pmd_thread **pmd_list, size_t n) @@ -132,10 +160,12 @@ dp_netdev_impl_get(struct ds *reply, struct dp_netdev_pmd_thread **pmd_list, * returns the function pointer to the one requested by "name". */ static int32_t -dp_netdev_impl_get_by_name(const char *name, dp_netdev_input_func *out_func) +dp_netdev_impl_get_by_name(const char *name, dp_netdev_input_func *dpif_func, + dp_netdev_recirc_func *dpif_recirc_func) { ovs_assert(name); - ovs_assert(out_func); + ovs_assert(dpif_func); + ovs_assert(dpif_recirc_func); uint32_t i; @@ -145,11 +175,13 @@ dp_netdev_impl_get_by_name(const char *name, dp_netdev_input_func *out_func) if (dpif_impls[i].probe) { int probe_err = dpif_impls[i].probe(); if (probe_err) { - *out_func = NULL; + *dpif_func = NULL; + *dpif_recirc_func = NULL; return probe_err; } } - *out_func = dpif_impls[i].input_func; + *dpif_func = dpif_impls[i].input_func; + *dpif_recirc_func = dpif_impls[i].recirc_func; return 0; } } @@ -160,12 +192,15 @@ dp_netdev_impl_get_by_name(const char *name, dp_netdev_input_func *out_func) int32_t dp_netdev_impl_set_default_by_name(const char *name) { - dp_netdev_input_func new_default; + dp_netdev_input_func new_dpif_default; + dp_netdev_recirc_func new_dpif_recirc_default; - int32_t err = dp_netdev_impl_get_by_name(name, &new_default); + int32_t err = dp_netdev_impl_get_by_name(name, &new_dpif_default, + &new_dpif_recirc_default); if (!err) { - default_dpif_func = new_default; + default_dpif_func = new_dpif_default; + default_dpif_recirc_func = new_dpif_recirc_default; } return err; diff --git a/lib/dpif-netdev-private-dpif.h b/lib/dpif-netdev-private-dpif.h index 4465d034f..dd4fedec3 100644 --- a/lib/dpif-netdev-private-dpif.h +++ b/lib/dpif-netdev-private-dpif.h @@ -36,6 +36,16 @@ typedef int32_t (*dp_netdev_input_func)(struct dp_netdev_pmd_thread *pmd, struct dp_packet_batch *packets, odp_port_t port_no); +/* Typedef for DPIF re-circulate functions. + * The implementation on success must handle the whole batch of packets. + * The implementation on failure must return the error code and also + * the batch of packets must be unchnaged. After failure, scalar dpif + * is called and is expected to handle packet processing thereafter. + * Returns 0 on sucess else returns error code on failure. + */ +typedef int32_t (*dp_netdev_recirc_func)(struct dp_netdev_pmd_thread *pmd, + struct dp_packet_batch *packets); + /* Probe a DPIF implementation. This allows the implementation to validate CPU * ISA availability. Returns -ENOTSUP if not available, returns 0 if valid to * use. @@ -46,6 +56,10 @@ typedef int32_t (*dp_netdev_input_func_probe)(void); struct dpif_netdev_impl_info_t { /* Function pointer to execute to have this DPIF implementation run. */ dp_netdev_input_func input_func; + + /* Function pointer to execute recirc DPIF implementation. */ + dp_netdev_recirc_func recirc_func; + /* Function pointer to execute to check the CPU ISA is available to run. If * not necessary, it must be set to NULL which implies that it is always * valid to use. */ @@ -63,6 +77,10 @@ dp_netdev_impl_get(struct ds *reply, struct dp_netdev_pmd_thread **pmd_list, * overridden at runtime. */ dp_netdev_input_func dp_netdev_impl_get_default(void); +/* Returns the default recirculate DPIF which is first ./configure selected, + * but can be overridden at runtime. */ +dp_netdev_recirc_func dp_netdev_recirc_impl_get_default(void); + /* Overrides the default DPIF with the user set DPIF. */ int32_t dp_netdev_impl_set_default_by_name(const char *name); diff --git a/lib/dpif-netdev-private-thread.h b/lib/dpif-netdev-private-thread.h index 4472b199d..bce91358b 100644 --- a/lib/dpif-netdev-private-thread.h +++ b/lib/dpif-netdev-private-thread.h @@ -124,6 +124,9 @@ struct dp_netdev_pmd_thread { /* Function pointer to call for dp_netdev_input() functionality. */ ATOMIC(dp_netdev_input_func) netdev_input_func; + /* Function pointer to call for dp_netdev_recirculate() functionality. */ + ATOMIC(dp_netdev_recirc_func) netdev_input_recirc_func; + /* Pointer for per-DPIF implementation scratch space. */ void *netdev_input_func_userdata; diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index a50571dc8..99102c5a0 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1148,6 +1148,10 @@ dpif_netdev_impl_set(struct unixctl_conn *conn, int argc OVS_UNUSED, * default. */ atomic_store_relaxed(&pmd->netdev_input_func, dp_netdev_impl_get_default()); + /* Initialize recirc DPIF function pointer to the newly configured + * default. */ + atomic_store_relaxed(&pmd->netdev_input_recirc_func, + dp_netdev_recirc_impl_get_default()); }; free(pmd_list); @@ -7473,6 +7477,11 @@ dp_netdev_configure_pmd(struct dp_netdev_pmd_thread *pmd, struct dp_netdev *dp, /* Initialize DPIF function pointer to the default configured version. */ atomic_init(&pmd->netdev_input_func, dp_netdev_impl_get_default()); + /* Initialize recirculate DPIF function pointer to the default configured + * version. */ + atomic_init(&pmd->netdev_input_recirc_func, + dp_netdev_recirc_impl_get_default()); + /* Init default miniflow_extract function */ atomic_init(&pmd->miniflow_extract_opt, dp_mfex_impl_get_default()); @@ -8818,7 +8827,10 @@ dp_execute_cb(void *aux_, struct dp_packet_batch *packets_, } (*depth)++; - dp_netdev_recirculate(pmd, packets_); + int ret = pmd->netdev_input_recirc_func(pmd, packets_); + if (ret != 0) { + dp_netdev_recirculate(pmd, packets_); + } (*depth)--; return; } -- 2.25.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev