From patchwork Mon Dec 31 19:45:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ophir Munk X-Patchwork-Id: 1019703 X-Patchwork-Delegate: ian.stokes@intel.com 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 43T7Ct3tKwz9sDP for ; Tue, 1 Jan 2019 06:48:42 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 9917AB44; Mon, 31 Dec 2018 19:46:31 +0000 (UTC) X-Original-To: ovs-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 6A4DDAE1 for ; Mon, 31 Dec 2018 19:46:28 +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 DE6E87D2 for ; Mon, 31 Dec 2018 19:46:25 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from ophirmu@mellanox.com) with ESMTPS (AES256-SHA encrypted); 31 Dec 2018 21:46:20 +0200 Received: from localhost.localdomain (pegasus05.mtr.labs.mlnx [10.210.16.100]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id wBVJkK7C022031; Mon, 31 Dec 2018 21:46:20 +0200 Received: from pegasus05.mtr.labs.mlnx (localhost [127.0.0.1]) by localhost.localdomain (8.14.7/8.14.7) with ESMTP id wBVJkKRr001685; Mon, 31 Dec 2018 19:46:20 GMT Received: (from root@localhost) by pegasus05.mtr.labs.mlnx (8.14.7/8.14.7/Submit) id wBVJkK3O001684; Mon, 31 Dec 2018 19:46:20 GMT From: Ophir Munk To: ovs-dev@openvswitch.org Date: Mon, 31 Dec 2018 19:45:56 +0000 Message-Id: <1546285557-1617-5-git-send-email-ophirmu@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1546285557-1617-1-git-send-email-ophirmu@mellanox.com> References: <1546285557-1617-1-git-send-email-ophirmu@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: Shahaf Shuler , Simon Horman , Ilya Maximets , Thomas Monjalon Subject: [ovs-dev] [hwol RFC v1 4/5] netdev-dpdk: Add netdev function: flow_stats_get() 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 This function gets the offloaded flow stats. When a flow is fully offloaded reading the PMD SW stats will result in no updates. In order to reflect the actual stats accounted for the flow, the hw must be queried. Signed-off-by: Ophir Munk --- lib/netdev-dpdk.c | 35 ++++++++++++++++++++++++++++++++--- lib/netdev-provider.h | 7 +++++++ lib/netdev.c | 11 +++++++++++ lib/netdev.h | 2 ++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index e1f2331..a78c01c 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -5051,9 +5051,38 @@ netdev_dpdk_flow_del(struct netdev *netdev, const ovs_u128 *ufid, return netdev_dpdk_destroy_rte_flow(netdev, ufid, rte_flow); } -#define DPDK_FLOW_OFFLOAD_API \ - .flow_put = netdev_dpdk_flow_put, \ - .flow_del = netdev_dpdk_flow_del +static int +netdev_dpdk_flow_stats_get(struct netdev *netdev, const ovs_u128 *ufid, + struct dpif_flow_stats *stats) { + + int ret = 0; + struct rte_flow_error error; + struct rte_flow_query_count query; + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct rte_flow *rte_flow = ufid_to_rte_flow_find(ufid); + if (!rte_flow) { + return EINVAL; + } + const struct rte_flow_action action = { + .type = RTE_FLOW_ACTION_TYPE_COUNT + }; + memset(&query, 0, sizeof(query)); + ret = rte_flow_query(dev->port_id, rte_flow, &action, &query, &error); + if (ret) { + return -ret; + } + + stats->n_packets = (query.hits_set) ? query.hits : 0; + stats->n_bytes = (query.bytes_set) ? query.bytes : 0; + stats->used = 0; + stats->tcp_flags = 0; + return ret; +} + +#define DPDK_FLOW_OFFLOAD_API \ + .flow_put = netdev_dpdk_flow_put, \ + .flow_del = netdev_dpdk_flow_del, \ + .flow_stats_get = netdev_dpdk_flow_stats_get #define NETDEV_DPDK_CLASS_COMMON \ .is_pmd = true, \ diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h index fb0c27e..50b6575 100644 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@ -881,6 +881,13 @@ struct netdev_class { int (*flow_del)(struct netdev *, const ovs_u128 *ufid, struct dpif_flow_stats *); + /* Get offloaded flow stats. When a flow is fully offloaded, reading the + * PMD stats will result is no updates. In order to reflect the actual + * stats the hardware must be querried. + * Return 0 if successful, otherwise returns a positive errno value. */ + int (*flow_stats_get)(struct netdev *netdev, const ovs_u128 *ufid, + struct dpif_flow_stats *stats); + /* Initializies the netdev flow api. * Return 0 if successful, otherwise returns a positive errno value. */ int (*init_flow_api)(struct netdev *); diff --git a/lib/netdev.c b/lib/netdev.c index 45b50f2..2cf7ad9 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -2232,6 +2232,17 @@ netdev_flow_del(struct netdev *netdev, const ovs_u128 *ufid, } int +netdev_flow_stats_get(struct netdev *netdev, const ovs_u128 *ufid, + struct dpif_flow_stats *stats) +{ + const struct netdev_class *class = netdev->netdev_class; + + return (class->flow_stats_get + ? class->flow_stats_get(netdev, ufid, stats) + : EOPNOTSUPP); +} + +int netdev_init_flow_api(struct netdev *netdev) { const struct netdev_class *class = netdev->netdev_class; diff --git a/lib/netdev.h b/lib/netdev.h index d94817f..1fca859 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -226,6 +226,8 @@ int netdev_flow_get(struct netdev *, struct match *, struct nlattr **actions, struct dpif_flow_attrs *, struct ofpbuf *wbuffer); int netdev_flow_del(struct netdev *, const ovs_u128 *, struct dpif_flow_stats *); +int netdev_flow_stats_get(struct netdev *, const ovs_u128 *, + struct dpif_flow_stats *); int netdev_init_flow_api(struct netdev *); uint32_t netdev_get_block_id(struct netdev *); int netdev_get_hw_info(struct netdev *, int);