From: Paul Blakey <[email protected]> Currently ethertype to prio hmap is static and the first ethertype being used gets a lower priority. Usually there is an arp request before the ip traffic and the arp ethertype gets a lower tc priority while the ip traffic proto gets a higher priority. In this case ip traffic will go through more hops in tc and HW. Instead, reserve lower priorities for ip ethertypes.
Signed-off-by: Paul Blakey <[email protected]> Reviewed-by: Roi Dayan <[email protected]> Reviewed-by: Simon Horman <[email protected]> Acked-by: Eelco Chaudron <[email protected]> --- Notes: v3: - Use TC_RESERVED_PRIORITY_NONE as suggested by Eelco. - Added review/ack tags by Simon and Eelco. v2: - don't reverse ip prio if multi mask per prio is not supported. lib/netdev-offload-tc.c | 35 ++++++++++++++++++++++++++++------- lib/tc.h | 2 ++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index f6f90a741fde..ce7f8ad97306 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -325,6 +325,28 @@ struct prio_map_data { uint16_t prio; }; +static uint16_t +get_next_available_prio(ovs_be16 protocol) +{ + static uint16_t last_prio = TC_RESERVED_PRIORITY_MAX; + + if (multi_mask_per_prio) { + if (protocol == htons(ETH_P_IP)) { + return TC_RESERVED_PRIORITY_IPV4; + } else if (protocol == htons(ETH_P_IPV6)) { + return TC_RESERVED_PRIORITY_IPV6; + } + } + + /* last_prio can overflow if there will be many different kinds of + * flows which shouldn't happen organically. */ + if (last_prio == UINT16_MAX) { + return TC_RESERVED_PRIORITY_NONE; + } + + return ++last_prio; +} + /* Get free prio for tc flower * If prio is already allocated for mask/eth_type combination then return it. * If not assign new prio. @@ -336,11 +358,11 @@ get_prio_for_tc_flower(struct tc_flower *flower) { static struct hmap prios = HMAP_INITIALIZER(&prios); static struct ovs_mutex prios_lock = OVS_MUTEX_INITIALIZER; - static uint16_t last_prio = TC_RESERVED_PRIORITY_MAX; size_t key_len = sizeof(struct tc_flower_key); size_t hash = hash_int((OVS_FORCE uint32_t) flower->key.eth_type, 0); struct prio_map_data *data; struct prio_map_data *new_data; + uint16_t prio; if (!multi_mask_per_prio) { hash = hash_bytes(&flower->mask, key_len, hash); @@ -359,21 +381,20 @@ get_prio_for_tc_flower(struct tc_flower *flower) } } - if (last_prio == UINT16_MAX) { - /* last_prio can overflow if there will be many different kinds of - * flows which shouldn't happen organically. */ + prio = get_next_available_prio(flower->key.eth_type); + if (prio == TC_RESERVED_PRIORITY_NONE) { ovs_mutex_unlock(&prios_lock); - return 0; + return prio; } new_data = xzalloc(sizeof *new_data); memcpy(&new_data->mask, &flower->mask, key_len); - new_data->prio = ++last_prio; + new_data->prio = prio; new_data->protocol = flower->key.eth_type; hmap_insert(&prios, &new_data->node, hash); ovs_mutex_unlock(&prios_lock); - return new_data->prio; + return prio; } static uint32_t diff --git a/lib/tc.h b/lib/tc.h index 161f438124b0..a828fd3e3f14 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -49,6 +49,8 @@ enum tc_flower_reserved_prio { TC_RESERVED_PRIORITY_NONE, TC_RESERVED_PRIORITY_POLICE, + TC_RESERVED_PRIORITY_IPV4, + TC_RESERVED_PRIORITY_IPV6, __TC_RESERVED_PRIORITY_MAX }; #define TC_RESERVED_PRIORITY_MAX (__TC_RESERVED_PRIORITY_MAX -1) -- 2.38.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
