From patchwork Thu Oct 11 13:04:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moti Haimovsky X-Patchwork-Id: 46618 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9DE391B551; Thu, 11 Oct 2018 15:04:37 +0200 (CEST) Received: from EUR03-AM5-obe.outbound.protection.outlook.com (mail-eopbgr30079.outbound.protection.outlook.com [40.107.3.79]) by dpdk.org (Postfix) with ESMTP id 025671B4C5 for ; Thu, 11 Oct 2018 15:04:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Ujn4ayvSbx1EzpM634tYpwYJVZgOKPjPoz8c9wITSOE=; b=dGE8JWjIzwwgxwJUysYtj1W3zTU5BLQUG7ta57hw93ZoSpcJGkwlh1kVAITonk6cmIjNboJQr/9WqxBZwznLiD5kkG8D6L/1EHaMnHZd5BoEQ8PZ4abwZ1yMMHjRQLbTPaFq+pbj2ayq1Vu8v0cozpq9Ce2tnNY+c6u4oph1AYI= Received: from AM0PR05MB4435.eurprd05.prod.outlook.com (52.134.92.20) by AM0PR05MB4898.eurprd05.prod.outlook.com (20.177.41.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1207.28; Thu, 11 Oct 2018 13:04:34 +0000 Received: from AM0PR05MB4435.eurprd05.prod.outlook.com ([fe80::2549:a872:4864:b84e]) by AM0PR05MB4435.eurprd05.prod.outlook.com ([fe80::2549:a872:4864:b84e%6]) with mapi id 15.20.1207.029; Thu, 11 Oct 2018 13:04:34 +0000 From: Mordechay Haimovsky To: Shahaf Shuler CC: "dev@dpdk.org" , Mordechay Haimovsky Thread-Topic: [PATCH v2 1/2] net/mlx5: refactor TC-flow infrastructure Thread-Index: AQHUYWL0Utxkj9DMqUCkCsdPOlLAdA== Date: Thu, 11 Oct 2018 13:04:33 +0000 Message-ID: <1539263057-16678-2-git-send-email-motih@mellanox.com> References: <1539263057-16678-1-git-send-email-motih@mellanox.com> In-Reply-To: <1539263057-16678-1-git-send-email-motih@mellanox.com> Accept-Language: he-IL, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: HE1PR05CA0223.eurprd05.prod.outlook.com (2603:10a6:3:fa::23) To AM0PR05MB4435.eurprd05.prod.outlook.com (2603:10a6:208:5a::20) authentication-results: spf=none (sender IP is ) smtp.mailfrom=motih@mellanox.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [37.142.13.130] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM0PR05MB4898; 6:oOE596gI5RlvanS36iyoO2zhV+2JKjG8zOhnDE93Z/jCbEQOWu7hp26B/fLQm86KmEbiHl+j6zzqQ23ffxdz+AzYGyYUZHzOgKCEto1/gQ4KEH7FsTVv0Ag2Vb2GyCwLL2uDYG10sbibasi3+OSy7dJULWU+aSu00BII+0hte/kq+OUWNEX5Ccmtq6apzwlQvSwjbLojYnTgk83g7P7RCHS/Nl5uzRZBC2ZW5755BzXxFw7mD645UESIct+AlG7mADmapVACROEqrzhwu6/akFk7klWZpfhCfV95Uez1vbDg7MYpiVvm2WHUTHZVSmM3fMvLfHvXlnnT29cvUwAekUmofT1JhjlcAeiIt4CEKzOVeIHAgxgIxPYgm1v+K0bPuHlWWSbic9WSEjp9Wg+2mUCBCwgtr0p5RshPUlgiWn2qHenR69zUHCKjBsWRQRR97LOIDlV5e7ANOb5CIc2f4w==; 5:LGjMYb7I5oyc13PuWA/XmRS8w4Y/RDCASu4GCMh9dZ0XhDBzPgkhLLSBHCJz1Ljekuo7CYrzK6cx3JlRlJR1fJVz+YBclJyWSopSPUQV3jSE6XIOfCP8AqzzqLjVUkxaFjMftKQzJmCb42L8jXV0j0yaeBlo+FIXlbC9iePXLBI=; 7:rWYbWoZjC5C3GIDRK4fg17du0Au98OxPshNCBOQeOXODTkB0EE3/vzip1X59iFUMaD3THdIh49sb9bKPJCINRxfyCRABZXlxl447Sfl6EuME83/tF2V5gFz/8PRtVZm32QdQwSBLv43nkBls3OGTlN5HWXG5oEUZxYFK21pulEABh9AAf6u+FYzKaiYcM7e+zidVxqr/a6fYsQ7ffIo28qZlusdbkH8I5VlPpScIXyruMWZ24ruc8fEFmONKh1Ux x-ms-office365-filtering-correlation-id: 1142f05a-7b3e-4182-537f-08d62f7a16e8 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:AM0PR05MB4898; x-ms-traffictypediagnostic: AM0PR05MB4898: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(269456686620040); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3002001)(3231355)(944501410)(52105095)(10201501046)(93006095)(93001095)(6055026)(149066)(150057)(6041310)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123558120)(20161123564045)(201708071742011)(7699051); SRVR:AM0PR05MB4898; BCL:0; PCL:0; RULEID:; SRVR:AM0PR05MB4898; x-forefront-prvs: 08220FA8D6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(376002)(136003)(346002)(39860400002)(396003)(366004)(199004)(189003)(71200400001)(71190400001)(105586002)(5250100002)(6862004)(4326008)(54906003)(2900100001)(99286004)(76176011)(52116002)(106356001)(6116002)(97736004)(7736002)(2906002)(25786009)(305945005)(107886003)(3846002)(37006003)(5660300001)(66066001)(6636002)(86362001)(256004)(14444005)(14454004)(8936002)(476003)(2616005)(11346002)(446003)(486006)(36756003)(68736007)(186003)(26005)(102836004)(8676002)(81166006)(81156014)(6436002)(316002)(53936002)(6512007)(386003)(6506007)(6486002)(478600001)(42262002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR05MB4898; H:AM0PR05MB4435.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: dUCV2yP4QeNTgzJZUQnrHd5rTJJ63CWg0A4cHA4HGg7B3LYnfefCOtEDyoAxAMv3Z/+caRroSLRABckLqgNfdV6dqK1CbldSftD4hqefSyrz/xY2izV3PnOheyg1eXNG1FOwvCDZQwo7nKDNPuSq+k+vkpiWiT/up8YpGORBnMOef3941jOQlGbwvxhyyW7h3sucspmzyxf+IAjPcc8zWh6MO93Grouov1WkquwpOahGhjxD7VpFXxKXuuXxZy/RGe5lCnCg0V9/GtPCm5qDPOVSZP4Q5sm3NMzYmMKQu/SVStma0ghZVffENZQHh90kY9AW1RsMeSJeBapmVFs29ZfuCuW+vE3zWwgeZi8sRC4= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1142f05a-7b3e-4182-537f-08d62f7a16e8 X-MS-Exchange-CrossTenant-originalarrivaltime: 11 Oct 2018 13:04:34.0016 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4898 Subject: [dpdk-dev] [PATCH v2 1/2] net/mlx5: refactor TC-flow infrastructure X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This commit refactors tc_flow as a preparation to coming commits that sends different type of messages and expect differ type of replies while still using the same underlying routines. Signed-off-by: Moti Haimovsky --- drivers/net/mlx5/mlx5.c | 18 +++---- drivers/net/mlx5/mlx5.h | 4 +- drivers/net/mlx5/mlx5_flow.h | 8 +-- drivers/net/mlx5/mlx5_flow_tcf.c | 113 ++++++++++++++++++++++++++++++--------- 4 files changed, 102 insertions(+), 41 deletions(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 7425e2f..20adf88 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -286,8 +286,8 @@ close(priv->nl_socket_route); if (priv->nl_socket_rdma >= 0) close(priv->nl_socket_rdma); - if (priv->mnl_socket) - mlx5_flow_tcf_socket_destroy(priv->mnl_socket); + if (priv->tcf_context) + mlx5_flow_tcf_context_destroy(priv->tcf_context); ret = mlx5_hrxq_ibv_verify(dev); if (ret) DRV_LOG(WARNING, "port %u some hash Rx queue still remain", @@ -1137,8 +1137,8 @@ claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0)); if (vf && config.vf_nl_en) mlx5_nl_mac_addr_sync(eth_dev); - priv->mnl_socket = mlx5_flow_tcf_socket_create(); - if (!priv->mnl_socket) { + priv->tcf_context = mlx5_flow_tcf_context_create(); + if (!priv->tcf_context) { err = -rte_errno; DRV_LOG(WARNING, "flow rules relying on switch offloads will not be" @@ -1153,7 +1153,7 @@ error.message = "cannot retrieve network interface index"; } else { - err = mlx5_flow_tcf_init(priv->mnl_socket, ifindex, + err = mlx5_flow_tcf_init(priv->tcf_context, ifindex, &error); } if (err) { @@ -1161,8 +1161,8 @@ "flow rules relying on switch offloads will" " not be supported: %s: %s", error.message, strerror(rte_errno)); - mlx5_flow_tcf_socket_destroy(priv->mnl_socket); - priv->mnl_socket = NULL; + mlx5_flow_tcf_context_destroy(priv->tcf_context); + priv->tcf_context = NULL; } } TAILQ_INIT(&priv->flows); @@ -1217,8 +1217,8 @@ close(priv->nl_socket_route); if (priv->nl_socket_rdma >= 0) close(priv->nl_socket_rdma); - if (priv->mnl_socket) - mlx5_flow_tcf_socket_destroy(priv->mnl_socket); + if (priv->tcf_context) + mlx5_flow_tcf_context_destroy(priv->tcf_context); if (own_domain_id) claim_zero(rte_eth_switch_domain_free(priv->domain_id)); rte_free(priv); diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 2dec88a..d14239c 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -169,7 +169,7 @@ struct mlx5_drop { struct mlx5_rxq_ibv *rxq; /* Verbs Rx queue. */ }; -struct mnl_socket; +struct mlx5_flow_tcf_context; struct priv { LIST_ENTRY(priv) mem_event_cb; /* Called by memory event callback. */ @@ -236,7 +236,7 @@ struct priv { rte_spinlock_t uar_lock[MLX5_UAR_PAGE_NUM_MAX]; /* UAR same-page access control required in 32bit implementations. */ #endif - struct mnl_socket *mnl_socket; /* Libmnl socket. */ + struct mlx5_flow_tcf_context *tcf_context; /* TC flower context. */ }; #define PORT_ID(priv) ((priv)->dev_data->port_id) diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index fee05f0..41d55e8 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -338,9 +338,9 @@ int mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item, /* mlx5_flow_tcf.c */ -int mlx5_flow_tcf_init(struct mnl_socket *nl, unsigned int ifindex, - struct rte_flow_error *error); -struct mnl_socket *mlx5_flow_tcf_socket_create(void); -void mlx5_flow_tcf_socket_destroy(struct mnl_socket *nl); +int mlx5_flow_tcf_init(struct mlx5_flow_tcf_context *ctx, + unsigned int ifindex, struct rte_flow_error *error); +struct mlx5_flow_tcf_context *mlx5_flow_tcf_context_create(void); +void mlx5_flow_tcf_context_destroy(struct mlx5_flow_tcf_context *ctx); #endif /* RTE_PMD_MLX5_FLOW_H_ */ diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c index 91f6ef6..8535a15 100644 --- a/drivers/net/mlx5/mlx5_flow_tcf.c +++ b/drivers/net/mlx5/mlx5_flow_tcf.c @@ -153,6 +153,19 @@ struct tc_vlan { #define IPV6_ADDR_LEN 16 #endif +/** + * Structure for holding netlink context. + * Note the size of the message buffer which is MNL_SOCKET_BUFFER_SIZE. + * Using this (8KB) buffer size ensures that netlink messages will never be + * truncated. + */ +struct mlx5_flow_tcf_context { + struct mnl_socket *nl; /* NETLINK_ROUTE libmnl socket. */ + uint32_t seq; /* Message sequence number. */ + uint32_t buf_size; /* Message buffer size. */ + uint8_t *buf; /* Message buffer. */ +}; + /** Empty masks for known item types. */ static const union { struct rte_flow_item_port_id port_id; @@ -1429,8 +1442,8 @@ struct flow_tcf_ptoi { /** * Send Netlink message with acknowledgment. * - * @param nl - * Libmnl socket to use. + * @param ctx + * Flow context to use. * @param nlh * Message to send. This function always raises the NLM_F_ACK flag before * sending. @@ -1439,12 +1452,13 @@ struct flow_tcf_ptoi { * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -flow_tcf_nl_ack(struct mnl_socket *nl, struct nlmsghdr *nlh) +flow_tcf_nl_ack(struct mlx5_flow_tcf_context *ctx, struct nlmsghdr *nlh) { alignas(struct nlmsghdr) uint8_t ans[mnl_nlmsg_size(sizeof(struct nlmsgerr)) + nlh->nlmsg_len - sizeof(*nlh)]; - uint32_t seq = random(); + uint32_t seq = ctx->seq++; + struct mnl_socket *nl = ctx->nl; int ret; nlh->nlmsg_flags |= NLM_F_ACK; @@ -1479,7 +1493,7 @@ struct flow_tcf_ptoi { struct rte_flow_error *error) { struct priv *priv = dev->data->dev_private; - struct mnl_socket *nl = priv->mnl_socket; + struct mlx5_flow_tcf_context *nl = priv->tcf_context; struct mlx5_flow *dev_flow; struct nlmsghdr *nlh; @@ -1508,7 +1522,7 @@ struct flow_tcf_ptoi { flow_tcf_remove(struct rte_eth_dev *dev, struct rte_flow *flow) { struct priv *priv = dev->data->dev_private; - struct mnl_socket *nl = priv->mnl_socket; + struct mlx5_flow_tcf_context *nl = priv->tcf_context; struct mlx5_flow *dev_flow; struct nlmsghdr *nlh; @@ -1560,10 +1574,47 @@ struct flow_tcf_ptoi { }; /** - * Initialize ingress qdisc of a given network interface. + * Create and configure a libmnl socket for Netlink flow rules. + * + * @return + * A valid libmnl socket object pointer on success, NULL otherwise and + * rte_errno is set. + */ +static struct mnl_socket * +mlx5_flow_mnl_socket_create(void) +{ + struct mnl_socket *nl = mnl_socket_open(NETLINK_ROUTE); + + if (nl) { + mnl_socket_setsockopt(nl, NETLINK_CAP_ACK, &(int){ 1 }, + sizeof(int)); + if (!mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID)) + return nl; + } + rte_errno = errno; + if (nl) + mnl_socket_close(nl); + return NULL; +} + +/** + * Destroy a libmnl socket. * * @param nl * Libmnl socket of the @p NETLINK_ROUTE kind. + */ +static void +mlx5_flow_mnl_socket_destroy(struct mnl_socket *nl) +{ + if (nl) + mnl_socket_close(nl); +} + +/** + * Initialize ingress qdisc of a given network interface. + * + * @param nl + * Pointer to tc-flower context to use. * @param ifindex * Index of network interface to initialize. * @param[out] error @@ -1573,8 +1624,8 @@ struct flow_tcf_ptoi { * 0 on success, a negative errno value otherwise and rte_errno is set. */ int -mlx5_flow_tcf_init(struct mnl_socket *nl, unsigned int ifindex, - struct rte_flow_error *error) +mlx5_flow_tcf_init(struct mlx5_flow_tcf_context *nl, + unsigned int ifindex, struct rte_flow_error *error) { struct nlmsghdr *nlh; struct tcmsg *tcm; @@ -1616,37 +1667,47 @@ struct flow_tcf_ptoi { } /** - * Create and configure a libmnl socket for Netlink flow rules. + * Create libmnl context for Netlink flow rules. * * @return * A valid libmnl socket object pointer on success, NULL otherwise and * rte_errno is set. */ -struct mnl_socket * -mlx5_flow_tcf_socket_create(void) +struct mlx5_flow_tcf_context * +mlx5_flow_tcf_context_create(void) { - struct mnl_socket *nl = mnl_socket_open(NETLINK_ROUTE); - - if (nl) { - mnl_socket_setsockopt(nl, NETLINK_CAP_ACK, &(int){ 1 }, - sizeof(int)); - if (!mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID)) - return nl; - } - rte_errno = errno; - if (nl) - mnl_socket_close(nl); + struct mlx5_flow_tcf_context *ctx = rte_zmalloc(__func__, + sizeof(*ctx), + sizeof(uint32_t)); + if (!ctx) + goto error; + ctx->nl = mlx5_flow_mnl_socket_create(); + if (!ctx->nl) + goto error; + ctx->buf_size = MNL_SOCKET_BUFFER_SIZE; + ctx->buf = rte_zmalloc(__func__, + ctx->buf_size, sizeof(uint32_t)); + if (!ctx->buf) + goto error; + ctx->seq = random(); + return ctx; +error: + mlx5_flow_tcf_context_destroy(ctx); return NULL; } /** - * Destroy a libmnl socket. + * Destroy a libmnl context. * * @param nl * Libmnl socket of the @p NETLINK_ROUTE kind. */ void -mlx5_flow_tcf_socket_destroy(struct mnl_socket *nl) +mlx5_flow_tcf_context_destroy(struct mlx5_flow_tcf_context *ctx) { - mnl_socket_close(nl); + if (!ctx) + return; + mlx5_flow_mnl_socket_destroy(ctx->nl); + rte_free(ctx->buf); + rte_free(ctx); } From patchwork Thu Oct 11 13:04:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moti Haimovsky X-Patchwork-Id: 46619 X-Patchwork-Delegate: shahafs@mellanox.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C45081B55C; Thu, 11 Oct 2018 15:04:39 +0200 (CEST) Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-eopbgr70078.outbound.protection.outlook.com [40.107.7.78]) by dpdk.org (Postfix) with ESMTP id 866EA1B549 for ; Thu, 11 Oct 2018 15:04:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=a93LNP8sqyirYoCK2Vl+/QWepbMBjzoQu8+zvnsFQ44=; b=JZaraNdckJbn8GaYpVRsPeafWe6H6VA+212uhm1ARE9MDGaaAZmRL2Y6KKj1pv8GVytQ5OUrQwM6tkL0zcgMTCzRfHqxuLqcPVdNLCpXKQwYKFkRgG1TAIkJElVYFEKsOBo/jKM8wp/ed6AvF1CCG+vJOAqzwjWZ71CyM+A1IIE= Received: from AM0PR05MB4435.eurprd05.prod.outlook.com (52.134.92.20) by AM0PR05MB4898.eurprd05.prod.outlook.com (20.177.41.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1207.28; Thu, 11 Oct 2018 13:04:35 +0000 Received: from AM0PR05MB4435.eurprd05.prod.outlook.com ([fe80::2549:a872:4864:b84e]) by AM0PR05MB4435.eurprd05.prod.outlook.com ([fe80::2549:a872:4864:b84e%6]) with mapi id 15.20.1207.029; Thu, 11 Oct 2018 13:04:35 +0000 From: Mordechay Haimovsky To: Shahaf Shuler CC: "dev@dpdk.org" , Mordechay Haimovsky Thread-Topic: [PATCH v2 2/2] net/mlx5: support e-switch flow count action Thread-Index: AQHUYWL1UOItk2Md5UWoTRs4HVyTAA== Date: Thu, 11 Oct 2018 13:04:35 +0000 Message-ID: <1539263057-16678-3-git-send-email-motih@mellanox.com> References: <1539263057-16678-1-git-send-email-motih@mellanox.com> In-Reply-To: <1539263057-16678-1-git-send-email-motih@mellanox.com> Accept-Language: he-IL, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: HE1PR05CA0223.eurprd05.prod.outlook.com (2603:10a6:3:fa::23) To AM0PR05MB4435.eurprd05.prod.outlook.com (2603:10a6:208:5a::20) authentication-results: spf=none (sender IP is ) smtp.mailfrom=motih@mellanox.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [37.142.13.130] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM0PR05MB4898; 6:NrXhHinLp0hklB+lrs/AlgXc+uLby9JL0ko5Ot85YDujZxb8FVhRAek7zkR47EYIpTxNSWTz+pW+NOEBprjv+r1rTOUmqQkSYeH9Egguu5atjd8q0WbN/DoL64YDG0kMzIldJiqLoRpeHHwdAj51pOqQhHTUm+EX3A7v2jG71gOfXQUhbb9F7FAhfYp+Pyzp7Y1HQpz6umj87e2obCq+SY4OJ5hXhWlIG02DhEB+TZz50wNcbEbz1IXWjLfP6GYGwjVdG544OJoxHspN9M+aXiZSR0u9AYIfMtRxnHhYxhneqdgEYzYWp5KnJCA8m0d6yTiygO0Dzn7+MDmAs30MJw8QsocoYHj1C/P5859fQZyTttDyJxZTrCDS1ZEbBp/pBl0ZuecEV2nC2HMJTNSAkEUm4L6VrZnaKdm3oiTR/jTbDyFrk7E/f8GAOdLVLwHDKRjH0V400P8pdN4hYqB8fQ==; 5:bNIT7jbergha+V6neepwhqEiV8FRD6EbuTrz5+sMYZX+1aO3vLG2iqeTF5qP56zKUEC9DYWDqnSx+3sJ8WIEvg1P/KvkASYym4SxBhXOJ6IKe3IPgOrCTHNvqgGbrckLH2CqwS6ONywnjKWt690OkIrbOKM2slhPylrgQoGWW7k=; 7:JKOKLfXHioAb87myR1KeOyhfrhEtKy+1+ZdcseRwT09mRs8mDkdc8NtO4IytGQWajmD6QtaaWsnVvLyk7FBI4AANuh1E/PswRiNAe0minUuDOvGjr483Z5dA+0vBT7HXNCjPorH/hj/l5MTY7YlC2nTTUuD/N8AM5ajml+3G2O53JP893I9dX9ue+rSHg8eL00O/vQEqJ5a+EQKaEvyaWCDI1b79MXsSOHsl1twluNNgQnib20Xd/QZ9Rr/l11sx x-ms-office365-filtering-correlation-id: 2e5db41b-68c0-4845-3636-08d62f7a17a5 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:AM0PR05MB4898; x-ms-traffictypediagnostic: AM0PR05MB4898: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(211171220733660); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3002001)(3231355)(944501410)(52105095)(10201501046)(93006095)(93001095)(6055026)(149066)(150057)(6041310)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123558120)(20161123564045)(201708071742011)(7699051); SRVR:AM0PR05MB4898; BCL:0; PCL:0; RULEID:; SRVR:AM0PR05MB4898; x-forefront-prvs: 08220FA8D6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(376002)(136003)(346002)(39860400002)(396003)(366004)(199004)(189003)(71200400001)(71190400001)(105586002)(53946003)(5250100002)(6862004)(4326008)(54906003)(2900100001)(99286004)(76176011)(52116002)(4744004)(106356001)(6116002)(97736004)(7736002)(2906002)(25786009)(305945005)(107886003)(3846002)(37006003)(5660300001)(66066001)(6636002)(86362001)(256004)(14444005)(14454004)(8936002)(476003)(2616005)(11346002)(446003)(486006)(36756003)(68736007)(186003)(26005)(102836004)(8676002)(81166006)(81156014)(6436002)(316002)(53936002)(6512007)(386003)(6506007)(6486002)(478600001)(42262002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR05MB4898; H:AM0PR05MB4435.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: IN+gd+cmdV0XVCIZYE2jTGXBHNM+6J80pCoRLOPdE0XEimtdIyqNJG2MtyXqAz2fbp752aB4a4ddMPOBirSRcSqM16g4j3VzZOk+Ks42yY6SN6fm/R7+sYbMThR4Z+YcUNN35F7hkuvFMnSXd7CmTqrAkyO3Zu54wEpMvTKEPCToTlKfh56KB6gm1FkEDnwOZHkN5wsXTE0oSIS9AfoTzgPPRTCA5F9DyGmca65XVCzlHlz2KfdTI+gtnY42DIIbzVUs4g2IetKtzmyxnwfOQ2+kbQpnwiIs9nI3m2otZqoC0Ikd+vywFYfC0RwtGf58veQP301h8WfX1W8aWQgyZT4Rr66o0/VHQKH6vf/LLvs= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2e5db41b-68c0-4845-3636-08d62f7a17a5 X-MS-Exchange-CrossTenant-originalarrivaltime: 11 Oct 2018 13:04:35.3225 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4898 Subject: [dpdk-dev] [PATCH v2 2/2] net/mlx5: support e-switch flow count action X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This commit adds support for configuring flows destined to the mlx5 eswitch with 'count' action and for querying these counts at runtime. It is possible to offload an interface flow rules to the hardware using DPDK flow commands. With mlx5 it is also possible to offload a limited set of flow rules to the mlxsw (or e-switch) using the same DPDK flow commands using the 'transfer' attribute in the flow rule creation command. The commands destined for the switch are transposed to TC flower rules and are sent, as Netlink messages, to the mlx5 driver (or more precisely to the netdev which represent the mlxsw port). Each flow rule configured by the mlx5 driver is also assigned with a set of flow counters implicitly. These counters can be retrieved when querying the flow rule via Netlink, they can be found in each flow action section of the reply. Currently the limited set of eswitch flow rules does not contain the 'count' action but since every rule contains a count we can still retrieve these values as if we configured a 'count' action. Supporting the 'count' action in the flow configuration command is straight-forward. When transposing the command to a tc flower Netlink message we just ignore it instead of rejecting it. So the following two commands will have the same affect and behavior: testpmd> flow create 0 transfer ingress pattern eth src is 11:22:33:44:55:77 dst is 11:22:33:44:55:88 / end actions drop / end testpmd> flow create 0 transfer ingress pattern eth src is 11:22:33:44:55:77 dst is 11:22:33:44:55:88 / end actions count / drop / end In the flow query side, the command now also returns the counts the above flow via using tc Netlink query command. Special care was taken in order to prevent Netlink messages truncation due to short buffers by using MNL_SOCKET_BUFFER_SIZE buffers which are pre-allocate per port instance. Signed-off-by: Moti Haimovsky --- v2: * Rebase on top of 3f4722ee01e7 ("net/mlx5: refactor TC-flow infrastructure") --- drivers/net/mlx5/mlx5_flow.c | 29 +++- drivers/net/mlx5/mlx5_flow.h | 14 +- drivers/net/mlx5/mlx5_flow_dv.c | 1 + drivers/net/mlx5/mlx5_flow_tcf.c | 286 ++++++++++++++++++++++++++++++++++++- drivers/net/mlx5/mlx5_flow_verbs.c | 1 + 5 files changed, 325 insertions(+), 6 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 6b2698a..7c6ece1 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -1649,6 +1649,17 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, { } +int +flow_null_query(struct rte_eth_dev *dev __rte_unused, + struct rte_flow *flow __rte_unused, + enum rte_flow_action_type type __rte_unused, + void *data __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + rte_errno = ENOTSUP; + return -rte_errno; +} + /* Void driver to protect from null pointer reference. */ const struct mlx5_flow_driver_ops mlx5_flow_null_drv_ops = { .validate = flow_null_validate, @@ -1657,6 +1668,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority, .apply = flow_null_apply, .remove = flow_null_remove, .destroy = flow_null_destroy, + .query = flow_null_query, }; /** @@ -2349,10 +2361,19 @@ struct rte_flow * * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_flow_query_count(struct rte_flow *flow __rte_unused, - void *data __rte_unused, +mlx5_flow_query_count(struct rte_eth_dev *dev, + struct rte_flow *flow, + void *data, struct rte_flow_error *error) { + const struct mlx5_flow_driver_ops *fops; + enum mlx5_flow_drv_type ftype = flow->drv_type; + + assert(ftype > MLX5_FLOW_TYPE_MIN && ftype < MLX5_FLOW_TYPE_MAX); + fops = flow_get_drv_ops(ftype); + if (ftype == MLX5_FLOW_TYPE_TCF) + return fops->query(dev, flow, + RTE_FLOW_ACTION_TYPE_COUNT, data, error); #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT if (flow->actions & MLX5_FLOW_ACTION_COUNT) { struct rte_flow_query_count *qc = data; @@ -2402,7 +2423,7 @@ struct rte_flow * * @see rte_flow_ops */ int -mlx5_flow_query(struct rte_eth_dev *dev __rte_unused, +mlx5_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow, const struct rte_flow_action *actions, void *data, @@ -2415,7 +2436,7 @@ struct rte_flow * case RTE_FLOW_ACTION_TYPE_VOID: break; case RTE_FLOW_ACTION_TYPE_COUNT: - ret = mlx5_flow_query_count(flow, data, error); + ret = mlx5_flow_query_count(dev, flow, data, error); break; default: return rte_flow_error_set(error, ENOTSUP, diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 41d55e8..3e1e9a0 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -175,6 +175,8 @@ struct mlx5_flow_dv { struct mlx5_flow_tcf { struct nlmsghdr *nlh; struct tcmsg *tcm; + uint64_t hits; + uint64_t bytes; }; /* Verbs specification header. */ @@ -232,7 +234,6 @@ struct rte_flow { struct rte_flow_action_rss rss;/**< RSS context. */ uint8_t key[MLX5_RSS_HASH_KEY_LEN]; /**< RSS hash key. */ uint16_t (*queue)[]; /**< Destination queues to redirect traffic to. */ - void *nl_flow; /**< Netlink flow buffer if relevant. */ LIST_HEAD(dev_flows, mlx5_flow) dev_flows; /**< Device flows that are part of the flow. */ uint32_t actions; /**< Bit-fields which mark all detected actions. */ @@ -258,6 +259,11 @@ typedef void (*mlx5_flow_remove_t)(struct rte_eth_dev *dev, struct rte_flow *flow); typedef void (*mlx5_flow_destroy_t)(struct rte_eth_dev *dev, struct rte_flow *flow); +typedef int (*mlx5_flow_query_t)(struct rte_eth_dev *dev, + struct rte_flow *flow, + enum rte_flow_action_type type, + void *data, + struct rte_flow_error *error); struct mlx5_flow_driver_ops { mlx5_flow_validate_t validate; mlx5_flow_prepare_t prepare; @@ -265,10 +271,16 @@ struct mlx5_flow_driver_ops { mlx5_flow_apply_t apply; mlx5_flow_remove_t remove; mlx5_flow_destroy_t destroy; + mlx5_flow_query_t query; }; /* mlx5_flow.c */ +int flow_null_query(struct rte_eth_dev *dev, + struct rte_flow *flow, + enum rte_flow_action_type type, + void *data, + struct rte_flow_error *error); uint64_t mlx5_flow_hashfields_adjust(struct mlx5_flow *dev_flow, int tunnel, uint32_t layer_types, uint64_t hash_fields); diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index c9aa50f..9c8d074 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -1365,6 +1365,7 @@ .apply = flow_dv_apply, .remove = flow_dv_remove, .destroy = flow_dv_destroy, + .query = flow_null_query, }; #endif /* HAVE_IBV_FLOW_DV_SUPPORT */ diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c index 8535a15..d12a566 100644 --- a/drivers/net/mlx5/mlx5_flow_tcf.c +++ b/drivers/net/mlx5/mlx5_flow_tcf.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -163,7 +164,8 @@ struct mlx5_flow_tcf_context { struct mnl_socket *nl; /* NETLINK_ROUTE libmnl socket. */ uint32_t seq; /* Message sequence number. */ uint32_t buf_size; /* Message buffer size. */ - uint8_t *buf; /* Message buffer. */ + uint8_t *buf; + /* Message buffer (used for receiving large netlink messages). */ }; /** Empty masks for known item types. */ @@ -696,6 +698,9 @@ struct flow_tcf_ptoi { "can't have multiple fate actions"); action_flags |= MLX5_FLOW_ACTION_DROP; break; + case RTE_FLOW_ACTION_TYPE_COUNT: + action_flags |= MLX5_FLOW_ACTION_COUNT; + break; case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: action_flags |= MLX5_FLOW_ACTION_OF_POP_VLAN; break; @@ -875,6 +880,9 @@ struct flow_tcf_ptoi { SZ_NLATTR_TYPE_OF(struct tc_gact); flags |= MLX5_FLOW_ACTION_DROP; break; + case RTE_FLOW_ACTION_TYPE_COUNT: + flags |= MLX5_FLOW_ACTION_COUNT; + break; case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: flags |= MLX5_FLOW_ACTION_OF_POP_VLAN; goto action_of_vlan; @@ -1360,6 +1368,12 @@ struct flow_tcf_ptoi { mnl_attr_nest_end(nlh, na_act); mnl_attr_nest_end(nlh, na_act_index); break; + case RTE_FLOW_ACTION_TYPE_COUNT: + /* + * Driver adds the count action implicitly for + * each rule it creates. + */ + break; case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: conf.of_push_vlan = NULL; vlan_act = TCA_VLAN_ACT_POP; @@ -1564,6 +1578,275 @@ struct flow_tcf_ptoi { rte_free(dev_flow); } +/** + * Parse rtnetlink message attributes filling the attribute table with the info + * being retrieved. + * + * @param tb + * Attribute table to be filled. + * @param[out] max + * Maxinum entry in the attribute table. + * @param rte + * The attributes section in the message to be parsed. + * @param len + * The length of the attributes section in the message. + * @return + * 0 on successful extraction of action counts, -1 otherwise. + */ +static void +tc_parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) +{ + unsigned short type; + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); + while (RTA_OK(rta, len)) { + type = rta->rta_type; + if (type <= max && !tb[type]) + tb[type] = rta; + rta = RTA_NEXT(rta, len); + } +} + + /** + * Extract action counters from flower action. + * + * @param rta + * flower action stats properties in the Netlink message received. + * @param[out] qc + * Count statistics retrieved from the message query. + * @return + * 0 on successful extraction of action counts, -1 otherwise. + */ +static int +tc_flow_extract_stats_attr(struct rtattr *rta, struct rte_flow_query_count *qc) +{ + struct rtattr *tbs[TCA_STATS_MAX + 1]; + + tc_parse_rtattr(tbs, TCA_STATS_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)); + if (tbs[TCA_STATS_BASIC]) { + struct gnet_stats_basic bs = {0}; + + memcpy(&bs, RTA_DATA(tbs[TCA_STATS_BASIC]), + RTE_MIN(RTA_PAYLOAD(tbs[TCA_STATS_BASIC]), + sizeof(bs))); + qc->bytes = bs.bytes; + qc->hits = bs.packets; + qc->bytes_set = 1; + qc->hits_set = 1; + return 0; + } + return -1; +} + + /** + * Parse flower single action retrieving the flow counters from it if present. + * + * @param arg + * flower action properties in the Netlink message received. + * @param[out] qc + * Count statistics retrieved from the message query. + * @return + * 0 on successful retrieval of action counts, -1 otherwise. + */ +static int +tc_flow_parse_one_action(struct rtattr *arg, struct rte_flow_query_count *qc) +{ + struct rtattr *tb[TCA_ACT_MAX + 1]; + + if (arg == NULL) + return -1; + tc_parse_rtattr(tb, TCA_ACT_MAX, RTA_DATA(arg), RTA_PAYLOAD(arg)); + if (tb[TCA_ACT_KIND] == NULL) + return -1; + if (tb[TCA_ACT_STATS]) + return tc_flow_extract_stats_attr(tb[TCA_ACT_STATS], qc); + return -1; +} + + /** + * Parse flower action section in the message, retrieving the flow counters + * from the first action that contains them. + * flow counters are stored in the actions defined by the flow and not in the + * flow itself, therefore we need to traverse the flower action in search for + * them. + * + * @param opt + * flower section in the Netlink message received. + * @param[out] qc + * Count statistics retrieved from the message query. + */ +static void +tc_flow_parse_action(const struct rtattr *arg, struct rte_flow_query_count *qc) +{ + struct rtattr *tb[TCA_ACT_MAX_PRIO + 1]; + int i; + + if (arg == NULL) + return; + tc_parse_rtattr(tb, TCA_ACT_MAX_PRIO, RTA_DATA(arg), RTA_PAYLOAD(arg)); + for (i = 0; i <= TCA_ACT_MAX_PRIO; i++) + if (tb[i]) + if (tc_flow_parse_one_action(tb[i], qc) == 0) + break; +} + + /** + * Parse Netlink reply on flower type of filters, retrieving the flow counters + * from it. + * + * @param opt + * flower section in the Netlink message received. + * @param[out] qc + * Count statistics retrieved from the message query. + */ +static void +tc_flower_parse_opt(struct rtattr *opt, + struct rte_flow_query_count *qc) +{ + struct rtattr *tb[TCA_FLOWER_MAX + 1]; + + if (!opt) + return; + tc_parse_rtattr(tb, TCA_FLOWER_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)); + if (tb[TCA_FLOWER_ACT]) + tc_flow_parse_action(tb[TCA_FLOWER_ACT], qc); +} + + /** + * Parse Netlink reply on filter query, retrieving the flow counters. + * + * @param nlh + * Message received from Netlink. + * @param[out] qc + * Count statistics retrieved from the message query. + * + * @return + * MNL_CB_ERROR on error, MNL_CB_OK value otherwise. + */ +static int +mlx5_nl_flow_parse_filter(const struct nlmsghdr *nlh, + struct rte_flow_query_count *qc) +{ + struct tcmsg *t = NLMSG_DATA(nlh); + int len = nlh->nlmsg_len; + struct rtattr *tb[TCA_MAX + 1] = { }; + + if (nlh->nlmsg_type != RTM_NEWTFILTER && + nlh->nlmsg_type != RTM_GETTFILTER && + nlh->nlmsg_type != RTM_DELTFILTER) + return MNL_CB_OK; + len -= NLMSG_LENGTH(sizeof(*t)); + if (len < 0) + return MNL_CB_ERROR; + tc_parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len); + if (tb[TCA_KIND]) + if (strcmp(RTA_DATA(tb[TCA_KIND]), "flower") == 0) + tc_flower_parse_opt(tb[TCA_OPTIONS], qc); + return MNL_CB_OK; +} + +/** + * A callback to parse Netlink reply on filter query attempting to retrieve the + * flow counters if present. + * + * @param nlh + * Message received from Netlink. + * @param[out] data + * pointer to the count statistics to be filled by the routine. + * + * @return + * MNL_CB_ERROR on error, MNL_CB_OK value otherwise. + */ +static int +mlx5_nl_flow_parse_message(const struct nlmsghdr *nlh, void *data) +{ + struct rte_flow_query_count *qc = (struct rte_flow_query_count *)data; + + switch (nlh->nlmsg_type) { + case NLMSG_NOOP: + return MNL_CB_OK; + case NLMSG_ERROR: + case NLMSG_OVERRUN: + return MNL_CB_ERROR; + default: + break; + } + return mlx5_nl_flow_parse_filter(nlh, qc); +} + + /** + * Query a tcf rule for its statistics via netlink. + * + * @param[in] dev + * Pointer to Ethernet device. + * @param[in] flow + * Pointer to the sub flow. + * @param[out] data + * data retrieved by the query. + * @param[out] error + * Perform verbose error reporting if not NULL. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_flow_tcf_query(struct rte_eth_dev *dev, + struct rte_flow *flow, + enum rte_flow_action_type type, + void *data, + struct rte_flow_error *error) +{ + struct rte_flow_query_count *qc = data; + struct priv *priv = dev->data->dev_private; + struct mlx5_flow_tcf_context *ctx = priv->tcf_context; + struct mnl_socket *nl = ctx->nl; + struct mlx5_flow *dev_flow; + struct nlmsghdr *nlh; + uint32_t seq = priv->tcf_context->seq++; + ssize_t ret; + assert(qc); + + dev_flow = LIST_FIRST(&flow->dev_flows); + /* E-Switch flow can't be expanded. */ + assert(!LIST_NEXT(dev_flow, next)); + /* Currently only query count is supported. */ + if (type != RTE_FLOW_ACTION_TYPE_COUNT) + goto error_nosup; + nlh = dev_flow->tcf.nlh; + nlh->nlmsg_type = RTM_GETTFILTER; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ECHO; + nlh->nlmsg_seq = seq; + if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) == -1) + goto error_exit; + ret = mnl_socket_recvfrom(nl, priv->tcf_context->buf, + priv->tcf_context->buf_size); + if (ret == -1) + goto error_exit; + while (ret > 0) { + ret = mnl_cb_run(ctx->buf, ret, seq, + mnl_socket_get_portid(nl), + mlx5_nl_flow_parse_message, qc); + if (ret <= MNL_CB_STOP) + break; + ret = mnl_socket_recvfrom(nl, ctx->buf, ctx->buf_size); + } + /* Return the delta from last reset. */ + qc->hits -= dev_flow->tcf.hits; + qc->bytes -= dev_flow->tcf.bytes; + if (qc->reset) { + dev_flow->tcf.hits = qc->hits; + dev_flow->tcf.bytes = qc->bytes; + } + return 0; +error_nosup: + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "tcf: unsupported query"); +error_exit: + return rte_flow_error_set + (error, errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "netlink: failed to read flow rule statistics"); +} + const struct mlx5_flow_driver_ops mlx5_flow_tcf_drv_ops = { .validate = flow_tcf_validate, .prepare = flow_tcf_prepare, @@ -1571,6 +1854,7 @@ struct flow_tcf_ptoi { .apply = flow_tcf_apply, .remove = flow_tcf_remove, .destroy = flow_tcf_destroy, + .query = mlx5_flow_tcf_query, }; /** diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c index ad8f7ac..e377b3b 100644 --- a/drivers/net/mlx5/mlx5_flow_verbs.c +++ b/drivers/net/mlx5/mlx5_flow_verbs.c @@ -1655,4 +1655,5 @@ .apply = flow_verbs_apply, .remove = flow_verbs_remove, .destroy = flow_verbs_destroy, + .query = flow_null_query, };