From patchwork Thu Jul 4 14:28:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Blakey X-Patchwork-Id: 1127586 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45fgTs4LGfz9s4Y for ; Fri, 5 Jul 2019 00:34:25 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id A22D212D2; Thu, 4 Jul 2019 14:28:38 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 0D2F01169 for ; Thu, 4 Jul 2019 14:28:36 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id A7420893 for ; Thu, 4 Jul 2019 14:28:34 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE2 (envelope-from paulb@mellanox.com) with ESMTPS (AES256-SHA encrypted); 4 Jul 2019 17:28:33 +0300 Received: from reg-r-vrt-019-180.mtr.labs.mlnx (reg-r-vrt-019-180.mtr.labs.mlnx [10.213.19.180]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x64ESWov010477; Thu, 4 Jul 2019 17:28:33 +0300 From: Paul Blakey To: Paul Blakey , dev@openvswitch.org Date: Thu, 4 Jul 2019 17:28:23 +0300 Message-Id: <1562250507-20335-5-git-send-email-paulb@mellanox.com> X-Mailer: git-send-email 1.8.4.3 In-Reply-To: <1562250507-20335-1-git-send-email-paulb@mellanox.com> References: <1562250507-20335-1-git-send-email-paulb@mellanox.com> X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Marcelo Ricardo Leitner , Oz Shlomo , Simon Horman , Rony Efraim , David Miller , Yossi Kuperman Subject: [ovs-dev] [PATCH RFC v2 4/8] netdev-offload-tc: Implement netdev tc flush via tc filter del X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org To be consistent with our tc-ufid mapping after flush, and to support tc chains flushing in the next commit, implement flush operation via deleting all the filters we actually added and delete their mappings. This will also not delete the configured qos policing via matchall filters, while old code did. Signed-off-by: Paul Blakey --- lib/netdev-offload-tc.c | 74 +++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index e37049c..f4cc2db 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -43,7 +43,8 @@ VLOG_DEFINE_THIS_MODULE(netdev_offload_tc); static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(60, 5); -static struct hmap ufid_tc = HMAP_INITIALIZER(&ufid_tc); +static struct hmap ufid_to_tc = HMAP_INITIALIZER(&ufid_to_tc); +static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid); static bool multi_mask_per_prio = false; static bool block_support = false; @@ -143,45 +144,50 @@ static struct netlink_field set_flower_map[][4] = { static struct ovs_mutex ufid_lock = OVS_MUTEX_INITIALIZER; /** - * struct ufid_tc_data - data entry for ufid_tc hmap. - * @ufid_node: Element in @ufid_tc hash table by ufid key. - * @tc_node: Element in @ufid_tc hash table by tc_id key. + * struct ufid_tc_data - data entry for ufid-tc hashmaps. + * @ufid_to_tc_node: Element in @ufid_to_tc hash table by ufid key. + * @tc_to_ufid_node: Element in @tc_to_ufid hash table by tc_id key. * @ufid: ufid assigned to the flow * @id: tc id * @netdev: netdev associated with the tc rule */ struct ufid_tc_data { - struct hmap_node ufid_node; - struct hmap_node tc_node; + struct hmap_node ufid_to_tc_node; + struct hmap_node tc_to_ufid_node; ovs_u128 ufid; struct tc_id id; struct netdev *netdev; }; -/* Remove matching ufid entry from ufid_tc hashmap. */ static void -del_ufid_tc_mapping(const ovs_u128 *ufid) +del_ufid_tc_mapping_unlocked(const ovs_u128 *ufid) { size_t ufid_hash = hash_bytes(ufid, sizeof *ufid, 0); struct ufid_tc_data *data; - ovs_mutex_lock(&ufid_lock); - HMAP_FOR_EACH_WITH_HASH(data, ufid_node, ufid_hash, &ufid_tc) { + HMAP_FOR_EACH_WITH_HASH(data, ufid_to_tc_node, ufid_hash, &ufid_to_tc) { if (ovs_u128_equals(*ufid, data->ufid)) { break; } } if (!data) { - ovs_mutex_unlock(&ufid_lock); return; } - hmap_remove(&ufid_tc, &data->ufid_node); - hmap_remove(&ufid_tc, &data->tc_node); + hmap_remove(&ufid_to_tc, &data->ufid_to_tc_node); + hmap_remove(&tc_to_ufid, &data->tc_to_ufid_node); netdev_close(data->netdev); free(data); - ovs_mutex_unlock(&ufid_lock); +} + +/* Remove matching ufid entry from ufid-tc hashmaps. */ +static void +del_ufid_tc_mapping(const ovs_u128 *ufid) +{ + ovs_mutex_lock(&ufid_lock); + del_ufid_tc_mapping_unlocked(ufid); + ovs_mutex_lock(&ufid_lock); } /* Wrapper function to delete filter and ufid tc mapping */ @@ -195,7 +201,7 @@ del_filter_and_ufid_mapping(struct tc_id *id, const ovs_u128 *ufid) return err; } -/* Add ufid entry to ufid_tc hashmap. */ +/* Add ufid entry to ufid_to_tc hashmap. */ static void add_ufid_tc_mapping(struct netdev *netdev, const ovs_u128 *ufid, struct tc_id *id) @@ -209,12 +215,12 @@ add_ufid_tc_mapping(struct netdev *netdev, const ovs_u128 *ufid, new_data->netdev = netdev_ref(netdev); ovs_mutex_lock(&ufid_lock); - hmap_insert(&ufid_tc, &new_data->ufid_node, ufid_hash); - hmap_insert(&ufid_tc, &new_data->tc_node, tc_hash); + hmap_insert(&ufid_to_tc, &new_data->ufid_to_tc_node, ufid_hash); + hmap_insert(&tc_to_ufid, &new_data->tc_to_ufid_node, tc_hash); ovs_mutex_unlock(&ufid_lock); } -/* Get tc id from ufid_tc hashmap. +/* Get tc id from ufid_to_tc hashmap. * * Returns 0 if successful and fills id. * Otherwise returns the error. @@ -226,7 +232,7 @@ get_ufid_tc_mapping(const ovs_u128 *ufid, struct tc_id *id) struct ufid_tc_data *data; ovs_mutex_lock(&ufid_lock); - HMAP_FOR_EACH_WITH_HASH(data, ufid_node, ufid_hash, &ufid_tc) { + HMAP_FOR_EACH_WITH_HASH(data, ufid_to_tc_node, ufid_hash, &ufid_to_tc) { if (ovs_u128_equals(*ufid, data->ufid)) { *id = data->id; ovs_mutex_unlock(&ufid_lock); @@ -238,7 +244,7 @@ get_ufid_tc_mapping(const ovs_u128 *ufid, struct tc_id *id) return ENOENT; } -/* Find ufid entry in ufid_tc hashmap using tc_id id. +/* Find ufid entry in ufid_to_tc hashmap using tc_id id. * The result is saved in ufid. * * Returns true on success. @@ -250,7 +256,7 @@ find_ufid(struct netdev *netdev, struct tc_id *id, ovs_u128 *ufid) struct ufid_tc_data *data; ovs_mutex_lock(&ufid_lock); - HMAP_FOR_EACH_WITH_HASH(data, tc_node, tc_hash, &ufid_tc) { + HMAP_FOR_EACH_WITH_HASH(data, tc_to_ufid_node, tc_hash, &tc_to_ufid) { if (netdev == data->netdev && data->id.prio == id->prio && data->id.handle == id->handle @@ -337,21 +343,23 @@ get_block_id_from_netdev(struct netdev *netdev) static int netdev_tc_flow_flush(struct netdev *netdev) { - enum tc_qdisc_hook hook = get_tc_qdisc_hook(netdev); - int ifindex = netdev_get_ifindex(netdev); - uint32_t block_id = 0; - struct tc_id id; - int prio = 0; + struct ufid_tc_data *data, *next; + int err; - if (ifindex < 0) { - VLOG_ERR_RL(&error_rl, "flow_flush: failed to get ifindex for %s: %s", - netdev_get_name(netdev), ovs_strerror(-ifindex)); - return -ifindex; + ovs_mutex_lock(&ufid_lock); + HMAP_FOR_EACH_SAFE(data, next, tc_to_ufid_node, &tc_to_ufid) { + if (data->netdev != netdev) { + continue; + } + + err = tc_del_filter(&data->id); + if (!err) { + del_ufid_tc_mapping_unlocked(&data->ufid); + } } + ovs_mutex_unlock(&ufid_lock); - block_id = get_block_id_from_netdev(netdev); - id = make_tc_id(ifindex, block_id, prio, hook); - return tc_del_filter(&id); + return 0; } static int