From patchwork Mon Dec 28 09:24:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: taoyunxiang X-Patchwork-Id: 1420988 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=cmss.chinamobile.com Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D4Qd01v3sz9sWC for ; Tue, 29 Dec 2020 05:12:36 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 6E94A86B3B; Mon, 28 Dec 2020 18:12:34 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id e-i7lO3Yy2eF; Mon, 28 Dec 2020 18:12:28 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 4C15C869C5; Mon, 28 Dec 2020 18:11:59 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 04A54C1FA9; Mon, 28 Dec 2020 18:11:59 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id ACC71C0891 for ; Mon, 28 Dec 2020 09:26:34 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 9905B819CF for ; Mon, 28 Dec 2020 09:26:34 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jZFpW5j8NRmQ for ; Mon, 28 Dec 2020 09:26:33 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from cmccmta2.chinamobile.com (cmccmta2.chinamobile.com [221.176.66.80]) by hemlock.osuosl.org (Postfix) with ESMTP id 7ECA881EDB for ; Mon, 28 Dec 2020 09:26:32 +0000 (UTC) Received: from spf.mail.chinamobile.com (unknown[172.16.121.3]) by rmmx-syy-dmz-app08-12008 (RichMail) with SMTP id 2ee85fe9a497f49-c07e8; Mon, 28 Dec 2020 17:25:44 +0800 (CST) X-RM-TRANSID: 2ee85fe9a497f49-c07e8 X-RM-TagInfo: emlType=0 X-RM-SPAM-FLAG: 00000000 Received: from yun.localdomain (unknown[112.25.154.146]) by rmsmtp-syy-appsvr02-12002 (RichMail) with SMTP id 2ee25fe9a48a90b-7b892; Mon, 28 Dec 2020 17:25:44 +0800 (CST) X-RM-TRANSID: 2ee25fe9a48a90b-7b892 From: Tao YunXiang To: ovs-dev@openvswitch.org Date: Mon, 28 Dec 2020 01:24:47 -0800 Message-Id: <20201228092520.11807-30-taoyunxiang@cmss.chinamobile.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201228092520.11807-1-taoyunxiang@cmss.chinamobile.com> References: <8> <20201228092520.11807-1-taoyunxiang@cmss.chinamobile.com> MIME-Version: 1.0 X-Mailman-Approved-At: Mon, 28 Dec 2020 18:10:34 +0000 Cc: Rongyin Subject: [ovs-dev] [PATCH 29/62] dpif-netdev: try to offload flow after dpcls_lookup X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Rongyin The original netdev datapath offload mechanism is based on mega_ufid, But Intel FPGA card only support exact match, so there is a so called "wildcard" situation when the pkt miss FPGA table search and slow path EMC cache search but hit in dpcls cache. As for original offload mechanism, we won't try to offload such flows(as the mega_ufid is the same as before) This patch tries to use ufid instead of mega_ufid during offloading. So the original megaufid_to_mark and flow_to_mark mapping can be kept. Also as for flows that has been offloaded but failed, we won't waste effort to offload that flow again. So a offload_fail status flag is added in megaufid_to_mark mapping. Before append offload list, we should try to check this flag. This patch changed offloading mechanism, should be considered carefully, and task more tests. Code Source From: Self Code Description: see above Jira: #[Optional] 市场项目编号(名称):[Optional] --- lib/dpif-netdev.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 100 insertions(+), 12 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 008ffa8..db28b88 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2155,6 +2155,7 @@ struct megaflow_to_mark_data { const struct cmap_node node; ovs_u128 mega_ufid; uint32_t mark; + bool offload_failed; /* indicate if this ufid has been offloaded fail */ }; struct flow_mark { @@ -2193,13 +2194,15 @@ flow_mark_free(uint32_t mark) /* associate megaflow with a mark, which is a 1:1 mapping */ static void -megaflow_to_mark_associate(const ovs_u128 *mega_ufid, uint32_t mark) +megaflow_to_mark_associate(const ovs_u128 *mega_ufid, uint32_t mark, + bool offload_failed) { size_t hash = dp_netdev_flow_hash(mega_ufid); struct megaflow_to_mark_data *data = xzalloc(sizeof(*data)); data->mega_ufid = *mega_ufid; data->mark = mark; + data->offload_failed = offload_failed; cmap_insert(&flow_mark.megaflow_to_mark, CONST_CAST(struct cmap_node *, &data->node), hash); @@ -2242,6 +2245,23 @@ megaflow_to_mark_find(const ovs_u128 *mega_ufid) return INVALID_FLOW_MARK; } +static inline bool +megaflow_to_offload_st_find(const ovs_u128 *mega_ufid) +{ + size_t hash = dp_netdev_flow_hash(mega_ufid); + struct megaflow_to_mark_data *data; + + CMAP_FOR_EACH_WITH_HASH (data, node, hash, &flow_mark.megaflow_to_mark) { + if (ovs_u128_equals(*mega_ufid, data->mega_ufid)) { + return data->offload_failed; + } + } + + VLOG_DBG("Offload status of Mark id for ufid "UUID_FMT" was not found \n", + UUID_ARGS((struct uuid *)mega_ufid)); + return false; +} + /* associate mark with a flow, which is 1:N mapping */ static void mark_to_flow_associate(const uint32_t mark, struct dp_netdev_flow *flow) @@ -2297,7 +2317,7 @@ mark_to_flow_disassociate(struct dp_netdev_pmd_thread *pmd, /* Taking a global 'port_mutex' to fulfill thread safety * restrictions for the netdev-offload-dpdk module. */ ovs_mutex_lock(&pmd->dp->port_mutex); - ret = netdev_flow_del(port, &flow->mega_ufid, NULL); + ret = netdev_flow_del(port, &flow->ufid, NULL); ovs_mutex_unlock(&pmd->dp->port_mutex); netdev_close(port); } @@ -2305,7 +2325,7 @@ mark_to_flow_disassociate(struct dp_netdev_pmd_thread *pmd, flow_mark_free(mark); VLOG_DBG("Freed flow mark %u\n", mark); - megaflow_to_mark_disassociate(&flow->mega_ufid); + megaflow_to_mark_disassociate(&flow->ufid); } dp_netdev_flow_unref(flow); @@ -2420,7 +2440,10 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) * If a mega flow has already been offloaded (from other PMD * instances), do not offload it again. */ - mark = megaflow_to_mark_find(&flow->mega_ufid); + mark = megaflow_to_mark_find(&flow->ufid); + if (megaflow_to_offload_st_find(&flow->ufid) == true) { + return -1; + } if (mark != INVALID_FLOW_MARK) { VLOG_DBG("Flow has already been offloaded with mark %u\n", mark); if (flow->mark != INVALID_FLOW_MARK) { @@ -2448,7 +2471,7 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) ovs_mutex_lock(&pmd->dp->port_mutex); ret = netdev_flow_put(port, &offload->match, CONST_CAST(struct nlattr *, offload->actions), - offload->actions_len, &flow->mega_ufid, &info, + offload->actions_len, &flow->ufid, &info, NULL); ovs_mutex_unlock(&pmd->dp->port_mutex); netdev_close(port); @@ -2458,14 +2481,25 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) } if (!modification) { - megaflow_to_mark_associate(&flow->mega_ufid, mark); + megaflow_to_mark_associate(&flow->ufid, mark,false); mark_to_flow_associate(mark, flow); + VLOG_DBG("TIMO DBG: associate ufid with st false"); + VLOG_DBG("TIMO DBG: ufid:"UUID_FMT" mark:%u \n", + UUID_ARGS((struct uuid *)&flow->ufid),mark); } return 0; err_free: if (!modification) { - flow_mark_free(mark); + /*flow_mark_free(mark);*/ + /* If offloaded fail, also generate ufid->mark mapping + * we waste some mark values in pool , but can get offload + * status + */ + megaflow_to_mark_associate(&flow->ufid, mark,true); + VLOG_DBG("TIMO DBG: associate ufid with st true"); + VLOG_DBG("TIMO DBG: ufid:"UUID_FMT" mark:%u \n", + UUID_ARGS((struct uuid *)&flow->ufid),mark); } else { mark_to_flow_disassociate(pmd, flow); } @@ -3060,7 +3094,7 @@ dpif_netdev_get_flow_offload_status(const struct dp_netdev *dp, /* Taking a global 'port_mutex' to fulfill thread safety * restrictions for the netdev-offload-dpdk module. */ ovs_mutex_lock(&dp->port_mutex); - ret = netdev_flow_get(netdev, &match, &actions, &netdev_flow->mega_ufid, + ret = netdev_flow_get(netdev, &match, &actions, &netdev_flow->ufid, stats, attrs, &buf); ovs_mutex_unlock(&dp->port_mutex); netdev_close(netdev); @@ -3362,7 +3396,10 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, cmap_insert(&pmd->flow_table, CONST_CAST(struct cmap_node *, &flow->node), dp_netdev_flow_hash(&flow->ufid)); - queue_netdev_flow_put(pmd, flow, match, actions, actions_len); + /*Don't try to offload flows that has been offloaded failed */ + if (megaflow_to_offload_st_find(&flow->ufid) == false) { + queue_netdev_flow_put(pmd, flow, match, actions, actions_len); + } if (OVS_UNLIKELY(!VLOG_DROP_DBG((&upcall_rl)))) { struct ds ds = DS_EMPTY_INITIALIZER; @@ -3451,8 +3488,11 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd, old_actions = dp_netdev_flow_get_actions(netdev_flow); ovsrcu_set(&netdev_flow->actions, new_actions); - queue_netdev_flow_put(pmd, netdev_flow, match, - put->actions, put->actions_len); + /*Don't try to offload flows that has been offloaded failed */ + if (megaflow_to_offload_st_find(&netdev_flow->ufid) == false) { + queue_netdev_flow_put(pmd, netdev_flow, match, + put->actions, put->actions_len); + } if (stats) { get_dpif_flow_status(pmd->dp, netdev_flow, stats, NULL); @@ -4212,7 +4252,37 @@ dp_netdev_actions_free(struct dp_netdev_actions *actions) { free(actions); } - + +static void +dp_netdev_append_hw_offload(struct dp_netdev_pmd_thread *pmd, + struct dp_netdev_flow *flow) +{ + struct match flow_put_match; + struct dp_netdev_actions *flow_put_actions; + struct dp_flow_offload_item *offload; + int op = DP_NETDEV_FLOW_OFFLOAD_OP_ADD; + + match_wc_init(&flow_put_match,&(flow->flow)); + /* If this flow has been offloaded, but fail, won't offload again + * Otherwise if this flow has been offloaded succeded, it means + * although the ufid is the same, but exact flow is different + * in this scenario, or hw flow is ageout. we should also try to + * offload it to hw + */ + if (megaflow_to_offload_st_find(&flow->ufid) == true) { + return ; + } + flow_put_actions = dp_netdev_flow_get_actions(flow); + + offload = dp_netdev_alloc_flow_offload(pmd, flow, op); + offload->match = flow_put_match; + offload->actions = xmalloc(flow_put_actions->size); + memcpy(offload->actions, flow_put_actions->actions, flow_put_actions->size); + offload->actions_len = flow_put_actions->size; + + dp_netdev_append_flow_offload(offload); +} + static void dp_netdev_rxq_set_cycles(struct dp_netdev_rxq *rx, enum rxq_cycles_counter_type type, @@ -6532,6 +6602,15 @@ smc_lookup_batch(struct dp_netdev_pmd_thread *pmd, flow->flow.in_port.odp_port == packet->md.in_port.odp_port)) { tcp_flags = miniflow_get_tcp_flags(&keys[i].mf); + /* In case of wildcard condition: FPGA and EMC lookup miss but + * smc/dpcls lookup hit, before insert EMC, try to offload + * netdev flows again(correspond to new ufid) + */ + if (netdev_is_flow_api_enabled() && + (flow->flow.dl_type == htons(ETH_TYPE_IP))) { + dp_netdev_append_hw_offload(pmd,flow); + } + /* SMC hit and emc miss, we insert into EMC */ keys[i].len = netdev_flow_key_size(miniflow_n_values(&keys[i].mf)); @@ -6882,6 +6961,15 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd, } flow = dp_netdev_flow_cast(rules[i]); + /* In case of wildcard condition: FPGA and EMC lookup miss but + * smc/dpcls lookup hit, before insert EMC, try to offload + * netdev flows again(correspond to new mega_ufid) + */ + if (netdev_is_flow_api_enabled() && + (flow->flow.dl_type == htons(ETH_TYPE_IP))) { + dp_netdev_append_hw_offload(pmd,flow); + } + uint32_t hash = dp_netdev_flow_hash(&flow->ufid); smc_insert(pmd, keys[i], hash);