The patch adds the subtable lookup name to the existing dp-extra-info mentioned below:
dp-extra-info:miniflow_bits(18,4), lookup(generic) dp-extra-info:miniflow_bits(9,4), lookup(avx512_gather) Suggested-by: Ilya Maximets <i.maxim...@ovn.org> Signed-off-by: Kumar Amber <kumar.am...@intel.com> --- v2: - Add RCU protection for ds_extra_info. - Add string regeneration for dpcls reprobe. --- --- lib/dpif-netdev-lookup.c | 39 +++++++++++++++++++++++++++++---- lib/dpif-netdev-lookup.h | 14 +++++++++++- lib/dpif-netdev-private-dpcls.h | 3 +++ lib/dpif-netdev-private-flow.h | 6 +++-- lib/dpif-netdev.c | 26 +++++++++++++++++----- 5 files changed, 76 insertions(+), 12 deletions(-) diff --git a/lib/dpif-netdev-lookup.c b/lib/dpif-netdev-lookup.c index bd0a99abe..e20a45589 100644 --- a/lib/dpif-netdev-lookup.c +++ b/lib/dpif-netdev-lookup.c @@ -20,6 +20,8 @@ #include "openvswitch/vlog.h" +#define SUBTABLE_STRING_OFFSET 18 + VLOG_DEFINE_THIS_MODULE(dpif_netdev_lookup); /* Actual list of implementations goes here */ @@ -93,11 +95,11 @@ dpcls_subtable_set_prio(const char *name, uint8_t priority) } dpcls_subtable_lookup_func -dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count) +dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count, + const char **name) { /* Iter over each subtable impl, and get highest priority one. */ int32_t prio = -1; - const char *name = NULL; dpcls_subtable_lookup_func best_func = NULL; for (int i = 0; i < ARRAY_SIZE(subtable_lookups); i++) { @@ -109,16 +111,45 @@ dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count) if (probed_func) { best_func = probed_func; prio = probed_prio; - name = subtable_lookups[i].name; + if (name) { + *name = subtable_lookups[i].name; + } } } } VLOG_DBG("Subtable lookup function '%s' with units (%d,%d), priority %d\n", - name, u0_bit_count, u1_bit_count, prio); + *name, u0_bit_count, u1_bit_count, prio); /* Programming error - we must always return a valid func ptr. */ ovs_assert(best_func != NULL); return best_func; } + +void +dpcls_update_flow_dump(struct cmap flow_table, + struct dpcls_subtable_lookup_info_t *lookup_funcs, + int impls_count) +{ + struct dp_netdev_flow *flow; + const char *name = NULL; + int32_t prio = -1; + + for (int i = 0; i < impls_count; i++) { + int32_t probed_prio = lookup_funcs[i].prio; + if (probed_prio > prio) { + name = lookup_funcs[i].name; + prio = probed_prio; + } + } + CMAP_FOR_EACH (flow, node, &flow_table) { + struct ds info = DS_EMPTY_INITIALIZER; + char *extra_info = ovsrcu_get(char *, &flow->dp_extra_info); + ds_put_cstr(&info, extra_info); + ds_truncate(&info, SUBTABLE_STRING_OFFSET); + ds_put_format(&info,",lookup(%s)", name); + ovsrcu_set(&flow->dp_extra_info, ds_steal_cstr(&info)); + ds_destroy(&info); + } +} diff --git a/lib/dpif-netdev-lookup.h b/lib/dpif-netdev-lookup.h index 59f51faa0..a8a83d9a9 100644 --- a/lib/dpif-netdev-lookup.h +++ b/lib/dpif-netdev-lookup.h @@ -20,6 +20,7 @@ #include <config.h> #include "dpif-netdev.h" #include "dpif-netdev-private-dpcls.h" +#include "dpif-netdev-private-flow.h" /* Function to perform a probe for the subtable bit fingerprint. * Returns NULL if not valid, or a valid function pointer to call for this @@ -66,8 +67,14 @@ struct dpcls_subtable_lookup_info_t { int32_t dpcls_subtable_set_prio(const char *name, uint8_t priority); +/* Retrieve the best implementation for dpcls subtable. + * Name parameter is used to fetch the name of dpcls subtable + * selected by the function. + * The function can also be called with name as NULL. + */ dpcls_subtable_lookup_func -dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count); +dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count, + const char **name); /* Retrieve the array of lookup implementations for iteration. * On error, returns a negative number. @@ -76,4 +83,9 @@ dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count); int32_t dpcls_subtable_lookup_info_get(struct dpcls_subtable_lookup_info_t **out_ptr); +void +dpcls_update_flow_dump(struct cmap flow_table, + struct dpcls_subtable_lookup_info_t *lookup_funcs, + int impls_count); + #endif /* dpif-netdev-lookup.h */ diff --git a/lib/dpif-netdev-private-dpcls.h b/lib/dpif-netdev-private-dpcls.h index 0d5da73c7..d17ef32af 100644 --- a/lib/dpif-netdev-private-dpcls.h +++ b/lib/dpif-netdev-private-dpcls.h @@ -88,6 +88,9 @@ struct dpcls_subtable { * here to prevent garbage from being read. */ ATOMIC(dpcls_subtable_lookup_func) lookup_func; + /* Holds the name of the DPCLS implementation slected. */ + const char *subtable_lookup_name; + /* Caches the masks to match a packet to, reducing runtime calculations. */ uint64_t *mf_masks; diff --git a/lib/dpif-netdev-private-flow.h b/lib/dpif-netdev-private-flow.h index 7425dd44e..e1fc7b648 100644 --- a/lib/dpif-netdev-private-flow.h +++ b/lib/dpif-netdev-private-flow.h @@ -123,8 +123,10 @@ struct dp_netdev_flow { * packet_batch_per_flow_init() and packet_batch_per_flow_execute()). */ struct packet_batch_per_flow *batch; - /* Packet classification. */ - char *dp_extra_info; /* String to return in a flow dump/get. */ + /* Packet classification. + * String to return in a flow dump/get. + */ + OVSRCU_TYPE(char *) dp_extra_info; struct dpcls_rule cr; /* In owning dp_netdev's 'cls'. */ /* 'cr' must be the last member. */ }; diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 676434308..48845b629 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -623,6 +623,8 @@ static int dpif_netdev_xps_get_tx_qid(const struct dp_netdev_pmd_thread *pmd, inline struct dpcls * dp_netdev_pmd_lookup_dpcls(struct dp_netdev_pmd_thread *pmd, odp_port_t in_port); +static inline struct dpcls_subtable * +dpcls_find_subtable(struct dpcls *cls, const struct netdev_flow_key *mask); static void dp_netdev_request_reconfigure(struct dp_netdev *dp); static inline bool @@ -1034,6 +1036,7 @@ dpif_netdev_subtable_lookup_set(struct unixctl_conn *conn, int argc OVS_UNUSED, uint32_t new_prio = strtoul(argv[2], &err_char, 10); uint32_t lookup_dpcls_changed = 0; uint32_t lookup_subtable_changed = 0; + struct dpcls_subtable_lookup_info_t *lookup_funcs = NULL; struct shash_node *node; if (errno != 0 || new_prio > UINT8_MAX) { unixctl_command_reply_error(conn, @@ -1075,6 +1078,11 @@ dpif_netdev_subtable_lookup_set(struct unixctl_conn *conn, int argc OVS_UNUSED, } ovs_mutex_lock(&pmd->flow_mutex); uint32_t subtbl_changes = dpcls_subtable_lookup_reprobe(cls); + if (subtbl_changes) { + int count = dpcls_subtable_lookup_info_get(&lookup_funcs); + dpcls_update_flow_dump(pmd->flow_table, lookup_funcs, + count); + } ovs_mutex_unlock(&pmd->flow_mutex); if (subtbl_changes) { lookup_dpcls_changed++; @@ -2380,7 +2388,8 @@ static void dp_netdev_flow_free(struct dp_netdev_flow *flow) { dp_netdev_actions_free(dp_netdev_flow_get_actions(flow)); - free(flow->dp_extra_info); + ovsrcu_postpone(free, + ovsrcu_get_protected(char *, &flow->dp_extra_info)); free(flow); } @@ -3746,7 +3755,8 @@ dp_netdev_flow_to_dpif_flow(const struct dp_netdev *dp, flow->pmd_id = netdev_flow->pmd_id; get_dpif_flow_status(dp, netdev_flow, &flow->stats, &flow->attrs); - flow->attrs.dp_extra_info = netdev_flow->dp_extra_info; + flow->attrs.dp_extra_info = ovsrcu_get(char *, + &netdev_flow->dp_extra_info); } static int @@ -4116,7 +4126,11 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, count_1bits(flow->cr.mask->mf.map.bits[unit])); } ds_put_char(&extra_info, ')'); - flow->dp_extra_info = ds_steal_cstr(&extra_info); + struct dpcls_subtable *subtable = dpcls_find_subtable(cls, &mask); + ds_put_format(&extra_info, ",lookup(%s)", subtable->subtable_lookup_name); + + ovsrcu_set(&flow->dp_extra_info, ds_steal_cstr(&extra_info)); + ds_destroy(&extra_info); cmap_insert(&pmd->flow_table, CONST_CAST(struct cmap_node *, &flow->node), @@ -9753,7 +9767,8 @@ dpcls_create_subtable(struct dpcls *cls, const struct netdev_flow_key *mask) * by the PMD thread. */ atomic_init(&subtable->lookup_func, - dpcls_subtable_get_best_impl(unit0, unit1)); + dpcls_subtable_get_best_impl(unit0, unit1, + &subtable->subtable_lookup_name)); cmap_insert(&cls->subtables_map, &subtable->cmap_node, mask->hash); /* Add the new subtable at the end of the pvector (with no hits yet) */ @@ -9802,7 +9817,8 @@ dpcls_subtable_lookup_reprobe(struct dpcls *cls) /* Set the subtable lookup function atomically to avoid garbage data * being read by the PMD thread. */ atomic_store_relaxed(&subtable->lookup_func, - dpcls_subtable_get_best_impl(u0_bits, u1_bits)); + dpcls_subtable_get_best_impl(u0_bits, u1_bits, + &subtable->subtable_lookup_name)); subtables_changed += (old_func != subtable->lookup_func); } -- 2.25.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev