From patchwork Fri Dec 16 15:50:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1716566 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::136; helo=smtp3.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=vgMps2LP; dkim-atps=neutral Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (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 4NYYWB21tVz23ym for ; Sat, 17 Dec 2022 02:51:50 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 4FB6C6117E; Fri, 16 Dec 2022 15:51:48 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 4FB6C6117E Authentication-Results: smtp3.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=vgMps2LP 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 Vl6vw7zxlZSI; Fri, 16 Dec 2022 15:51:46 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id 4C07A6117B; Fri, 16 Dec 2022 15:51:45 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 4C07A6117B Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 25245C007D; Fri, 16 Dec 2022 15:51:45 +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 88C8AC007D for ; Fri, 16 Dec 2022 15:51:37 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 997B36115E for ; Fri, 16 Dec 2022 15:51:36 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 997B36115E 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 uJ1B95oYQnuC for ; Fri, 16 Dec 2022 15:51:34 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 285E461151 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2107.outbound.protection.outlook.com [40.107.243.107]) by smtp3.osuosl.org (Postfix) with ESMTPS id 285E461151 for ; Fri, 16 Dec 2022 15:51:34 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=VFt4QUesD5bgK9Vr+NCGITkHrVraR5cWyFRW2vuvfm0BEjOZIHrLGhj5Uc/qFGtvuCAe/bv9CxyOdsj9iGNPgUJG5C37SQ8Cil8r0g9mdglQ08oa47boup+SPwryyfN6QDlg4irK356uOJd036fM9kayaYrq7Ldd/a/ZGhCp5aOf4gLM7sFzaT2/JwGMYKh4yNli8WfEDQezI44RPwkP05QrlFY9RyFpFQ2Z8nTZ1E+g7BhQlKyCzrk6MRTMkNVRxf+QcJ8PxWKIB7a+XtQUX7S2e76Q9XPeYWwggMkQocpK87qVmRjGtTlnNN/VUeGsOlMID315+rwdMzaMzT4J7w== 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=Sy6hcrB5lWt6pkY4xOj8bi3Knj9+1yg3GMNoIpZD7Nk=; b=CJgUXdW7PlmZO3PuY2e7k0CzfBQiwsqDDa6eXgkPbyT5QRsdpe8xigEIdIrgxtI7EOWMIFg3bw3hFLYifKkGVB1abaUFHL9Qu6ndtpSNpBLMulWQnuB7Wl3Rfs2sm1h/mcnoTy38g42XssMh8LgmpmBNrkcdtCFa6wBtCKpDUzFWGCQY6CxgG5jfTnvlVk7EVzzhgal0zBcUhryFt3jeScoB6OlZf1KMgJWpn6+rZKQ64zrFi2OQFIOa/pdi+gfFs7kWBQvrjnaS9fs4PH6OFJzLZqBI+Py0lwQH8yW6nVj/9x8W80D7Ib1MFBizqCCLo5Xyv8iCc4L9vI9xKua2Uw== 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=Sy6hcrB5lWt6pkY4xOj8bi3Knj9+1yg3GMNoIpZD7Nk=; b=vgMps2LP/IOdxxWOYF6cHs/kpTAFuu5cr1FDuJqzyymS2DgQkHSQf4LA3ziwrcc4HrSFsZVr0+ziIlE4jI/b/Rj2qXZDp/BUuYp0Cw67dMt1B2vUl5PQJpT4k3xACOoSVF7rhxa/0X4hYr0zSpnamMGkAzUscVthiDbS7GHPl/Y= 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 SJ0PR13MB5621.namprd13.prod.outlook.com (2603:10b6:a03:420::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5924.11; Fri, 16 Dec 2022 15:51:32 +0000 Received: from PH0PR13MB4842.namprd13.prod.outlook.com ([fe80::483b:9e84:fadc:da30]) by PH0PR13MB4842.namprd13.prod.outlook.com ([fe80::483b:9e84:fadc:da30%9]) with mapi id 15.20.5880.021; Fri, 16 Dec 2022 15:51:32 +0000 From: Simon Horman To: dev@openvswitch.org Date: Fri, 16 Dec 2022 16:50:51 +0100 Message-Id: <20221216155054.986464-4-simon.horman@corigine.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221216155054.986464-1-simon.horman@corigine.com> References: <20221216155054.986464-1-simon.horman@corigine.com> X-ClientProxiedBy: AM9P250CA0024.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:21c::29) To PH0PR13MB4842.namprd13.prod.outlook.com (2603:10b6:510:78::6) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH0PR13MB4842:EE_|SJ0PR13MB5621:EE_ X-MS-Office365-Filtering-Correlation-Id: ce20f759-a076-4fb9-7caa-08dadf7d658b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: k/r2CxtGMMr4DPsCzwETYZ069K+Uj37IUg1t3+/t0xcwfE6O6JE4ClEg8V7Q8TZHSy7ibryXB+1GzkuAbVpPeNDTSJvpmK59be1jDJcO3ujebDmIepLdZ40Jt39ymDFcLRudeceIYbQP+xEu9XTNzGqllfFTdDqxmGn89KuN+Jh3iHIg7PyBXk5tQU6vHM9m3OoJXUp8s1neqo6W5OkvZjaSZEXVahIdTrAM/YMDHUonPMKNPPRv1B3O2vtm3mJcLkOQ1hJzxsktrI9buH8Iit2K+4XmlOuJ2jzNzN3otj5n7T3DBRoWJc5VWq2uMZ3WT0QiGcyYtZKI5iKc/s/OHwIW5SACFeSxe+nxDcBYg0xNkojAGddQcIf5tSnasConj14uVOv5iOknXsNWXNVE9NTmv0KYKNKsH8ePpyFQ+0TS3qwajC3zN5pC/xI3pz0AWnl2cNRfClvm8t4bpOA9yCtibky4bsDfk4OulE+gmO58KLZmkps+1y7guqca9V0SMk4QNj/9p2NLaQCPG0Ok3bfVNPvppnBy/UcO82U6yyqoJhBjA2StGda7Bs7SetBQXwo/sLynN27o8PIiCEd6CtWU/IcFLodZnepXlOt9O2z8SLZcz5toSQRDsp866A9y 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:(13230022)(4636009)(366004)(136003)(376002)(39840400004)(396003)(346002)(451199015)(36756003)(2906002)(5660300002)(44832011)(86362001)(8936002)(30864003)(2616005)(38100700002)(1076003)(83380400001)(6916009)(54906003)(316002)(186003)(6512007)(107886003)(41300700001)(6486002)(4326008)(66556008)(6666004)(52116002)(6506007)(478600001)(66476007)(8676002)(66946007); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 2CMdMNzrW+DaUMlwS1JpBjbGdEAnaB/IFVFGNIuJ+33bRgPt/bni1Eag8ZN4VTxfAGgixw12qiWguaSVVoJCJ2sW0JDNqxeVToERGNrXgjOfDkKu9EfgYtl2J3KyLz467brdKlf1xz6UjeeiO2eDu0ImRjx9/wSjaZu5vyCv0SZ9K2CXK7MnOn4BjI4ka/nQBG9lUox1LEMkEbMEAgm+d5z8riLgOvTqAaDR2TLnp9BbU0PhfjrBlJhwfKoxg6HtCmx/U6OIu6AmClVSNqkOUGsey9xuPaRCrQpMOs6z1f19z32VnzMy+m2tVf/I++bksoXMhAHcWYydlq6HAb9Bth9UO2C3Fei5nPuoQ7yf1bf97cNz2JV3O2b5sH764jAJU25VzAOT5Cbi3wlNT5ohAuOUC5gv4sHo1vWXs+Greu7zIPA8zsCH4/phI8oiC6FpBCkVeW+fRbTKV9vHbQkVQBHCHZthmMX1XEKY4Ta6fCnFNMaIkHGnt5FhWzInSiX8GQsi+I+3RDu4WqL/vWwELJUH/HUiVOKuuNqLkxycICo5thWGTjyE799emDU6HOwfYdh6KyZ8kb+XWIN8l3G0/Zsdz3sBYFRrsLLdNO0jJBQCPZdq2q42GvmdgYcc8DhR4XqYh6C5Q2IFo7RPDe5N2o13LMKgC4z3blk6aGNTr8oxBSI8wXS4OB+bKXxlCryMIbqkcR5ls8D51GrAfgloEs3v6vrw8DNjf6uOsSGCdCwj1azcOmQCp1/E08/2gyW0mYDsnoPFFcgF7r9B5nnDEplJUBBmjJGmfox7cQahBdcBVts7foMmX2bzO5cKJrzop9vCCqMtjNt7tRUh7qV79cKMntcBjhB1beFuz55TpWQoQ4gU7zkQsCTALN49HibaNze4jIcIuuM6UI6qhjll3/KJvWR2u/QHuaszgTjOWf0k95zosMVQO1PpgNkvH5bKZ84yF4EQ2hj4P9sy1DD7qn+kIodVaq7YpsqGj1J7bJfbwFY4hK9lDvOw9Slitwrn3Gq1ZdLQpCpzZSd1cCEtyj3JR8QITLXtNgsSzhkMeVrZa8j3hvDYbKRpPGpGqlTszrFGECaFJ7pZByE+XnlDFUHpFu4iROjA56dkuNZbBkTdmMDXMvPV84yMt7qS27o/1qJV/o0rZyp1IDFQ2I2bR9K1fUPdBqmJsurDdbRO8JwyMi7dWsqziPK6mlXfDSJrKWleSukqtYIhbV7TfrIXWDoVgXmU3xcltMI3otoOPQa/uO30fxIldgX0ThMT2qe+UG+irGdNsT/aRTjJrG17+yRw0IiYwVYOEiv2VDxrXShpziaJjGmzW04AL4xjdyO96GAhMdF4niMB+A4DZR6UCoCrWeFmC92t32il2jKp/EX3rZEZf49VDwko1o5r5I8zTtLC9802sx5i410nY+KOHE4EcaqtqrbSvC8ocVuuRqXPPs6+HauZCPhWW/ijoe8/UEPG98AXSTVmZjxgZ4AXKwAbJa44mW6S1OoG8kDqsr1I5Sa1vqLEg4KiD26Z7PTGj4tt5GCyLYot4wmK+Yz9zgq8i0sV2mB5rQxmw2heAC4+c0TAWLquDqs4M8hWZ41lqK2IhbKRXZNjqaGALp9J1vBp2nIDiqHlfRPactbIEXJNkIbWOAGK4VsW5PJaoIUIICab9+A4ME5HxX9IMMugQA== X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: ce20f759-a076-4fb9-7caa-08dadf7d658b X-MS-Exchange-CrossTenant-AuthSource: PH0PR13MB4842.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Dec 2022 15:51:29.6392 (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: SV0rthT18CVSMRf58W3JRqGOdBtnOA8/B49VCRS+fzVi6W7n9rawsQQIvak5wZBbO0WALsPdndI3SKSazpCggMltbGMOazKChtWuz8cLobA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR13MB5621 Cc: Eli Britstein , Jin Liu , Chaoyong He , oss-drivers@corigine.com, Ilya Maximets , Peng Zhang Subject: [ovs-dev] [PATCH 3/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. Signed-off-by: Peng Zhang Signed-off-by: Jin Liu --- lib/netdev-dpdk.c | 199 ++++++++++++++++++++++++++++++++++++++ lib/netdev-dpdk.h | 41 ++++++++ lib/netdev-offload-dpdk.c | 88 +++++++++++++++++ 3 files changed, 328 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index fff57f78279a..180f3fb4b299 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -5274,8 +5275,206 @@ netdev_dpdk_rte_flow_query_count(struct netdev *netdev, return ret; } +static int OVS_UNUSED +netdev_dpdk_meter_profile_create(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 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); + + ret = rte_mtr_capabilities_get(dev->port_id, &cap, error); + if (ret) { + goto out; + } + + ret = netdev_dpdk_meter_profile_create(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(dev->port_id, meter_id, &mtr_stats, &stats_mask, + clear, error); + ret = rte_mtr_meter_profile_add(dev->port_id, meter_profile_id, profile, + error); + if (!mod || ret) { + goto out; + } + + rte_mtr_policy_drop_red(policy); + ret = rte_mtr_meter_policy_add(dev->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(dev->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_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 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); + + ret = rte_mtr_stats_read(dev->port_id, meter_id, &mtr_stats, &stats_mask, + clear, &error); + if (ret) { + goto out; + } + + ret = rte_mtr_destroy(dev->port_id, meter_id, &error); + if (!ret) { + ret = rte_mtr_meter_policy_delete(dev->port_id, meter_policy_id, + &error); + if (!ret) { + ret = rte_mtr_meter_profile_delete(dev->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_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_error error; + struct rte_mtr_stats mtr_stats; + 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->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_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 5cd95d00f5a5..58342dc6af1e 100644 --- a/lib/netdev-dpdk.h +++ b/lib/netdev-dpdk.h @@ -54,6 +54,19 @@ netdev_dpdk_get_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 **, @@ -79,6 +92,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..26c21f270a47 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -2452,6 +2452,91 @@ 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) { + flag = 0; + } else if (config->flags & OFPMF13_PKTPS) { + flag = 1; + } else { + return EBADF; + } + + if (flag == 0) { + rate = ((uint64_t) config->bands[0].rate * 1024) / 8; + burst = ((uint64_t) config->bands[0].burst_size * 1024) / 8; + } else { + rate = config->bands[0].rate; + burst = config->bands[0].burst_size; + } + + 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 +2823,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, + .dpdk_meter_set = netdev_offload_dpdk_meter_set, + .dpdk_meter_get = netdev_offload_dpdk_meter_get, + .dpdk_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,