From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9CAF4C10F11 for ; Wed, 10 Apr 2019 11:21:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6172120820 for ; Wed, 10 Apr 2019 11:21:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554895305; bh=PhJYZ3S5wa3FfMH2rsU44pTFnX6gJJ+OkrQcNGxgDMQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=WpYEfeO03XqH2JWnKOmBvP7KHfd6zRItKA0M1IPWunTOp0xOilgCHqVbZocThc8oN nRmTinD5hQPJ3QK8qVqvpoMWATI0320c4ZugL5QcFCEQhxRkNvxJVXO5Qz8usikYgn Bpkrm45uhUgammiEwfjIS6SLMVgr+cJoQpV45jnQ= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730785AbfDJLVo (ORCPT ); Wed, 10 Apr 2019 07:21:44 -0400 Received: from mail.kernel.org ([198.145.29.99]:36356 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728757AbfDJLVn (ORCPT ); Wed, 10 Apr 2019 07:21:43 -0400 Received: from localhost (unknown [77.138.135.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6C7EC20820; Wed, 10 Apr 2019 11:21:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554895302; bh=PhJYZ3S5wa3FfMH2rsU44pTFnX6gJJ+OkrQcNGxgDMQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cwgJL6U0za5aQ4WGlObzW5NBIAG4L0WEePgDCIZsVZera+gyLRUsliF5sQfu12WTw Y/P1BCPjKwtOefj6OUqZz19VfGrwgR8jMG2sK1JRF7iRmgVi+P+bcyAmVo01VdTaLY e7mpvxYzNLY/7aOpCQE1QpEvycp0dla6tFzcg7nU= From: Leon Romanovsky To: David Ahern Cc: Leon Romanovsky , netdev , Mark Zhang , RDMA mailing list , Stephen Hemminger Subject: [PATCH iproute2-next 6/8] rdma: Add stat manual mode support Date: Wed, 10 Apr 2019 14:21:19 +0300 Message-Id: <20190410112121.6790-7-leon@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190410112121.6790-1-leon@kernel.org> References: <20190410112121.6790-1-leon@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Mark Zhang In manual mode a QP can be manually bound to a counter. If counter is not specified that kernel will allocate one. And in unbind if lqpn is not specified then all QPs on this counter will be unbound. The manual and auto mode are mutual-exclusive. Examples: $ rdma statistic qp bind link mlx5_2/1 lqpn 178 $ rdma statistic qp bind link mlx5_2/1 lqpn 178 cntn 4 $ rdma statistic qp unbind link mlx5_2/1 cntn 4 $ rdma statistic qp unbind link mlx5_2/1 cntn 4 lqpn 178 Signed-off-by: Mark Zhang Signed-off-by: Leon Romanovsky --- rdma/stat.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) diff --git a/rdma/stat.c b/rdma/stat.c index aec0e837..c5395692 100644 --- a/rdma/stat.c +++ b/rdma/stat.c @@ -20,6 +20,8 @@ static int stat_help(struct rd *rd) pr_out(" %s statistic OBJECT show link [ DEV/PORT_INDEX ] [ FILTER-NAME FILTER-VALUE ]\n", rd->filename); pr_out(" %s statistic OBJECT mode\n", rd->filename); pr_out(" %s statistic OBJECT set COUNTER_SCOPE [DEV/PORT_INDEX] auto {CRITERIA | off}\n", rd->filename); + pr_out(" %s statistic OBJECT bind COUNTER_SCOPE [DEV/PORT_INDEX] [OBJECT-ID] [COUNTER-ID]\n", rd->filename); + pr_out(" %s statistic OBJECT unbind COUNTER_SCOPE [DEV/PORT_INDEX] [COUNTER-ID]\n", rd->filename); pr_out("where OBJECT: = { qp }\n"); pr_out(" CRITERIA : = { type }\n"); pr_out(" COUNTER_SCOPE: = { link | dev }\n"); @@ -30,6 +32,10 @@ static int stat_help(struct rd *rd) pr_out(" %s statistic qp mode link mlx5_0\n", rd->filename); pr_out(" %s statistic qp set link mlx5_2/1 auto type on\n", rd->filename); pr_out(" %s statistic qp set link mlx5_2/1 auto off\n", rd->filename); + pr_out(" %s statistic qp bind link mlx5_2/1 lqpn 178\n", rd->filename); + pr_out(" %s statistic qp bind link mlx5_2/1 lqpn 178 cntn 4\n", rd->filename); + pr_out(" %s statistic qp unbind link mlx5_2/1 cntn 4\n", rd->filename); + pr_out(" %s statistic qp unbind link mlx5_2/1 cntn 4 lqpn 178\n", rd->filename); return 0; } @@ -478,6 +484,216 @@ static int stat_qp_set(struct rd *rd) return rd_exec_cmd(rd, cmds, "parameter"); } +static int qp_bind_unbind_parse_cb(const struct nlmsghdr *nlh, void *data) +{ + struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; + + mnl_attr_parse(nlh, 0, rd_attr_cb, tb); + if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] || + !tb[RDMA_NLDEV_ATTR_RES_LQPN] || !tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]) + return MNL_CB_ERROR; + + return MNL_CB_OK; +} + +static int stat_get_arg(struct rd *rd, const char *arg) +{ + int value = 0; + char *endp; + + if (strcmpx(rd_argv(rd), arg) != 0) + return -EINVAL; + + rd_arg_inc(rd); + value = strtol(rd_argv(rd), &endp, 10); + rd_arg_inc(rd); + + return value; +} + +static int stat_one_qp_bind(struct rd *rd) +{ + int lqpn = 0, cntn = 0, ret; + uint32_t seq; + + if (rd_no_arg(rd)) { + stat_help(rd); + return -EINVAL; + } + + ret = rd_build_filter(rd, stat_valid_filters); + if (ret) + return ret; + + lqpn = stat_get_arg(rd, "lqpn"); + + rd_prepare_msg(rd, RDMA_NLDEV_CMD_STAT_SET, + &seq, (NLM_F_REQUEST | NLM_F_ACK)); + + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_MODE, + RDMA_COUNTER_MODE_MANUAL); + + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_RES, RDMA_NLDEV_ATTR_RES_QP); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_RES_LQPN, lqpn); + + if (rd_argc(rd)) { + cntn = stat_get_arg(rd, "cntn"); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_COUNTER_ID, + cntn); + } + + ret = rd_send_msg(rd); + if (ret) + return ret; + + if (rd->json_output) + jsonw_start_object(rd->jw); + ret = rd_recv_msg(rd, qp_bind_unbind_parse_cb, rd, seq); + if (rd->json_output) + jsonw_end_object(rd->jw); + + return ret; +} + +static int do_stat_qp_unbind_lqpn(struct rd *rd, uint32_t cntn, uint32_t lqpn) +{ + uint32_t seq; + int ret; + + rd_prepare_msg(rd, RDMA_NLDEV_CMD_STAT_DEL, + &seq, (NLM_F_REQUEST | NLM_F_ACK)); + + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_MODE, + RDMA_COUNTER_MODE_MANUAL); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_RES, RDMA_NLDEV_ATTR_RES_QP); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_COUNTER_ID, cntn); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_RES_LQPN, lqpn); + + ret = rd_send_msg(rd); + if (ret) + return ret; + + return rd_recv_msg(rd, qp_bind_unbind_parse_cb, rd, seq); +} + +static int stat_get_counter_parse_cb(const struct nlmsghdr *nlh, void *data) +{ + struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; + struct nlattr *nla_table, *nla_entry; + struct rd *rd = data; + uint32_t lqpn, cntn; + int err; + + mnl_attr_parse(nlh, 0, rd_attr_cb, tb); + + if (!tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]) + return MNL_CB_ERROR; + cntn = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]); + + nla_table = tb[RDMA_NLDEV_ATTR_RES_QP]; + if (!nla_table) + return MNL_CB_ERROR; + + mnl_attr_for_each_nested(nla_entry, nla_table) { + struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; + + err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); + if (err != MNL_CB_OK) + return -EINVAL; + + if (!nla_line[RDMA_NLDEV_ATTR_RES_LQPN]) + return -EINVAL; + + lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]); + err = do_stat_qp_unbind_lqpn(rd, cntn, lqpn); + if (err) + return MNL_CB_ERROR; + } + + return MNL_CB_OK; +} + +static int stat_one_qp_unbind(struct rd *rd) +{ + int flags = NLM_F_REQUEST | NLM_F_ACK, ret; + char buf[MNL_SOCKET_BUFFER_SIZE]; + int lqpn = 0, cntn = 0; + unsigned int portid; + uint32_t seq; + + ret = rd_build_filter(rd, stat_valid_filters); + if (ret) + return ret; + + cntn = stat_get_arg(rd, "cntn"); + if (rd_argc(rd)) { + lqpn = stat_get_arg(rd, "lqpn"); + return do_stat_qp_unbind_lqpn(rd, cntn, lqpn); + } + + rd_prepare_msg(rd, RDMA_NLDEV_CMD_STAT_GET, &seq, flags); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_COUNTER_ID, cntn); + ret = rd_send_msg(rd); + if (ret) + return ret; + + + /* Can't use rd_recv_msg() since the callback also calls it (recursively), + * then rd_recv_msg() always return -1 here + */ + portid = mnl_socket_get_portid(rd->nl); + ret = mnl_socket_recvfrom(rd->nl, buf, sizeof(buf)); + if (ret <= 0) + return ret; + + ret = mnl_cb_run(buf, ret, seq, portid, stat_get_counter_parse_cb, rd); + mnl_socket_close(rd->nl); + if (ret != MNL_CB_OK) + return ret; + + return 0; +} + +static int stat_qp_bind_link(struct rd *rd) +{ + return rd_exec_link(rd, stat_one_qp_bind, true); +} + +static int stat_qp_bind(struct rd *rd) +{ + const struct rd_cmd cmds[] = { + { NULL, stat_help }, + { "link", stat_qp_bind_link }, + { "help", stat_help }, + { 0 }, + }; + + return rd_exec_cmd(rd, cmds, "parameter"); +} + +static int stat_qp_unbind_link(struct rd *rd) +{ + return rd_exec_link(rd, stat_one_qp_unbind, true); +} + +static int stat_qp_unbind(struct rd *rd) +{ + const struct rd_cmd cmds[] = { + { NULL, stat_help }, + { "link", stat_qp_unbind_link }, + { "help", stat_help }, + { 0 }, + }; + + return rd_exec_cmd(rd, cmds, "parameter"); +} + static int stat_qp(struct rd *rd) { const struct rd_cmd cmds[] = { @@ -486,6 +702,8 @@ static int stat_qp(struct rd *rd) { "list", stat_qp_show }, { "mode", stat_qp_get_mode }, { "set", stat_qp_set }, + { "bind", stat_qp_bind }, + { "unbind", stat_qp_unbind }, { "help", stat_help }, { 0 } }; -- 2.20.1