From patchwork Thu Mar 30 11:20:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1763200 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=corigine.onmicrosoft.com header.i=@corigine.onmicrosoft.com header.a=rsa-sha256 header.s=selector2-corigine-onmicrosoft-com header.b=vaaDPWxD; dkim-atps=neutral Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PnLbR6xctz1yXv for ; Thu, 30 Mar 2023 22:21:39 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id E608B84355; Thu, 30 Mar 2023 11:21:37 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org E608B84355 Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=corigine.onmicrosoft.com header.i=@corigine.onmicrosoft.com header.a=rsa-sha256 header.s=selector2-corigine-onmicrosoft-com header.b=vaaDPWxD X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YcszT083_Ck9; Thu, 30 Mar 2023 11:21:35 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 115A38432F; Thu, 30 Mar 2023 11:21:34 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 115A38432F Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2BE2CC0090; Thu, 30 Mar 2023 11:21:33 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id E6A5AC008D for ; Thu, 30 Mar 2023 11:21:29 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id A4DF660B3A for ; Thu, 30 Mar 2023 11:21:29 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org A4DF660B3A Authentication-Results: smtp3.osuosl.org; dkim=pass (1024-bit key) header.d=corigine.onmicrosoft.com header.i=@corigine.onmicrosoft.com header.a=rsa-sha256 header.s=selector2-corigine-onmicrosoft-com header.b=vaaDPWxD X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NKrtps8Db0oo for ; Thu, 30 Mar 2023 11:21:28 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 7B0E660B2B Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2071a.outbound.protection.outlook.com [IPv6:2a01:111:f400:7eab::71a]) by smtp3.osuosl.org (Postfix) with ESMTPS id 7B0E660B2B for ; Thu, 30 Mar 2023 11:21:28 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YmY///aWw/RC2dsWLEAF3BJZtVk9FNDg1iRF25+MfL2iXKc6omqxlkuoRzlQmdNXBj1lpvEF4dHMD3whrjlGPYCEm/LTxpd3R1lkAtcdlosMiNm9WJAKt5TGqWn+JgTaGnK8GsYEscm232yBvNApHaz+QjBbztq7Q8dEzPU8hluVNF9JeysIeAJzqi3rPKUj7k5L10PsWdCTf1yiF9pLjb4kJqHa41qKP5hBl/iiQRfD6SnXvGuN1RKW5ItE/zvdGmSIdmN2zv2ltSSMRLzQ2UxWFAhkadyMvQE1UeSlgNHomo6JYRk46Jso0lPfHNYN+aoQ0ucd5z9SqLd/9r95OA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=rVjnTeg2rN2v9Ds2x3hsmE9qX43YuYkYhUsODww+r3g=; b=mPlrQExNR6fPk54pLS1UGBkiBzPEoGlJgYVOUXy7O+W79bK6ZDXuJCJ49kXX/I4PqPFSXg5ZmUnyDL9AdqZHg57nbicNtNXFlU/fb2Qc7hrs3aWdVjI5taoDblvQBcXYzNKOVu9j3xBvOSpRbmFATVJGUqdSdZIkt8iY8qSOyVxbFQg6n6n1KCZrJKJlRQFJp/tzsLJP8+A8EkrqthXZOSEcL5LchsIeTl90FJYq9YxO+XWX/cOaZD7X9MSiUq2hTPGstwuXtiiwyxCuD2nc7NHdbJDj5ery4qCEJ6Btl0/q/3ZSYEVcMkCyxaqWuZ5XKO6EAfPF+NF9+yjBgCG0cQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com; dkim=pass header.d=corigine.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rVjnTeg2rN2v9Ds2x3hsmE9qX43YuYkYhUsODww+r3g=; b=vaaDPWxDJ20uFl62ByZFEC5f3vvi+Cyt0DweQqEYApaLa1yxkyGBgHJ9WQIj4qKPufToFexfbB2Ma/dDwwCQ1SlSgcRvuX+w+Vhqd3FTK+x3EqE2ORgoXg+bwhZUNPaAcTVMTnuS2pvo6MM3Mk3Tq48dGva7oN2zW+SR/otOMsI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=corigine.com; Received: from PH0PR13MB4842.namprd13.prod.outlook.com (2603:10b6:510:78::6) by SA0PR13MB3999.namprd13.prod.outlook.com (2603:10b6:806:70::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6254.22; Thu, 30 Mar 2023 11:21:26 +0000 Received: from PH0PR13MB4842.namprd13.prod.outlook.com ([fe80::c506:5243:557e:82cb]) by PH0PR13MB4842.namprd13.prod.outlook.com ([fe80::c506:5243:557e:82cb%5]) with mapi id 15.20.6254.021; Thu, 30 Mar 2023 11:21:26 +0000 From: Simon Horman To: dev@openvswitch.org Date: Thu, 30 Mar 2023 13:20:55 +0200 Message-Id: <20230330112057.14242-5-simon.horman@corigine.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230330112057.14242-1-simon.horman@corigine.com> References: <20230330112057.14242-1-simon.horman@corigine.com> X-ClientProxiedBy: AM0PR01CA0111.eurprd01.prod.exchangelabs.com (2603:10a6:208:168::16) To PH0PR13MB4842.namprd13.prod.outlook.com (2603:10b6:510:78::6) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH0PR13MB4842:EE_|SA0PR13MB3999:EE_ X-MS-Office365-Filtering-Correlation-Id: 9824d309-2c82-4756-1269-08db3110e68e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: gL8Qspsbk/p7B8KZIuSdqmHDjbGTajeu2JE0LOgALnzu3xSjquy9rDTRJNFOtcGLhA9LFonZZEr+qCk8ROw451hEhQSSGPKgmgsSO2Li8293H2yG13oHCZPZxuDvksFxtwlAdtBM0VtKW74rcvRMhRP2YJ+RTEb9VWdkQR7MY1A+Pu1b26BOH+kjiYneU0YASvd9fMpPOgOHTa+aPjTrl7jNXtbHKp0W3lDyqj5St3VNghTHxXP2tRqifNqCGC/zXZ5cD07gPMBVeCcG8aNxWMGUet25dJR95RguhVCbMKto8T9PhXoCI6cYLF2gLbT3Ha6l4fTFq63j2ivN/YBPQZl4eIH8qKajSolgGLEET1xsslsCnk89iocYU6gG34UOrECXrXtP1SNGB9YXHssITuFA+FGgyhSsdUkvacH4IkpIUbKLyNb7330NX6NItfDZpH2faacRRTiNm+T6n0TMh35GmpQwaE9QPs3d+axd/KS0LRIK/mEbwbgdGeQznd/wUH7s+W3OmNBvrk0GHCDw5Y3g3FQp3eeq2teejxoAxS+farWuwaHgFi8Js6bKAC/3 X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR13MB4842.namprd13.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230028)(4636009)(136003)(376002)(396003)(346002)(366004)(39840400004)(451199021)(38100700002)(36756003)(86362001)(8936002)(6666004)(107886003)(5660300002)(83380400001)(2616005)(1076003)(41300700001)(478600001)(44832011)(30864003)(52116002)(316002)(186003)(4326008)(8676002)(66556008)(6916009)(66476007)(6512007)(6506007)(54906003)(66946007)(2906002)(6486002); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Clm4t5OoUfULCuCFaE+wJHp1AZrLlr+5igA5GVs2kk6AtQZeDtdOmqhDa+/NK35ZXKuKSq0Uf/vv8f7mSvTK7QeSqLNvAE6rU+jZDmLxo0DiA4MHtqZ5O1K9HnmQfAoeb6ezv05xYXA5vArdHVtR4jjNd2oCb8qa60dkU5D5KvIwuzidJo1CbYcv5IFWqTXufq5Siml/FIpNXfklpHWj/Qa62wSmKi8XFGNXiuBS/hypU1g4bvYyYXh4AxKO3cjlnSqfL/oKOKOodh4bOQxG19tIiQv9h12lQ/bvrSuKB+F7eI1pL3pq5i863bIbV/pwGt8xjQC7mhqmqufFzLrJRkAuyQZ9aLGSQqzjh/ZEqUkJZATRwcSEblO5D1CIKJtpXlx8c4Lirgs5miet+P/I0R4vVQt11zyUh6HOPhLTLC9iKMSZNH9EZknA+4CicKyTql0CEJdf4iIldh/7Jas5/+5dsm7H3AgHIuCcric+FILk47DR4uyGhiejv3mnZ6Kc+fOm2Bu5ZkS+/9m5nJM2OfGp2ksxlG9wSguJOo7775WO2FD0l+99Qsz4dt/h+295YIew27eq9s9/1PcrPPF4ao2sroAjhpZ6IqSOZdUJvc7i8tjKfJIwrqInwLBImKAv7u2bD/iljyPzwMVj0QzBBZ5J12jAhEcMmM9XdJjkHyawydsPShhw5PuKWtewBviHDDL0vlbJCU/dwJ5KusmhwjK2+LD51vOnpAr9Skyc0K8Xtn9EujljMOnVLRQVtETeoy85jlXw9F4cGjoRKtJHlmzGpo9G2eom/r+kUXzyzOROLqzAtDu4rlRcW6xmyWfHlvhWqL+HNW65/NNHtKLA6kh9MMIhpesdQ3ag/eXc58pSGd3ktTyl8SHza4W1gbJDI2F0DuE5vZHVuJqoAEu6IXVOQ1pnk/RzUrFSaX589Nt3CYS9ipMCaB++k3PIVqXNbogtxiOrIfzNUFC0AsrB1MGJoEq5Ue4vzieGGZiFNMTFNZi/A/chZJ1+dC0FRI9kcko1OL1T9/uI5E8pRp3bmqWUYo/RbdK2JgBk8JD92t+/96vTPkEfdssMc+Qf984vWhPsvUOFFMQsA3q0Rv2Rw/1xZczXOIXElMSuYOVtHfhxT0U2FF4wnDAQ0WZKs7FEpRwp5v8ASVSVxjeIfjbQXzQbB2AvkFm4no6R26SQXQv0UKSaeWR6r4ph8UI1FGUqhvQ0YFlWOslRbwUTr7EcGIIhgAW8PTX7PlyoR8HgqrVvILp8M2/NojMQ3dEGU7QC0h4NStLcKWbU+JbM6MP+QCBlbtB40wYSjCN71x0KZ7lWAjNSONpdkqY0oiN7cBjp/x6zf6QOaifGWnmFHnNwRr5uNCt113fMKvAr7Sd8CmI3/5P68204tMIpCbjQ/2u50QHL7J+aSf1ubfx2hNhz4KyI9ZythmmSdeZ2nrsdYMhS7O8rbmq06GBgnlSXmO2bAlpCFRHhrxizY2Csn/1bibYjGMdiR32fjSXcnApj3c+g2S2A2tyfYza28qxmdBov7dW9Lv7NhcretGKJfv+z63z0nPUhy6CxtbBBWopkhRs1BzkPetLWZRqHlLXrayqDAbisA0HFe3kCsosrLk3SE8eCaQwTYj4+myGjUWAci9pdKvAdKZ7/R3AQeAYzExi7YV7o+itpiXXjQwPk7SbEcQ== X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9824d309-2c82-4756-1269-08db3110e68e X-MS-Exchange-CrossTenant-AuthSource: PH0PR13MB4842.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Mar 2023 11:21:26.1969 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: fe128f2c-073b-4c20-818e-7246a585940c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: q6cd3TEAUP0JkZzG5gfW/lKKQJ/zGfZqZvaoAK7pB1XCvcWRmeqNWTF3kwpjNWFEL0LMFDxm+Z6s+W8PVj+Zw3ftkBxuPXjyW4uWlJ0h+5Y= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR13MB3999 Cc: Eli Britstein , Jin Liu , Chaoyong He , oss-drivers@corigine.com, Ilya Maximets , Peng Zhang Subject: [ovs-dev] [PATCH dpdk-latest v3 4/6] netdev-offload-dpdk: Implement meter offload API for DPDK 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: Peng Zhang For dpif-netdev, meters are mapped by DPDK meter with one-to-one relationship. Implement meter offload API to set/get/del the DPDK meter with proxy port id. Signed-off-by: Peng Zhang Signed-off-by: Jin Liu Co-authored-by: Jin Liu Signed-off-by: Simon Horman --- lib/netdev-dpdk.c | 202 ++++++++++++++++++++++++++++++++++++++ lib/netdev-dpdk.h | 41 ++++++++ lib/netdev-offload-dpdk.c | 84 ++++++++++++++++ 3 files changed, 327 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index d6f2f0517da6..cc2d0762226f 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -5330,8 +5331,209 @@ netdev_dpdk_rte_flow_query_count(struct netdev *netdev, return ret; } +static int OVS_UNUSED +netdev_dpdk_meter_profile_init(struct rte_mtr_meter_profile *profile, + struct rte_mtr_capabilities *cap, + const uint64_t rate, + const uint64_t burst, + const int flag) +{ + if (!cap->meter_srtcm_rfc2697_n_max) { + return EOPNOTSUPP; + } + + profile->alg = RTE_MTR_SRTCM_RFC2697; + profile->packet_mode = flag; + profile->srtcm_rfc2697.cir = rate; + profile->srtcm_rfc2697.cbs = burst; + profile->srtcm_rfc2697.ebs = burst; + + return 0; +} + #ifdef ALLOW_EXPERIMENTAL_API +static int +netdev_dpdk_rte_mtr_meter_add(struct rte_mtr_meter_profile *profile, + struct netdev *netdev, + uint32_t meter_id, + const uint32_t rate, + const uint32_t burst, + const int flag, + struct rte_mtr_error *error) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + uint32_t meter_profile_id = meter_id; + uint32_t meter_policy_id = meter_id; + struct rte_mtr_capabilities cap; + struct rte_mtr_stats mtr_stats; + struct rte_mtr_params params; + uint64_t stats_mask = 0; + int prox_port_id; + int clear = 0; + int mod; + int ret; + + memset(&mtr_stats, 0, sizeof(struct rte_mtr_stats)); + memset(&cap, 0, sizeof(cap)); + + ovs_mutex_lock(&dev->mutex); + + prox_port_id = dev->flow_transfer_proxy_port_id; + ret = rte_mtr_capabilities_get(prox_port_id, &cap, error); + if (ret) { + goto out; + } + + ret = netdev_dpdk_meter_profile_init(profile, &cap, rate, burst, flag); + if (ret) { + goto out; + } + + /* If can get the meter stats, the meter is offload in the HW. + * So the operate is mod, just update the meter_profile. + * + * If can't get the meter stats, the meter is not offload in the HW. + * So the operate is add, need create the profile, policy, mtr. */ + mod = rte_mtr_stats_read(prox_port_id, meter_id, &mtr_stats, &stats_mask, + clear, error); + ret = rte_mtr_meter_profile_add(prox_port_id, meter_profile_id, profile, + error); + if (!mod || ret) { + goto out; + } + + rte_mtr_policy_drop_red(policy); + ret = rte_mtr_meter_policy_add(prox_port_id, meter_policy_id, &policy, + error); + + if (ret) { + goto out; + } + + memset(¶ms, 0 , sizeof(struct rte_mtr_params)); + params.meter_profile_id = meter_profile_id; + params.meter_policy_id = meter_policy_id; + params.stats_mask = cap.stats_mask; + params.meter_enable = 1; + + ret = rte_mtr_create(prox_port_id, meter_id, ¶ms, 1, error); +out: + ovs_mutex_unlock(&dev->mutex); + return ret; +} + +int +netdev_dpdk_meter_create(struct netdev *netdev, + const uint32_t meter_profile_id, + const uint64_t rate, + const uint64_t burst, + const int flag) +{ + struct rte_mtr_meter_profile profile; + struct rte_mtr_error error; + int ret; + + memset(&profile, 0 , sizeof(struct rte_mtr_meter_profile)); + memset(&error, 0 , sizeof(struct rte_mtr_error)); + + ret = netdev_dpdk_rte_mtr_meter_add(&profile, netdev, meter_profile_id, + rate, burst, flag, &error); + if (!ret) { + if (!VLOG_DROP_DBG(&rl)) { + VLOG_DBG("%s: rte_meter_id %d port_id %d mtr create ", + netdev_get_name(netdev), meter_profile_id, + netdev_dpdk_get_prox_port_id(netdev)); + } + } else { + VLOG_DBG("%s: rte_mtr creation failed: %d (%s).", + netdev_get_name(netdev), error.type, error.message); + } + return ret; +} + +int +netdev_dpdk_meter_del(struct netdev *netdev, + const uint32_t meter_id, + const uint32_t meter_profile_id, + const uint32_t meter_policy_id) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct rte_mtr_stats mtr_stats; + struct rte_mtr_error error; + uint64_t stats_mask = 0; + int proxy_port_id; + int clear = 0; + int ret = 0 ; + + memset(&mtr_stats, 0, sizeof(struct rte_mtr_stats)); + memset(&error, 0 , sizeof(struct rte_mtr_error)); + ovs_mutex_lock(&dev->mutex); + + proxy_port_id = dev->flow_transfer_proxy_port_id; + ret = rte_mtr_stats_read(proxy_port_id, meter_id, &mtr_stats, &stats_mask, + clear, &error); + if (ret) { + goto out; + } + + ret = rte_mtr_destroy(proxy_port_id, meter_id, &error); + if (!ret) { + ret = rte_mtr_meter_policy_delete(proxy_port_id, meter_policy_id, + &error); + if (!ret) { + ret = rte_mtr_meter_profile_delete(proxy_port_id, meter_profile_id, + &error); + } + + if (!VLOG_DROP_DBG(&rl)) { + VLOG_DBG("%s: rte_meter_id %d port_id %d mtr delete", + netdev_get_name(netdev), meter_id, + netdev_dpdk_get_prox_port_id(netdev)); + } + } else { + VLOG_DBG("%s: rte_mtr delete mtr_id %d failed: %d (%s).", + netdev_get_name(netdev), meter_id, error.type, error.message); + } + +out: + ovs_mutex_unlock(&dev->mutex); + return ret; +} + +int +netdev_dpdk_meter_get(struct netdev *netdev, + const uint32_t meter_id, + uint64_t *byte_in_count, + uint64_t *packet_in_count) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct rte_mtr_stats mtr_stats; + struct rte_mtr_error error; + uint64_t stats_mask = 0; + int clear = 0; + int ret = 0 ; + + memset(&mtr_stats, 0, sizeof(struct rte_mtr_stats)); + memset(&error, 0, sizeof(struct rte_mtr_error)); + + ret = rte_mtr_stats_read(dev->flow_transfer_proxy_port_id, meter_id, + &mtr_stats, &stats_mask, clear, &error); + if (!ret) { + *byte_in_count = mtr_stats.n_bytes[RTE_COLOR_GREEN]; + *packet_in_count = mtr_stats.n_pkts[RTE_COLOR_GREEN]; + if (!VLOG_DROP_DBG(&rl)) { + VLOG_DBG("%s: rte_meter_id %d port_id %d mtr get stats success ", + netdev_get_name(netdev),meter_id, + netdev_dpdk_get_prox_port_id(netdev)); + } + } else { + VLOG_DBG("%s: rte_mtr get mtr_id %d stats failed: %d (%s).", + netdev_get_name(netdev), meter_id, error.type, error.message); + } + return ret; +} + int netdev_dpdk_rte_flow_tunnel_decap_set(struct netdev *netdev, struct rte_flow_tunnel *tunnel, diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h index 277db156fe06..a4c8ecc3d685 100644 --- a/lib/netdev-dpdk.h +++ b/lib/netdev-dpdk.h @@ -56,6 +56,19 @@ netdev_dpdk_get_prox_port_id(struct netdev *netdev); #ifdef ALLOW_EXPERIMENTAL_API +int netdev_dpdk_meter_create(struct netdev *netdev, + const uint32_t meter_profile_id, + const uint64_t rate, + const uint64_t burst, + const int flag); +int netdev_dpdk_meter_del(struct netdev *netdev, + const uint32_t meter_id, + const uint32_t meter_profile_id, + const uint32_t meter_policy_id); +int netdev_dpdk_meter_get(struct netdev *netdev, + const uint32_t meter_id, + uint64_t *byte_in_count, + uint64_t *packet_in_count); int netdev_dpdk_rte_flow_tunnel_decap_set(struct netdev *, struct rte_flow_tunnel *, struct rte_flow_action **, @@ -81,6 +94,34 @@ int netdev_dpdk_rte_flow_tunnel_item_release(struct netdev *, #else +static inline int +netdev_dpdk_meter_create(struct netdev *netdev OVS_UNUSED, + const uint32_t meter_profile_id OVS_UNUSED, + const uint64_t rate OVS_UNUSED, + const uint64_t burst OVS_UNUSED, + const int flag OVS_UNUSED) +{ + return -1; +} + +static inline int +netdev_dpdk_meter_del(struct netdev *netdev OVS_UNUSED, + const uint32_t meter_id OVS_UNUSED, + const uint32_t meter_profile_id OVS_UNUSED, + const uint32_t meter_policy_id OVS_UNUSED) +{ + return -1; +} + +static inline int +netdev_dpdk_meter_get(struct netdev *netdev OVS_UNUSED, + const uint32_t meter_id OVS_UNUSED, + uint64_t *byte_in_count OVS_UNUSED, + uint64_t *packet_in_count OVS_UNUSED) +{ + return -1; +} + static inline void set_error(struct rte_flow_error *error, enum rte_flow_error_type type) { diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index 38f00fd309e6..144b406459dc 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -2452,6 +2452,87 @@ netdev_offload_dpdk_flow_del(struct netdev *netdev OVS_UNUSED, return netdev_offload_dpdk_flow_destroy(rte_flow_data); } +static int +netdev_offload_dpdk_meter_set(struct netdev *dev, + ofproto_meter_id meter_id, + struct ofputil_meter_config *config) +{ + uint32_t mid = meter_id.uint32; + uint64_t burst; + uint64_t rate; + int ret = 0; + int flag; + + if (config->n_bands != 1 || config->bands[0].type != OFPMBT13_DROP) { + return 0; + } + + if (!(config->flags & (OFPMF13_KBPS | OFPMF13_PKTPS))) { + return EBADF; + } + + flag = !(config->flags & OFPMF13_KBPS); + rate = config->bands[0].rate; + burst = config->bands[0].burst_size; + if (flag == 0) { + rate *= 1024 / 8; + burst *= 1024 / 8; + } + + if (!config->bands[0].burst_size) { + burst = rate / 5; + } + ret = netdev_dpdk_meter_create(dev, mid, rate, burst, flag); + if (ret) { + VLOG_ERR("Failed offload the flow to the %s", dev->name); + } + return ret; +} + +static int +netdev_offload_dpdk_meter_del(struct netdev *dev, + ofproto_meter_id meter_id, + struct ofputil_meter_stats *stats) +{ + uint32_t meter_profile_id = meter_id.uint32; + uint32_t meter_policy_id = meter_id.uint32; + int ret = 0; + + ret = netdev_dpdk_meter_del(dev, meter_id.uint32, meter_profile_id, + meter_policy_id); + if (ret) { + VLOG_ERR("Failed del the flow to the %s", dev->name); + return ret; + } + + if (stats) { + memset(stats, 0, sizeof *stats); + } + + return 0; +} + +static int +netdev_offload_dpdk_meter_get(struct netdev *dev, + ofproto_meter_id meter_id, + struct ofputil_meter_stats *stats) +{ + uint64_t byte_in_count = 0; + uint64_t packet_in_count = 0; + int ret = 0; + + ret = netdev_dpdk_meter_get(dev, meter_id.uint32, &byte_in_count, + &packet_in_count); + if (ret) { + VLOG_ERR("Failed get the flow to the %s", dev->name); + return ret; + } + stats->byte_in_count = byte_in_count; + stats->packet_in_count = packet_in_count; + + return 0; +} + static int netdev_offload_dpdk_init_flow_api(struct netdev *netdev) { @@ -2738,6 +2819,9 @@ const struct netdev_flow_api netdev_offload_dpdk = { .type = "dpdk_flow_api", .flow_put = netdev_offload_dpdk_flow_put, .flow_del = netdev_offload_dpdk_flow_del, + .meter_set = netdev_offload_dpdk_meter_set, + .meter_get = netdev_offload_dpdk_meter_get, + .meter_del = netdev_offload_dpdk_meter_del, .init_flow_api = netdev_offload_dpdk_init_flow_api, .uninit_flow_api = netdev_offload_dpdk_uninit_flow_api, .flow_get = netdev_offload_dpdk_flow_get,