All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leon Romanovsky <leon@kernel.org>
To: David Ahern <dsahern@gmail.com>
Cc: Leon Romanovsky <leonro@mellanox.com>,
	netdev <netdev@vger.kernel.org>,
	RDMA mailing list <linux-rdma@vger.kernel.org>,
	Stephen Hemminger <stephen@networkplumber.org>,
	Steve Wise <swise@opengridcomputing.com>
Subject: [PATCH iproute2-next v2 18/19] rdma: Perform single .doit call to query specific objects
Date: Sat, 23 Feb 2019 11:15:27 +0200	[thread overview]
Message-ID: <20190223091528.8509-19-leon@kernel.org> (raw)
In-Reply-To: <20190223091528.8509-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

If user provides specific index, we can speedup query
by using .doit callback and save full dump and filtering
after that.

Reviewed-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/rdma.h     | 10 +++++-
 rdma/res-cmid.c | 33 +++++++++++++------
 rdma/res-cq.c   | 34 ++++++++++++++------
 rdma/res-mr.c   | 33 ++++++++++++++-----
 rdma/res-pd.c   | 32 ++++++++++++++-----
 rdma/res-qp.c   | 32 ++++++++++++++-----
 rdma/res.c      | 34 +++++++++++++++++++-
 rdma/res.h      | 84 ++++++++++++++++++++++++++++++++-----------------
 rdma/utils.c    | 20 ++++++++++++
 9 files changed, 239 insertions(+), 73 deletions(-)

diff --git a/rdma/rdma.h b/rdma/rdma.h
index d2559e7c..e86c7f21 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -30,13 +30,20 @@
 #define MAX_NUMBER_OF_FILTERS 64
 struct filters {
 	const char *name;
-	bool is_number;
+	uint8_t is_number:1;
+	uint8_t is_doit:1;
 };
 
 struct filter_entry {
 	struct list_head list;
 	char *key;
 	char *value;
+	/*
+	 * This field menas that we can try to issue .doit calback
+	 * on value above. This value can be converted to integer
+	 * with simple atoi(). Otherwise "is_doit" will be false.
+	 */
+	uint8_t is_doit:1;
 };
 
 struct dev_map {
@@ -101,6 +108,7 @@ struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index);
 /*
  * Filter manipulation
  */
+bool rd_doit_index(struct rd *rd, uint32_t *idx);
 int rd_build_filter(struct rd *rd, const struct filters valid_filters[]);
 bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val);
 bool rd_check_is_string_filtered(struct rd *rd, const char *key, const char *val);
diff --git a/rdma/res-cmid.c b/rdma/res-cmid.c
index 22d99a8b..0b61e433 100644
--- a/rdma/res-cmid.c
+++ b/rdma/res-cmid.c
@@ -107,11 +107,9 @@ static int ss_ntop(struct nlattr *nla_line, char *addr_str, uint16_t *port)
 	}
 	return 0;
 }
-
 static int res_cm_id_line(struct rd *rd, const char *name, int idx,
-			  struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	char src_addr_str[INET6_ADDRSTRLEN];
 	char dst_addr_str[INET6_ADDRSTRLEN];
 	uint16_t src_port, dst_port;
@@ -120,11 +118,6 @@ static int res_cm_id_line(struct rd *rd, const char *name, int idx,
 	uint32_t lqpn = 0, ps;
 	uint32_t cm_idn = 0;
 	char *comm = NULL;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_STATE] ||
 	    !nla_line[RDMA_NLDEV_ATTR_RES_PS] ||
@@ -225,6 +218,23 @@ out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
 	return MNL_CB_OK;
 }
 
+int res_cm_id_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	int idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_cm_id_line(rd, name, idx, tb);
+}
+
 int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -244,8 +254,13 @@ int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_CM_ID];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_cm_id_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
 
+		ret = res_cm_id_line(rd, name, idx, nla_line);
 		if (ret != MNL_CB_OK)
 			break;
 	}
diff --git a/rdma/res-cq.c b/rdma/res-cq.c
index cea4f6bd..c14637e6 100644
--- a/rdma/res-cq.c
+++ b/rdma/res-cq.c
@@ -31,9 +31,8 @@ static void print_poll_ctx(struct rd *rd, uint8_t poll_ctx, struct nlattr *attr)
 }
 
 static int res_cq_line(struct rd *rd, const char *name, int idx,
-		       struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	char *comm = NULL;
 	uint32_t pid = 0;
 	uint8_t poll_ctx = 0;
@@ -41,11 +40,6 @@ static int res_cq_line(struct rd *rd, const char *name, int idx,
 	uint32_t cqn = 0;
 	uint64_t users;
 	uint32_t cqe;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_CQE] ||
 	    !nla_line[RDMA_NLDEV_ATTR_RES_USECNT] ||
@@ -80,7 +74,6 @@ static int res_cq_line(struct rd *rd, const char *name, int idx,
 		cqn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CQN]);
 	if (rd_check_is_filtered(rd, "cqn", cqn))
 		goto out;
-
 	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
 		ctxn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
 	if (rd_check_is_filtered(rd, "ctxn", ctxn))
@@ -112,6 +105,23 @@ out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
 	return MNL_CB_OK;
 }
 
+int res_cq_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	uint32_t idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_cq_line(rd, name, idx, tb);
+}
+
 int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -131,7 +141,13 @@ int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_CQ];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_cq_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
+
+		ret = res_cq_line(rd, name, idx, nla_line);
 
 		if (ret != MNL_CB_OK)
 			break;
diff --git a/rdma/res-mr.c b/rdma/res-mr.c
index 82e6d150..d42e8d81 100644
--- a/rdma/res-mr.c
+++ b/rdma/res-mr.c
@@ -8,20 +8,14 @@
 #include <inttypes.h>
 
 static int res_mr_line(struct rd *rd, const char *name, int idx,
-		       struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	uint32_t rkey = 0, lkey = 0;
 	uint64_t iova = 0, mrlen;
 	char *comm = NULL;
 	uint32_t pdn = 0;
 	uint32_t mrn = 0;
 	uint32_t pid = 0;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_MRLEN] ||
 	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
@@ -84,6 +78,24 @@ out:
 		free(comm);
 	return MNL_CB_OK;
 }
+
+int res_mr_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	uint32_t idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_mr_line(rd, name, idx, tb);
+}
+
 int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -103,8 +115,13 @@ int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_MR];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_mr_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
 
+		ret = res_mr_line(rd, name, idx, nla_line);
 		if (ret != MNL_CB_OK)
 			break;
 	}
diff --git a/rdma/res-pd.c b/rdma/res-pd.c
index e8c042dc..956d4d9f 100644
--- a/rdma/res-pd.c
+++ b/rdma/res-pd.c
@@ -8,20 +8,14 @@
 #include <inttypes.h>
 
 static int res_pd_line(struct rd *rd, const char *name, int idx,
-		       struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
 	uint32_t local_dma_lkey = 0, unsafe_global_rkey = 0;
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	char *comm = NULL;
 	uint32_t ctxn = 0;
 	uint32_t pid = 0;
 	uint32_t pdn = 0;
 	uint64_t users;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_USECNT] ||
 	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
@@ -88,6 +82,23 @@ out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
 	return MNL_CB_OK;
 }
 
+int res_pd_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	uint32_t idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_pd_line(rd, name, idx, tb);
+}
+
 int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -107,8 +118,13 @@ int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_PD];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_pd_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
 
+		ret = res_pd_line(rd, name, idx, nla_line);
 		if (ret != MNL_CB_OK)
 			break;
 	}
diff --git a/rdma/res-qp.c b/rdma/res-qp.c
index 5d5ef27b..ac9976fc 100644
--- a/rdma/res-qp.c
+++ b/rdma/res-qp.c
@@ -79,19 +79,13 @@ static void print_pathmig(struct rd *rd, uint32_t val, struct nlattr **nla_line)
 }
 
 static int res_qp_line(struct rd *rd, const char *name, int idx,
-		       struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn;
 	uint8_t type, state, path_mig_state = 0;
 	uint32_t port = 0, pid = 0;
 	uint32_t pdn = 0;
 	char *comm = NULL;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_LQPN] ||
 	    !nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN] ||
@@ -199,6 +193,23 @@ out:
 	return MNL_CB_OK;
 }
 
+int res_qp_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	uint32_t idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_qp_line(rd, name, idx, tb);
+}
+
 int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -218,8 +229,13 @@ int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_QP];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_qp_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
 
+		ret = res_qp_line(rd, name, idx, nla_line);
 		if (ret != MNL_CB_OK)
 			break;
 	}
diff --git a/rdma/res.c b/rdma/res.c
index 564af9b4..ef863f14 100644
--- a/rdma/res.c
+++ b/rdma/res.c
@@ -54,6 +54,11 @@ static int res_print_summary(struct rd *rd, struct nlattr **tb)
 	return 0;
 }
 
+static int res_no_args_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	return MNL_CB_OK;
+}
+
 static int res_no_args_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -83,6 +88,33 @@ static int res_no_args_parse_cb(const struct nlmsghdr *nlh, void *data)
 	return MNL_CB_OK;
 }
 
+int _res_send_idx_msg(struct rd *rd, uint32_t command, mnl_cb_t callback,
+		      uint32_t idx, uint32_t id)
+{
+	uint32_t flags = NLM_F_REQUEST | NLM_F_ACK;
+	uint32_t seq;
+	int ret;
+
+	rd_prepare_msg(rd, command, &seq, flags);
+	mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
+	if (rd->port_idx)
+		mnl_attr_put_u32(rd->nlh,
+				 RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx);
+
+	mnl_attr_put_u32(rd->nlh, id, idx);
+
+	ret = rd_send_msg(rd);
+	if (ret)
+		return ret;
+
+	if (rd->json_output)
+		jsonw_start_object(rd->jw);
+	ret = rd_recv_msg(rd, callback, rd, seq);
+	if (rd->json_output)
+		jsonw_end_object(rd->jw);
+	return ret;
+}
+
 int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback)
 {
 	uint32_t flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -214,7 +246,7 @@ void res_print_uint(struct rd *rd, const char *name, uint64_t val,
 		pr_out("%s %" PRIu64 " ", name, val);
 }
 
-RES_FUNC(res_no_args,	RDMA_NLDEV_CMD_RES_GET,	NULL, true);
+RES_FUNC(res_no_args,	RDMA_NLDEV_CMD_RES_GET,	NULL, true, 0);
 
 static int res_show(struct rd *rd)
 {
diff --git a/rdma/res.h b/rdma/res.h
index 575e1192..b4a7e552 100644
--- a/rdma/res.h
+++ b/rdma/res.h
@@ -9,31 +9,52 @@
 #include "rdma.h"
 
 int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback);
+int _res_send_idx_msg(struct rd *rd, uint32_t command, mnl_cb_t callback,
+		      uint32_t idx, uint32_t id);
+
 int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_pd_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_mr_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_cq_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_cm_id_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_qp_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 
-#define RES_FUNC(name, command, valid_filters, strict_port) \
-	static inline int _##name(struct rd *rd)\
-	{ \
-		return _res_send_msg(rd, command, name##_parse_cb); \
-	} \
-	static inline int name(struct rd *rd) \
-	{\
-		int ret = rd_build_filter(rd, valid_filters); \
-		if (ret) \
-			return ret; \
-		if ((uintptr_t)valid_filters != (uintptr_t)NULL) { \
-			ret = rd_set_arg_to_devname(rd); \
-			if (ret) \
-				return ret;\
-		} \
-		if (strict_port) \
-			return rd_exec_dev(rd, _##name); \
-		else \
-			return rd_exec_link(rd, _##name, strict_port); \
+#define RES_FUNC(name, command, valid_filters, strict_port, id)                        \
+	static inline int _##name(struct rd *rd)                                       \
+	{                                                                              \
+		uint32_t idx;                                                          \
+		int ret;                                                               \
+		if (id) {                                                              \
+			ret = rd_doit_index(rd, &idx);                                 \
+			if (ret) {                                                     \
+				ret = _res_send_idx_msg(rd, command,                   \
+							name##_idx_parse_cb,           \
+							idx, id);                      \
+				if (!ret)                                              \
+					return ret;                                    \
+				/* Fallback for old systems without .doit callbacks */ \
+			}                                                              \
+		}                                                                      \
+		return _res_send_msg(rd, command, name##_parse_cb);                    \
+	}                                                                              \
+	static inline int name(struct rd *rd)                                          \
+	{                                                                              \
+		int ret = rd_build_filter(rd, valid_filters);                          \
+		if (ret)                                                               \
+			return ret;                                                    \
+		if ((uintptr_t)valid_filters != (uintptr_t)NULL) {                     \
+			ret = rd_set_arg_to_devname(rd);                               \
+			if (ret)                                                       \
+				return ret;                                            \
+		}                                                                      \
+		if (strict_port)                                                       \
+			return rd_exec_dev(rd, _##name);                               \
+		else                                                                   \
+			return rd_exec_link(rd, _##name, strict_port);                 \
 	}
 
 static const
@@ -42,11 +63,12 @@ struct filters pd_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "users", .is_number = true },
 	{ .name = "pid", .is_number = true },
 	{ .name = "ctxn", .is_number = true },
-	{ .name = "pdn", .is_number = true },
+	{ .name = "pdn", .is_number = true, .is_doit = true },
 	{ .name = "ctxn", .is_number = true }
 };
 
-RES_FUNC(res_pd, RDMA_NLDEV_CMD_RES_PD_GET, pd_valid_filters, true);
+RES_FUNC(res_pd, RDMA_NLDEV_CMD_RES_PD_GET, pd_valid_filters, true,
+	 RDMA_NLDEV_ATTR_RES_PDN);
 
 static const
 struct filters mr_valid_filters[MAX_NUMBER_OF_FILTERS] = {
@@ -55,11 +77,12 @@ struct filters mr_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "lkey", .is_number = true },
 	{ .name = "mrlen", .is_number = true },
 	{ .name = "pid", .is_number = true },
-	{ .name = "mrn", .is_number = true },
+	{ .name = "mrn", .is_number = true, .is_doit = true },
 	{ .name = "pdn", .is_number = true }
 };
 
-RES_FUNC(res_mr, RDMA_NLDEV_CMD_RES_MR_GET, mr_valid_filters, true);
+RES_FUNC(res_mr, RDMA_NLDEV_CMD_RES_MR_GET, mr_valid_filters, true,
+	 RDMA_NLDEV_ATTR_RES_MRN);
 
 static const
 struct filters cq_valid_filters[MAX_NUMBER_OF_FILTERS] = {
@@ -67,11 +90,12 @@ struct filters cq_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "users", .is_number = true },
 	{ .name = "poll-ctx", .is_number = false },
 	{ .name = "pid", .is_number = true },
-	{ .name = "cqn", .is_number = true },
+	{ .name = "cqn", .is_number = true, .is_doit = true },
 	{ .name = "ctxn", .is_number = true }
 };
 
-RES_FUNC(res_cq, RDMA_NLDEV_CMD_RES_CQ_GET, cq_valid_filters, true);
+RES_FUNC(res_cq, RDMA_NLDEV_CMD_RES_CQ_GET, cq_valid_filters, true,
+	 RDMA_NLDEV_ATTR_RES_CQN);
 
 static const
 struct filters cm_id_valid_filters[MAX_NUMBER_OF_FILTERS] = {
@@ -87,15 +111,16 @@ struct filters cm_id_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "src-port", .is_number = true },
 	{ .name = "dst-addr", .is_number = false },
 	{ .name = "dst-port", .is_number = true },
-	{ .name = "cm-idn", .is_number = true }
+	{ .name = "cm-idn", .is_number = true, .is_doit = true }
 };
 
-RES_FUNC(res_cm_id, RDMA_NLDEV_CMD_RES_CM_ID_GET, cm_id_valid_filters, false);
+RES_FUNC(res_cm_id, RDMA_NLDEV_CMD_RES_CM_ID_GET, cm_id_valid_filters, false,
+	 RDMA_NLDEV_ATTR_RES_CM_IDN);
 
 static const struct
 filters qp_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "link", .is_number = false },
-	{ .name = "lqpn", .is_number = true },
+	{ .name = "lqpn", .is_number = true, .is_doit = true },
 	{ .name = "rqpn", .is_number = true },
 	{ .name = "pid",  .is_number = true },
 	{ .name = "sq-psn", .is_number = true },
@@ -106,7 +131,8 @@ filters qp_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "pdn", .is_number = true },
 };
 
-RES_FUNC(res_qp,	RDMA_NLDEV_CMD_RES_QP_GET, qp_valid_filters, false);
+RES_FUNC(res_qp, RDMA_NLDEV_CMD_RES_QP_GET, qp_valid_filters, false,
+	 RDMA_NLDEV_ATTR_RES_LQPN);
 
 char *get_task_name(uint32_t pid);
 void print_dev(struct rd *rd, uint32_t idx, const char *name);
diff --git a/rdma/utils.c b/rdma/utils.c
index bce052d5..cff5297d 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -121,6 +121,7 @@ static int add_filter(struct rd *rd, char *key, char *value,
 	struct filter_entry *fe;
 	bool key_found = false;
 	int idx = 0;
+	char *endp;
 	int ret;
 
 	fe = calloc(1, sizeof(*fe));
@@ -163,6 +164,11 @@ static int add_filter(struct rd *rd, char *key, char *value,
 		goto err_alloc;
 	}
 
+	errno = 0;
+	strtol(fe->value, &endp, 10);
+	if (valid_filters[idx].is_doit && !errno && *endp == '\0')
+		fe->is_doit = true;
+
 	for (idx = 0; idx < strlen(fe->value); idx++)
 		fe->value[idx] = tolower(fe->value[idx]);
 
@@ -177,6 +183,20 @@ err:
 	return ret;
 }
 
+bool rd_doit_index(struct rd *rd, uint32_t *idx)
+{
+	struct filter_entry *fe;
+
+	list_for_each_entry(fe, &rd->filter_list, list) {
+		if (fe->is_doit) {
+			*idx = atoi(fe->value);
+			return true;
+		}
+	}
+
+	return false;
+}
+
 int rd_build_filter(struct rd *rd, const struct filters valid_filters[])
 {
 	int ret = 0;
-- 
2.19.1

  parent reply	other threads:[~2019-02-23  9:15 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-23  9:15 [PATCH iproute2-next v2 00/19] Export object IDs to users Leon Romanovsky
2019-02-23  9:15 ` Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 01/19] rdma: update uapi headers Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 02/19] rdma: Remove duplicated print code Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 03/19] rdma: Provide unique indexes for all visible objects Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 04/19] rdma: Provide parent context index for all objects except CM_ID Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 05/19] rdma: Move resource PD logic to separate file Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 06/19] rdma: Refactor out resource MR " Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 07/19] rdma: Move out resource CQ " Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 08/19] rdma: Move out resource CM-ID " Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 09/19] rdma: Move resource QP " Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 10/19] rdma: Properly mark RDMAtool license Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 11/19] rdma: Simplify code to reuse existing functions Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 12/19] rdma: Simplify CM_ID print code Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 13/19] rdma: Refactor CQ prints Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 14/19] rdma: Move MR code to be suitable for per-line parsing Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 15/19] rdma: Place PD parsing print routine into separate function Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 16/19] rdma: Move QP code to " Leon Romanovsky
2019-02-23  9:15 ` [PATCH iproute2-next v2 17/19] rdma: Unify netlink attribute checks prior to prints Leon Romanovsky
2019-02-23  9:15 ` Leon Romanovsky [this message]
2019-02-23  9:15 ` [PATCH iproute2-next v2 19/19] rdma: Provide and reuse filter functions Leon Romanovsky
2019-02-24 15:16 ` [PATCH iproute2-next v2 00/19] Export object IDs to users David Ahern
2019-02-24 17:23   ` Leon Romanovsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190223091528.8509-19-leon@kernel.org \
    --to=leon@kernel.org \
    --cc=dsahern@gmail.com \
    --cc=leonro@mellanox.com \
    --cc=linux-rdma@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=stephen@networkplumber.org \
    --cc=swise@opengridcomputing.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.