From patchwork Fri Aug 31 09:57:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 44084 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 03F9D4F94; Fri, 31 Aug 2018 11:57:54 +0200 (CEST) Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by dpdk.org (Postfix) with ESMTP id CD5FC4CC3 for ; Fri, 31 Aug 2018 11:57:50 +0200 (CEST) Received: by mail-wm0-f68.google.com with SMTP id r1-v6so800896wmh.0 for ; Fri, 31 Aug 2018 02:57:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=cj0hMPuuZ8uy7+SYxlK6j9pIQLbCY1Yk/imHufSRXCs=; b=kW1QA3mudUSbjpJRAvkTsVkGoPLQbmx2KM2FnQoZ/vpBZ1eoW4G9PKZE7+CB0Zqszh 9Gk5afieJR/dKlJda0kr0Pa4hM8+1dv5N0x89I26VXVJL5GgOfzYqWgWn2pR5kG9kXMu wKuIqTQHC1OkA3QMFZcNLmWuLkLFXYToOxohZL6OyqVAvuRrSi/dr27hg7lolpABSYaU BdA39ftkDLZcngn4rDtRWzvrOb1WW1csbXmdXnYklnC9FOicpMimR/zr5bLbL/zsUhYT DDHwnzyQg9aQ26SqovUg8KEGIsZ/289kPyYwzzJfwqbcWje/Cn1Wp2MHoNyZzKlzi0/8 WJag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=cj0hMPuuZ8uy7+SYxlK6j9pIQLbCY1Yk/imHufSRXCs=; b=UOS6lNbi33e+LV3ODN420rZn5/iPLMKeXS2xxfMWcvP9ubn+PtqwyfK0NQ4lVBx4NU yxnB2tMbkZ1pexcv+JSqHH/VMYtrwuyKfP/F8Jrln85rxQGkT5D00vZ0RKeXY1xJB/63 Tm5ZeFDvfGMaQZ12f3CZ+Sls+wgCtzKSBZarM02BCZJvFH7aDPF8cEJhx7Pwg1RdnxTD k9g9HAfOdfthHXEvwDInNXEOxZLHnUkcjO8GQGEbY96PHneaYH+pKe8Lo8CSpikqat2k jWHYt/82+9HSXjZA4OIAMqSDnp1suSbZtnamCVrO6tCToYMsMQNKDyWTZNC+ryKZyLc6 hgLw== X-Gm-Message-State: APzg51DvNx1De3F61xcDpBcD8m6eWx0cc6EI7+Bl4Wv4DUB9GWD6Sdqm YXZ4q84E69hPs2OG0rYxamP+/w== X-Google-Smtp-Source: ANB0VdbN0VHaYcr4h1QzzlVtrivYwvnH6vCf/BZ1+tNMwO4il+2F06Fii8W8MOuxH18WBdb7ao+BOQ== X-Received: by 2002:a1c:889:: with SMTP id 131-v6mr4091422wmi.142.1535709470530; Fri, 31 Aug 2018 02:57:50 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id r1-v6sm4995965wmg.9.2018.08.31.02.57.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 31 Aug 2018 02:57:49 -0700 (PDT) Date: Fri, 31 Aug 2018 11:57:34 +0200 From: Adrien Mazarguil To: Shahaf Shuler , Yongseok Koh , Slava Ovsiienko Cc: dev@dpdk.org Message-ID: <20180831092038.23051-5-adrien.mazarguil@6wind.com> References: <20180831092038.23051-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180831092038.23051-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH 4/8] net/mlx5: enhance TC flow rule send/ack function 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" A callback parameter to process replies will be useful for subsequent work in this area. It implies the following: - Replies may be much larger than requests. In fact their size cannot really be known in advance. Using MNL_SOCKET_BUFFER_SIZE (at least 8192 bytes) is the recommended approach to make truncation less likely (look for NLMSG_GOODSIZE in Linux). - Multipart replies are made of several messages. A loop is needed to process these. - In case of truncated message (since one cannot really be sure), its remaining parts must be flushed to prevent their reception by subsequent queries. - Using rte_get_tsc_cycles() instead of random() for message sequence numbers is faster yet unlikely to pick the same number twice in a row. - mlx5_nl_flow_init() can be simplified since the query message is never written over (it was already the case actually). Signed-off-by: Adrien Mazarguil --- drivers/net/mlx5/mlx5_nl_flow.c | 73 ++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/drivers/net/mlx5/mlx5_nl_flow.c b/drivers/net/mlx5/mlx5_nl_flow.c index 9ea2a1b55..e720728b7 100644 --- a/drivers/net/mlx5/mlx5_nl_flow.c +++ b/drivers/net/mlx5/mlx5_nl_flow.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -1050,38 +1051,63 @@ mlx5_nl_flow_brand(void *buf, uint32_t handle) } /** - * Send Netlink message with acknowledgment. + * Send Netlink message with acknowledgment and process reply. * * @param nl * Libmnl socket to use. * @param nlh - * Message to send. This function always raises the NLM_F_ACK flag before - * sending. + * Message to send. This function always raises the NLM_F_ACK flag and + * sets its sequence number before sending. + * @param cb + * Callback handler for received message. + * @param arg + * Data pointer for callback handler. * * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_nl_flow_nl_ack(struct mnl_socket *nl, struct nlmsghdr *nlh) +mlx5_nl_flow_chat(struct mnl_socket *nl, struct nlmsghdr *nlh, + mnl_cb_t cb, void *arg) { alignas(struct nlmsghdr) - uint8_t ans[mnl_nlmsg_size(sizeof(struct nlmsgerr)) + - nlh->nlmsg_len - sizeof(*nlh)]; - uint32_t seq = random(); + uint8_t ans[MNL_SOCKET_BUFFER_SIZE]; + unsigned int portid = mnl_socket_get_portid(nl); + uint32_t seq = rte_get_tsc_cycles(); + int err = 0; int ret; nlh->nlmsg_flags |= NLM_F_ACK; nlh->nlmsg_seq = seq; ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len); - if (ret != -1) + nlh = (void *)ans; + /* + * The following loop postpones non-fatal errors until multipart + * messages are complete. + */ + while (ret > 0) { ret = mnl_socket_recvfrom(nl, ans, sizeof(ans)); - if (ret != -1) - ret = mnl_cb_run - (ans, ret, seq, mnl_socket_get_portid(nl), NULL, NULL); - if (!ret) + if (ret == -1) { + err = errno; + if (err != ENOSPC) + break; + ret = sizeof(*nlh); + } + if (!err) { + ret = mnl_cb_run(nlh, ret, seq, portid, cb, arg); + if (ret < 0) + err = -ret; + } + if (!(nlh->nlmsg_flags & NLM_F_MULTI) || + nlh->nlmsg_type == NLMSG_DONE) + ret = -err; + else + ret = 1; + } + if (!err) return 0; - rte_errno = errno; - return -rte_errno; + rte_errno = err; + return -err; } /** @@ -1105,7 +1131,7 @@ mlx5_nl_flow_create(struct mnl_socket *nl, void *buf, nlh->nlmsg_type = RTM_NEWTFILTER; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL; - if (!mlx5_nl_flow_nl_ack(nl, nlh)) + if (!mlx5_nl_flow_chat(nl, nlh, NULL, NULL)) return 0; return rte_flow_error_set (error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, @@ -1133,7 +1159,7 @@ mlx5_nl_flow_destroy(struct mnl_socket *nl, void *buf, nlh->nlmsg_type = RTM_DELTFILTER; nlh->nlmsg_flags = NLM_F_REQUEST; - if (!mlx5_nl_flow_nl_ack(nl, nlh)) + if (!mlx5_nl_flow_chat(nl, nlh, NULL, NULL)) return 0; return rte_flow_error_set (error, errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, @@ -1171,23 +1197,20 @@ mlx5_nl_flow_ifindex_init(struct mnl_socket *nl, unsigned int ifindex, tcm->tcm_ifindex = ifindex; tcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0); tcm->tcm_parent = TC_H_INGRESS; + if (!mnl_attr_put_strz_check(nlh, sizeof(buf), TCA_KIND, "ingress")) + return rte_flow_error_set + (error, ENOBUFS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "netlink: not enough space for message"); /* Ignore errors when qdisc is already absent. */ - if (mlx5_nl_flow_nl_ack(nl, nlh) && + if (mlx5_nl_flow_chat(nl, nlh, NULL, NULL) && rte_errno != EINVAL && rte_errno != ENOENT) return rte_flow_error_set (error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "netlink: failed to remove ingress qdisc"); /* Create fresh ingress qdisc. */ - nlh = mnl_nlmsg_put_header(buf); nlh->nlmsg_type = RTM_NEWQDISC; nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL; - tcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm)); - tcm->tcm_family = AF_UNSPEC; - tcm->tcm_ifindex = ifindex; - tcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0); - tcm->tcm_parent = TC_H_INGRESS; - mnl_attr_put_strz_check(nlh, sizeof(buf), TCA_KIND, "ingress"); - if (mlx5_nl_flow_nl_ack(nl, nlh)) + if (mlx5_nl_flow_chat(nl, nlh, NULL, NULL)) return rte_flow_error_set (error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "netlink: failed to create ingress qdisc");