All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2 V1 0/5] RDMAtool
@ 2017-06-27 14:39 Leon Romanovsky
  2017-06-27 14:39 ` [PATCH iproute2 V1 1/6] rdma: Add basic infrastructure for RDMA tool Leon Romanovsky
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Leon Romanovsky @ 2017-06-27 14:39 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Leon Romanovsky, Doug Ledford, Ariel Almog, Dennis Dalessandro,
	Jason Gunthorpe, Linux RDMA, Linux Netdev

From: Leon Romanovsky <leonro@mellanox.com>

Hi,

This is second version of series implementing the RDAMtool -  the tool
to configure RDMA devices. The initial proposal was sent as RFC [1] and
was based on sysfs entries as POC.

The current series was rewritten completely to work with RDMA netlinks as
a source of user<->kernel communications. In order to achieve that, the
RDMA netlinks were extensively refactored and modernized [2, 3, 4 and 5].

Changelog
v0->v1:
 * Moved hunk with changes in man/Makefile from first patch to the last patch
 * Removed the "unknown command" from the examples in commit messages
 * Removed special "caps" parsing command and put it to be part of general "show" command
 * Changed parsed capability format to be similar to iproute2 suite
 * Added FW version as an output of show command.
 * Added forgotten CAP_FLAGS to the nla_policy list
RFC->v0:
 * Removed everything that is not implemented yet.
 * Abandoned sysfs interfaces in favor of netlink.

Available in the "topic/rdmatool-netlink-v1" topic branch of this git repo:
git://git.kernel.org/pub/scm/linux/kernel/git/leon/iproute2.git

Or for browsing:
https://git.kernel.org/cgit/linux/kernel/git/leon/iproute2.git/log/?h=topic/rdmatool-netlink-v1

Thanks

[1] https://www.spinics.net/lists/linux-rdma/msg49575.html
[2] https://patchwork.kernel.org/patch/9752865/
[3] https://www.spinics.net/lists/linux-rdma/msg50827.html
[4] https://www.spinics.net/lists/linux-rdma/msg51210.html
[5] https://patchwork.kernel.org/patch/9811729/ and https://patchwork.kernel.org/patch/9811731/]

Cc: Doug Ledford <dledford@redhat.com>
Cc: Ariel Almog <ariela@mellanox.com>
Cc: Dennis Dalessandro <dennis.dalessandro@intel.com>
Cc: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Cc: Linux RDMA <linux-rdma@vger.kernel.org>
Cc: Linux Netdev <netdev@vger.kernel.org>

Leon Romanovsky (6):
  rdma: Add basic infrastructure for RDMA tool
  rdma: Add dev object
  rdma: Add device capability parsing
  rdma: Add link option and parsing
  rdma: Add FW version to the device output
  rdma: Add initial manual for the tool

 Makefile          |   2 +-
 man/man8/Makefile |   3 +-
 man/man8/rdma.8   |  82 ++++++++++++++
 rdma/.gitignore   |   1 +
 rdma/Makefile     |  22 ++++
 rdma/dev.c        | 145 +++++++++++++++++++++++++
 rdma/link.c       | 202 +++++++++++++++++++++++++++++++++++
 rdma/rdma.c       | 112 ++++++++++++++++++++
 rdma/rdma.h       |  90 ++++++++++++++++
 rdma/utils.c      | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 10 files changed, 969 insertions(+), 2 deletions(-)
 create mode 100644 man/man8/rdma.8
 create mode 100644 rdma/.gitignore
 create mode 100644 rdma/Makefile
 create mode 100644 rdma/dev.c
 create mode 100644 rdma/link.c
 create mode 100644 rdma/rdma.c
 create mode 100644 rdma/rdma.h
 create mode 100644 rdma/utils.c

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH iproute2 V1 1/6] rdma: Add basic infrastructure for RDMA tool
  2017-06-27 14:39 [PATCH iproute2 V1 0/5] RDMAtool Leon Romanovsky
@ 2017-06-27 14:39 ` Leon Romanovsky
  2017-06-27 14:39 ` [PATCH iproute2 V1 2/6] rdma: Add dev object Leon Romanovsky
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Leon Romanovsky @ 2017-06-27 14:39 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Leon Romanovsky, Doug Ledford, Ariel Almog, Dennis Dalessandro,
	Jason Gunthorpe, Linux RDMA, Linux Netdev

From: Leon Romanovsky <leonro@mellanox.com>

RDMA devices are cross-functional devices from one side,
but very tailored for the specific markets from another.

Such diversity caused to spread of RDMA related configuration
across various tools, e.g. devlink, ip, ethtool, ib specific and
vendor specific solutions.

This patch adds ability to fill device and port information
by reading RDMA netlink.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 Makefile        |   2 +-
 rdma/.gitignore |   1 +
 rdma/Makefile   |  22 +++++
 rdma/rdma.c     | 110 +++++++++++++++++++++++
 rdma/rdma.h     |  76 ++++++++++++++++
 rdma/utils.c    | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 480 insertions(+), 1 deletion(-)
 create mode 100644 rdma/.gitignore
 create mode 100644 rdma/Makefile
 create mode 100644 rdma/rdma.c
 create mode 100644 rdma/rdma.h
 create mode 100644 rdma/utils.c

diff --git a/Makefile b/Makefile
index 18de7dcb..c255063b 100644
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@ WFLAGS += -Wmissing-declarations -Wold-style-definition -Wformat=2
 CFLAGS := $(WFLAGS) $(CCOPTS) -I../include $(DEFINES) $(CFLAGS)
 YACCFLAGS = -d -t -v
 
-SUBDIRS=lib ip tc bridge misc netem genl tipc devlink man
+SUBDIRS=lib ip tc bridge misc netem genl tipc devlink rdma man
 
 LIBNETLINK=../lib/libnetlink.a ../lib/libutil.a
 LDLIBS += $(LIBNETLINK)
diff --git a/rdma/.gitignore b/rdma/.gitignore
new file mode 100644
index 00000000..51fb172b
--- /dev/null
+++ b/rdma/.gitignore
@@ -0,0 +1 @@
+rdma
diff --git a/rdma/Makefile b/rdma/Makefile
new file mode 100644
index 00000000..64da2142
--- /dev/null
+++ b/rdma/Makefile
@@ -0,0 +1,22 @@
+include ../Config
+
+ifeq ($(HAVE_MNL),y)
+
+RDMA_OBJ = rdma.o utils.o
+
+TARGETS=rdma
+CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
+LDLIBS += $(shell $(PKG_CONFIG) libmnl --libs)
+
+endif
+
+all:	$(TARGETS) $(LIBS)
+
+rdma:	$(RDMA_OBJ) $(LIBS)
+	$(QUIET_LINK)$(CC) $^ $(LDFLAGS) $(LDLIBS) -o $@
+
+install: all
+	install -m 0755 $(TARGETS) $(DESTDIR)$(SBINDIR)
+
+clean:
+	rm -f $(RDMA_OBJ) $(TARGETS)
diff --git a/rdma/rdma.c b/rdma/rdma.c
new file mode 100644
index 00000000..9c754da3
--- /dev/null
+++ b/rdma/rdma.c
@@ -0,0 +1,110 @@
+/*
+ * rdma.c	RDMA tool
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Authors:     Leon Romanovsky <leonro@mellanox.com>
+ */
+
+#include <limits.h>
+#include <rdma/rdma_netlink.h>
+
+#include "rdma.h"
+#include "SNAPSHOT.h"
+
+static void help(char *name)
+{
+	pr_out("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n"
+	       "where  OBJECT := { help }\n"
+	       "       OPTIONS := { -V[ersion] }\n", name);
+}
+
+static int cmd_help(struct rdma *rd)
+{
+	help(rd->filename);
+	return 0;
+}
+
+static int rd_cmd(struct rdma *rd)
+{
+	const struct rdma_cmd cmds[] = {
+		{ NULL,		cmd_help },
+		{ "help",	cmd_help },
+		{ 0 }
+	};
+
+	return rdma_exec_cmd(rd, cmds, "object");
+}
+
+static int rd_init(struct rdma *rd, int argc, char **argv, char *filename)
+{
+	uint32_t seq;
+	int ret;
+
+	rd->filename = filename;
+	rd->argc = argc;
+	rd->argv = argv;
+	INIT_LIST_HEAD(&rd->dev_map_list);
+	rd->buff = malloc(MNL_SOCKET_BUFFER_SIZE);
+	if (!rd->buff)
+		return -ENOMEM;
+
+	rdma_prepare_msg(rd, RDMA_NLDEV_CMD_GET, &seq, (NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP));
+	if ((ret = rdma_send_msg(rd)))
+		return ret;
+
+	return rdma_recv_msg(rd, rd_dev_init_cb, rd, seq);
+}
+
+static void rd_free(struct rdma *rd)
+{
+	free(rd->buff);
+	rdma_free_devmap(rd);
+}
+int main(int argc, char **argv)
+{
+	char *filename;
+	static const struct option long_options[] = {
+		{ "version",		no_argument,		NULL, 'V' },
+		{ "help",		no_argument,		NULL, 'h' },
+		{ NULL, 0, NULL, 0 }
+	};
+	struct rdma rd;
+	int opt;
+	int err;
+
+	filename = basename(argv[0]);
+
+	while ((opt = getopt_long(argc, argv, "Vh",
+				  long_options, NULL)) >= 0) {
+
+		switch (opt) {
+		case 'V':
+			printf("%s utility, iproute2-ss%s\n", filename, SNAPSHOT);
+			return EXIT_SUCCESS;
+		case 'h':
+			help(filename);
+			return EXIT_SUCCESS;
+		default:
+			pr_err("Unknown option.\n");
+			help(filename);
+			return EXIT_FAILURE;
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	err = rd_init(&rd, argc, argv, filename);
+	if (err)
+		goto out;
+
+	err = rd_cmd(&rd);
+out:
+	/* Always cleanup */
+	rd_free(&rd);
+	return (err) ? EXIT_FAILURE:EXIT_SUCCESS;
+}
diff --git a/rdma/rdma.h b/rdma/rdma.h
new file mode 100644
index 00000000..9841aebf
--- /dev/null
+++ b/rdma/rdma.h
@@ -0,0 +1,76 @@
+/*
+ * rdma.c	RDMA tool
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Authors:     Leon Romanovsky <leonro@mellanox.com>
+ */
+#ifndef _RDMA_TOOL_H_
+#define _RDMA_TOOL_H_
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <libmnl/libmnl.h>
+
+#include <rdma/rdma_netlink.h>
+#include "list.h"
+
+#define pr_err(args...) fprintf(stderr, ##args)
+#define pr_out(args...) fprintf(stdout, ##args)
+
+struct port_map {
+	struct list_head list;
+	uint32_t idx;
+};
+
+struct dev_map {
+	struct list_head list;
+	char *dev_name;
+	uint32_t num_ports;
+	struct list_head port_map_list;
+	uint32_t idx;
+};
+
+struct rdma {
+	int argc;
+	char **argv;
+	char *filename;
+	struct list_head dev_map_list;
+	struct mnl_socket *nl;
+	struct nlmsghdr *nlh;
+	char *buff;
+};
+
+struct rdma_cmd {
+	const char *cmd;
+	int (*func)(struct rdma *rd);
+};
+
+/*
+ * Parser interface
+ */
+bool rd_no_arg(struct rdma *rd);
+bool rd_argv_match(struct rdma *rd, const char *pattern);
+void rd_arg_inc(struct rdma *rd);
+
+int rdma_exec_cmd(struct rdma *rd, const struct rdma_cmd *c, const char *str);
+
+/*
+ * Device manipulation
+ */
+void rdma_free_devmap(struct rdma *rd);
+
+/*
+ * Netlink
+ */
+int rdma_send_msg(struct rdma *rd);
+int rdma_recv_msg(struct rdma *rd, mnl_cb_t callback, void *data, uint32_t seq);
+int rdma_prepare_msg(struct rdma *rd, uint32_t cmd, uint32_t *seq, uint16_t flags);
+int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data);
+int rd_attr_cb(const struct nlattr *attr, void *data);
+#endif /* _RDMA_TOOL_H_ */
diff --git a/rdma/utils.c b/rdma/utils.c
new file mode 100644
index 00000000..96278a4c
--- /dev/null
+++ b/rdma/utils.c
@@ -0,0 +1,270 @@
+/*
+ * utils.c	RDMA tool
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Authors:     Leon Romanovsky <leonro@mellanox.com>
+ */
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <time.h>
+
+#include "rdma.h"
+#include <rdma/rdma_netlink.h>
+
+/*
+ * This macro will be moved to generic layer,
+ * after code will be accepted.
+ * it is placed here to avoid rebases with upstream code.
+ */
+#define MAX(a, b)	((a) > (b) ? (a) : (b))
+
+static int rd_argc(struct rdma *rd)
+{
+	return rd->argc;
+}
+
+static char *rd_argv(struct rdma *rd)
+{
+	if (!rd_argc(rd))
+		return NULL;
+	return *rd->argv;
+}
+
+static int strcmpx(const char *str1, const char *str2)
+{
+	if (strlen(str1) > strlen(str2))
+			return -1;
+	return strncmp(str1, str2, strlen(str1));
+}
+
+bool rd_argv_match(struct rdma *rd, const char *pattern)
+{
+	if (!rd_argc(rd))
+		return false;
+	return strcmpx(rd_argv(rd), pattern) == 0;
+}
+
+void rd_arg_inc(struct rdma *rd)
+{
+	if (!rd_argc(rd))
+		return;
+	rd->argc--;
+	rd->argv++;
+}
+
+bool rd_no_arg(struct rdma *rd)
+{
+	return rd_argc(rd) == 0;
+}
+
+static struct dev_map *dev_map_alloc(const char *dev_name)
+{
+	struct dev_map *dev_map;
+
+	dev_map = calloc(1, sizeof(*dev_map));
+	if (!dev_map)
+		return NULL;
+	dev_map->dev_name = strdup(dev_name);
+	INIT_LIST_HEAD(&dev_map->port_map_list);
+
+	return dev_map;
+}
+
+static void port_map_free(struct port_map *port_map)
+{
+	if(!port_map)
+		return;
+	free(port_map);
+}
+
+static void dev_map_free(struct dev_map *dev_map)
+{
+	struct port_map *port_map, *tmp;
+
+	if(!dev_map)
+		return;
+
+	list_for_each_entry_safe(port_map, tmp,
+				 &dev_map->port_map_list, list) {
+		list_del(&port_map->list);
+		port_map_free(port_map);
+	}
+
+	free(dev_map->dev_name);
+	free(dev_map);
+}
+
+static void dev_map_cleanup(struct rdma *rd)
+{
+	struct dev_map *dev_map, *tmp;
+
+	list_for_each_entry_safe(dev_map, tmp,
+				 &rd->dev_map_list, list) {
+		list_del(&dev_map->list);
+		dev_map_free(dev_map);
+	}
+}
+
+static int port_map_alloc(struct dev_map *dev_map, uint32_t num_ports)
+{
+	struct port_map *port_map;
+	int idx = 1;
+
+	while (idx <= num_ports) {
+		port_map = calloc(1, sizeof(*port_map));
+		if (!port_map)
+			return -ENOMEM;
+
+		list_add_tail(&port_map->list, &dev_map->port_map_list);
+		port_map->idx = idx++;
+	}
+
+	return 0;
+}
+
+static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
+	[RDMA_NLDEV_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING,
+	[RDMA_NLDEV_ATTR_PORT_INDEX] = MNL_TYPE_U32,
+};
+
+int rd_attr_cb(const struct nlattr *attr, void *data)
+{
+	const struct nlattr **tb = data;
+	int type;
+
+	if (mnl_attr_type_valid(attr, RDMA_NLDEV_ATTR_MAX) < 0)
+		return MNL_CB_ERROR;
+
+	type = mnl_attr_get_type(attr);
+
+	if (mnl_attr_validate(attr, nldev_policy[type]) < 0)
+		return MNL_CB_ERROR;
+
+	tb[type] = attr;
+	return MNL_CB_OK;
+}
+
+int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct dev_map *dev_map;
+	struct rdma *rd = data;
+	const char *dev_name;
+	uint32_t num_ports;
+	static int i = 1;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+	if (!tb[RDMA_NLDEV_ATTR_PORT_INDEX]) {
+		pr_err("This tool doesn't support switches yet\n");
+		return MNL_CB_ERROR;
+	}
+
+	dev_name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	num_ports = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
+
+	dev_map = dev_map_alloc(dev_name);
+	if (!dev_map)
+		/* The main function will cleanup the allocations */
+		return MNL_CB_ERROR;
+	list_add_tail(&dev_map->list, &rd->dev_map_list);
+	dev_map->idx = i++;
+
+	if (port_map_alloc(dev_map, num_ports))
+		return MNL_CB_ERROR;
+	dev_map->num_ports = num_ports;
+
+	return MNL_CB_OK;
+}
+
+void rdma_free_devmap(struct rdma *rd)
+{
+	if(!rd)
+		return;
+	dev_map_cleanup(rd);
+	return;
+}
+
+int rdma_exec_cmd(struct rdma *rd, const struct rdma_cmd *cmds, const char *str)
+{
+	const struct rdma_cmd *c;
+
+	/* First argument in objs table is default variant */
+	if (rd_no_arg(rd))
+		return cmds->func(rd);
+
+	for (c = cmds + 1; c->cmd; ++c) {
+		if (rd_argv_match(rd, c->cmd)) {
+			/* Move to next argument */
+			rd_arg_inc(rd);
+			return c->func(rd);
+		}
+	}
+
+	pr_err("Unknown %s '%s'.\n", str, rd_argv(rd));
+	return 0;
+}
+
+int rdma_prepare_msg(struct rdma *rd, uint32_t cmd, uint32_t *seq, uint16_t flags)
+{
+	*seq = time(NULL);
+
+	rd->nlh = mnl_nlmsg_put_header(rd->buff);
+	rd->nlh->nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, cmd);
+	rd->nlh->nlmsg_seq = *seq;
+	rd->nlh->nlmsg_flags = flags;
+
+	return 0;
+}
+
+int rdma_send_msg(struct rdma *rd)
+{
+	int ret;
+
+	rd->nl = mnl_socket_open(NETLINK_RDMA);
+	if (!rd->nl) {
+		pr_err("Failed to open NETLINK_RDMA socket\n");
+		return -ENODEV;
+	}
+
+	ret = mnl_socket_bind(rd->nl, 0, MNL_SOCKET_AUTOPID);
+	if (ret < 0) {
+		pr_err("Failed to bind socket with err %d\n", ret);
+		goto err;
+	}
+
+	ret = mnl_socket_sendto(rd->nl, rd->nlh, rd->nlh->nlmsg_len);
+	if (ret < 0) {
+		pr_err("Failed to send to socket with err %d\n", ret);
+		goto err;
+	}
+	return 0;
+
+err:	mnl_socket_close(rd->nl);
+	return ret;
+}
+
+int rdma_recv_msg(struct rdma *rd, mnl_cb_t callback, void *data, unsigned int seq)
+{
+	int ret;
+	unsigned int portid;
+	char buf[MNL_SOCKET_BUFFER_SIZE];
+
+	portid = mnl_socket_get_portid(rd->nl);
+	do {
+		ret = mnl_socket_recvfrom(rd->nl, buf, sizeof(buf));
+		if (ret <= 0)
+			break;
+
+		ret = mnl_cb_run(buf, ret, seq, portid, callback, data);
+	} while (ret > 0);
+
+	mnl_socket_close(rd->nl);
+	return ret;
+}
-- 
2.13.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH iproute2 V1 2/6] rdma: Add dev object
  2017-06-27 14:39 [PATCH iproute2 V1 0/5] RDMAtool Leon Romanovsky
  2017-06-27 14:39 ` [PATCH iproute2 V1 1/6] rdma: Add basic infrastructure for RDMA tool Leon Romanovsky
@ 2017-06-27 14:39 ` Leon Romanovsky
  2017-06-27 14:39 ` [PATCH iproute2 V1 4/6] rdma: Add link option and parsing Leon Romanovsky
       [not found] ` <20170627143920.28020-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  3 siblings, 0 replies; 9+ messages in thread
From: Leon Romanovsky @ 2017-06-27 14:39 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Leon Romanovsky, Doug Ledford, Ariel Almog, Dennis Dalessandro,
	Jason Gunthorpe, Linux RDMA, Linux Netdev

From: Leon Romanovsky <leonro@mellanox.com>

Device (dev) object represents struct ib_device to user space.

The supported commands are show, set and help, but it doesn't print
anything except device name at this stage. The downstream patches will
fill this object with subcommands.

Print all devices:
 # rdma dev
1: mlx5_0:
2: mlx5_1:
3: mlx5_2:

Print specific device:
 # rdma dev show mlx5_1
2: mlx5_1:

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/Makefile |  2 +-
 rdma/dev.c    | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 rdma/rdma.c   |  3 ++-
 rdma/rdma.h   |  6 ++++++
 rdma/utils.c  | 39 ++++++++++++++++++++++++++++++++++-----
 5 files changed, 98 insertions(+), 7 deletions(-)
 create mode 100644 rdma/dev.c

diff --git a/rdma/Makefile b/rdma/Makefile
index 64da2142..123d7ac5 100644
--- a/rdma/Makefile
+++ b/rdma/Makefile
@@ -2,7 +2,7 @@ include ../Config
 
 ifeq ($(HAVE_MNL),y)
 
-RDMA_OBJ = rdma.o utils.o
+RDMA_OBJ = rdma.o utils.o dev.o
 
 TARGETS=rdma
 CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
diff --git a/rdma/dev.c b/rdma/dev.c
new file mode 100644
index 00000000..d4809d63
--- /dev/null
+++ b/rdma/dev.c
@@ -0,0 +1,55 @@
+/*
+ * dev.c	RDMA tool
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Authors:     Leon Romanovsky <leonro@mellanox.com>
+ */
+
+#include "rdma.h"
+
+static int dev_help(struct rdma *rd)
+{
+	pr_out("Usage: %s dev show [DEV]\n", rd->filename);
+	return 0;
+}
+
+static void dev_one_show(const struct dev_map *dev_map)
+{
+	pr_out("%u: %s:\n", dev_map->idx, dev_map->dev_name);
+}
+
+static int dev_show(struct rdma *rd)
+{
+	struct dev_map *dev_map;
+
+	if (rd_no_arg(rd)) {
+		list_for_each_entry(dev_map, &rd->dev_map_list, list)
+			dev_one_show(dev_map);
+	}
+	else {
+		dev_map = dev_map_lookup(rd, false);
+		if (!dev_map) {
+			pr_err("Wrong device name\n");
+			return -ENOENT;
+		}
+		dev_one_show(dev_map);
+	}
+	return 0;
+}
+
+int cmd_dev(struct rdma *rd)
+{
+	const struct rdma_cmd cmds[] = {
+		{ NULL,		dev_show },
+		{ "show",	dev_show },
+		{ "list",	dev_show },
+		{ "help",	dev_help },
+		{ 0 }
+	};
+
+	return rdma_exec_cmd(rd, cmds, "dev command");
+}
diff --git a/rdma/rdma.c b/rdma/rdma.c
index 9c754da3..f904532c 100644
--- a/rdma/rdma.c
+++ b/rdma/rdma.c
@@ -18,7 +18,7 @@
 static void help(char *name)
 {
 	pr_out("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n"
-	       "where  OBJECT := { help }\n"
+	       "where  OBJECT := { dev | help }\n"
 	       "       OPTIONS := { -V[ersion] }\n", name);
 }
 
@@ -33,6 +33,7 @@ static int rd_cmd(struct rdma *rd)
 	const struct rdma_cmd cmds[] = {
 		{ NULL,		cmd_help },
 		{ "help",	cmd_help },
+		{ "dev",	cmd_dev },
 		{ 0 }
 	};
 
diff --git a/rdma/rdma.h b/rdma/rdma.h
index 9841aebf..f5e104ec 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -58,12 +58,18 @@ bool rd_no_arg(struct rdma *rd);
 bool rd_argv_match(struct rdma *rd, const char *pattern);
 void rd_arg_inc(struct rdma *rd);
 
+/*
+ * Commands interface
+ */
+int cmd_dev(struct rdma *rd);
 int rdma_exec_cmd(struct rdma *rd, const struct rdma_cmd *c, const char *str);
 
 /*
  * Device manipulation
  */
 void rdma_free_devmap(struct rdma *rd);
+struct dev_map *dev_map_lookup(struct rdma *rd, bool allow_port_index);
+struct dev_map *_dev_map_lookup(struct rdma *rd, const char *dev_name);
 
 /*
  * Netlink
diff --git a/rdma/utils.c b/rdma/utils.c
index 96278a4c..4d29eced 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -128,8 +128,10 @@ static int port_map_alloc(struct dev_map *dev_map, uint32_t num_ports)
 }
 
 static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
+	[RDMA_NLDEV_ATTR_DEV_INDEX] = MNL_TYPE_U32,
 	[RDMA_NLDEV_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING,
 	[RDMA_NLDEV_ATTR_PORT_INDEX] = MNL_TYPE_U32,
+	[RDMA_NLDEV_ATTR_CAP_FLAGS] = MNL_TYPE_U64,
 };
 
 int rd_attr_cb(const struct nlattr *attr, void *data)
@@ -156,10 +158,9 @@ int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data)
 	struct rdma *rd = data;
 	const char *dev_name;
 	uint32_t num_ports;
-	static int i = 1;
 
 	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
-	if (!tb[RDMA_NLDEV_ATTR_DEV_NAME])
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
 		return MNL_CB_ERROR;
 	if (!tb[RDMA_NLDEV_ATTR_PORT_INDEX]) {
 		pr_err("This tool doesn't support switches yet\n");
@@ -167,18 +168,18 @@ int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data)
 	}
 
 	dev_name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
-	num_ports = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
-
 	dev_map = dev_map_alloc(dev_name);
 	if (!dev_map)
 		/* The main function will cleanup the allocations */
 		return MNL_CB_ERROR;
 	list_add_tail(&dev_map->list, &rd->dev_map_list);
-	dev_map->idx = i++;
 
+	num_ports = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
 	if (port_map_alloc(dev_map, num_ports))
 		return MNL_CB_ERROR;
 	dev_map->num_ports = num_ports;
+	dev_map->idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+	dev_map->caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
 
 	return MNL_CB_OK;
 }
@@ -268,3 +269,31 @@ int rdma_recv_msg(struct rdma *rd, mnl_cb_t callback, void *data, unsigned int s
 	mnl_socket_close(rd->nl);
 	return ret;
 }
+
+struct dev_map *_dev_map_lookup(struct rdma *rd, const char *dev_name)
+{
+	struct dev_map *dev_map;
+
+	list_for_each_entry(dev_map, &rd->dev_map_list, list)
+		if (strcmp(dev_name, dev_map->dev_name) == 0)
+			return dev_map;
+
+	return NULL;
+}
+struct dev_map *dev_map_lookup(struct rdma *rd, bool allow_port_index)
+{
+	struct dev_map *dev_map;
+	char *dev_name;
+	char *slash;
+
+	dev_name = strdup(rd_argv(rd));
+	if (allow_port_index) {
+		slash = strrchr(dev_name, '/');
+		if (slash)
+			*slash = '\0';
+	}
+
+	dev_map = _dev_map_lookup(rd, dev_name);
+	free(dev_name);
+	return dev_map;
+}
-- 
2.13.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH iproute2 V1 3/6] rdma: Add device capability parsing
       [not found] ` <20170627143920.28020-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
@ 2017-06-27 14:39   ` Leon Romanovsky
       [not found]     ` <20170627143920.28020-4-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  2017-06-27 14:39   ` [PATCH iproute2 V1 5/6] rdma: Add FW version to the device output Leon Romanovsky
  2017-06-27 14:39   ` [PATCH iproute2 V1 6/6] rdma: Add initial manual for the tool Leon Romanovsky
  2 siblings, 1 reply; 9+ messages in thread
From: Leon Romanovsky @ 2017-06-27 14:39 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Leon Romanovsky, Doug Ledford, Ariel Almog, Dennis Dalessandro,
	Jason Gunthorpe, Linux RDMA, Linux Netdev

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

Add parsing interface for the device capability flags

$ rdma dev show
1: mlx5_0:
    caps: <BAD_PKEY_CNTR, BAD_QKEY_CNTR, CHANGE_PHY_PORT, PORT_ACTIVE_EVENT, SYS_IMAGE_GUID, RC_RNR_NAK_GEN, MEM_WINDOW, UD_IP_CSUM, UD_TSO, XRC, MEM_MGT_EXTENSIONS, BLOCK_MULTICAST_LOOPBACK, MEM_WINDOW_TYPE_2B, RAW_IP_CSUM, SIGNATURE_HANDOVER, VIRTUAL_FUNCTION>
2: mlx5_1:
    caps: <BAD_PKEY_CNTR, BAD_QKEY_CNTR, CHANGE_PHY_PORT, PORT_ACTIVE_EVENT, SYS_IMAGE_GUID, RC_RNR_NAK_GEN, MEM_WINDOW, UD_IP_CSUM, UD_TSO, XRC, MEM_MGT_EXTENSIONS, BLOCK_MULTICAST_LOOPBACK, MEM_WINDOW_TYPE_2B, RAW_IP_CSUM, SIGNATURE_HANDOVER, VIRTUAL_FUNCTION>
3: mlx5_2:
    caps: <BAD_PKEY_CNTR, BAD_QKEY_CNTR, CHANGE_PHY_PORT, PORT_ACTIVE_EVENT, SYS_IMAGE_GUID, RC_RNR_NAK_GEN, MEM_WINDOW, UD_IP_CSUM, UD_TSO, XRC, MEM_MGT_EXTENSIONS, BLOCK_MULTICAST_LOOPBACK, MEM_WINDOW_TYPE_2B, RAW_IP_CSUM, SIGNATURE_HANDOVER, VIRTUAL_FUNCTION>
4: mlx5_3:
    caps: <BAD_PKEY_CNTR, BAD_QKEY_CNTR, CHANGE_PHY_PORT, PORT_ACTIVE_EVENT, SYS_IMAGE_GUID, RC_RNR_NAK_GEN, MEM_WINDOW, UD_IP_CSUM, UD_TSO, XRC, MEM_MGT_EXTENSIONS, BLOCK_MULTICAST_LOOPBACK, MEM_WINDOW_TYPE_2B, RAW_IP_CSUM, SIGNATURE_HANDOVER, VIRTUAL_FUNCTION>
5: mlx5_4:
    caps: <BAD_PKEY_CNTR, BAD_QKEY_CNTR, CHANGE_PHY_PORT, PORT_ACTIVE_EVENT, SYS_IMAGE_GUID, RC_RNR_NAK_GEN, MEM_WINDOW, UD_IP_CSUM, UD_TSO, XRC, MEM_MGT_EXTENSIONS, BLOCK_MULTICAST_LOOPBACK, MEM_WINDOW_TYPE_2B, RAW_IP_CSUM, SIGNATURE_HANDOVER, VIRTUAL_FUNCTION>
root@mtr-leonro:~#

$ rdma dev show mlx5_4
5: mlx5_4:
    caps: <BAD_PKEY_CNTR, BAD_QKEY_CNTR, CHANGE_PHY_PORT, PORT_ACTIVE_EVENT, SYS_IMAGE_GUID, RC_RNR_NAK_GEN, MEM_WINDOW, UD_IP_CSUM, UD_TSO, XRC, MEM_MGT_EXTENSIONS, BLOCK_MULTICAST_LOOPBACK, MEM_WINDOW_TYPE_2B, RAW_IP_CSUM, SIGNATURE_HANDOVER, VIRTUAL_FUNCTION>

Signed-off-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 rdma/dev.c   | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 rdma/rdma.h  |  3 ++
 rdma/utils.c |  2 +-
 3 files changed, 95 insertions(+), 9 deletions(-)

diff --git a/rdma/dev.c b/rdma/dev.c
index d4809d63..76f4af88 100644
--- a/rdma/dev.c
+++ b/rdma/dev.c
@@ -17,28 +17,111 @@ static int dev_help(struct rdma *rd)
 	return 0;
 }
 
-static void dev_one_show(const struct dev_map *dev_map)
+static const char *dev_caps[64] = {
+	"RESIZE_MAX_WR",
+	"BAD_PKEY_CNTR",
+	"BAD_QKEY_CNTR",
+	"RAW_MULTI",
+	"AUTO_PATH_MIG",
+	"CHANGE_PHY_PORT",
+	"UD_AV_PORT_ENFORCE",
+	"CURR_QP_STATE_MOD",
+	"SHUTDOWN_PORT",
+	"INIT_TYPE",
+	"PORT_ACTIVE_EVENT",
+	"SYS_IMAGE_GUID",
+	"RC_RNR_NAK_GEN",
+	"SRQ_RESIZE",
+	"N_NOTIFY_CQ",
+	"LOCAL_DMA_LKEY",
+	"RESERVED",
+	"MEM_WINDOW",
+	"UD_IP_CSUM",
+	"UD_TSO",
+	"XRC",
+	"MEM_MGT_EXTENSIONS",
+	"BLOCK_MULTICAST_LOOPBACK",
+	"MEM_WINDOW_TYPE_2A",
+	"MEM_WINDOW_TYPE_2B",
+	"RC_IP_CSUM",
+	"RAW_IP_CSUM",
+	"CROSS_CHANNEL",
+	"MANAGED_FLOW_STEERING",
+	"SIGNATURE_HANDOVER",
+	"ON_DEMAND_PAGING",
+	"SG_GAPS_REG",
+	"VIRTUAL_FUNCTION",
+	"RAW_SCATTER_FCS",
+	"RDMA_NETDEV_OPA_VNIC",
+};
+
+static int dev_print_caps(struct rdma *rd)
 {
-	pr_out("%u: %s:\n", dev_map->idx, dev_map->dev_name);
+	struct dev_map *dev_map = rd->dev_map_curr;
+	uint64_t caps = dev_map->caps;
+	bool found = false;
+	uint32_t idx;
+
+	pr_out("    caps: <");
+	for (idx = 0; idx < 64; idx++) {
+		if (caps & 0x1) {
+			pr_out("%s", dev_caps[idx]?dev_caps[idx]:"UNKNONW");
+			if (caps >> 0x1)
+				pr_out(", ");
+			found = true;
+		}
+		caps >>= 0x1;
+	}
+	if(!found)
+		pr_out("NONE");
+
+	pr_out(">\n");
+	return 0;
+}
+
+static int dev_no_args(struct rdma *rd)
+{
+	struct dev_map *dev_map = rd->dev_map_curr;
+
+	pr_out("%u: %s: \n", dev_map->idx, dev_map->dev_name);
+	return dev_print_caps(rd);
+}
+
+static int dev_one_show(struct rdma *rd)
+{
+	const struct rdma_cmd cmds[] = {
+		{ NULL,		dev_no_args},
+		{ 0 }
+	};
+
+	return rdma_exec_cmd(rd, cmds, "parameter");
+
 }
 
 static int dev_show(struct rdma *rd)
 {
 	struct dev_map *dev_map;
+	int ret = 0;
 
 	if (rd_no_arg(rd)) {
-		list_for_each_entry(dev_map, &rd->dev_map_list, list)
-			dev_one_show(dev_map);
+		list_for_each_entry(dev_map, &rd->dev_map_list, list) {
+			rd->dev_map_curr = dev_map;
+			ret = dev_one_show(rd);
+			if (ret)
+				return ret;
+		}
+
 	}
 	else {
-		dev_map = dev_map_lookup(rd, false);
-		if (!dev_map) {
+		rd->dev_map_curr = dev_map_lookup(rd, false);
+		if (!rd->dev_map_curr) {
 			pr_err("Wrong device name\n");
 			return -ENOENT;
 		}
-		dev_one_show(dev_map);
+		rd_arg_inc(rd);
+		ret = dev_one_show(rd);
 	}
-	return 0;
+	return ret;
 }
 
 int cmd_dev(struct rdma *rd)
diff --git a/rdma/rdma.h b/rdma/rdma.h
index f5e104ec..8cca0f28 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -34,6 +34,7 @@ struct dev_map {
 	uint32_t num_ports;
 	struct list_head port_map_list;
 	uint32_t idx;
+	uint64_t caps;
 };
 
 struct rdma {
@@ -41,6 +42,7 @@ struct rdma {
 	char **argv;
 	char *filename;
 	struct list_head dev_map_list;
+	struct dev_map *dev_map_curr;
 	struct mnl_socket *nl;
 	struct nlmsghdr *nlh;
 	char *buff;
@@ -57,6 +59,7 @@ struct rdma_cmd {
 bool rd_no_arg(struct rdma *rd);
 bool rd_argv_match(struct rdma *rd, const char *pattern);
 void rd_arg_inc(struct rdma *rd);
+char *rd_argv(struct rdma *rd);
 
 /*
  * Commands interface
diff --git a/rdma/utils.c b/rdma/utils.c
index 4d29eced..94737c5c 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -28,7 +28,7 @@ static int rd_argc(struct rdma *rd)
 	return rd->argc;
 }
 
-static char *rd_argv(struct rdma *rd)
+char *rd_argv(struct rdma *rd)
 {
 	if (!rd_argc(rd))
 		return NULL;
-- 
2.13.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH iproute2 V1 4/6] rdma: Add link option and parsing
  2017-06-27 14:39 [PATCH iproute2 V1 0/5] RDMAtool Leon Romanovsky
  2017-06-27 14:39 ` [PATCH iproute2 V1 1/6] rdma: Add basic infrastructure for RDMA tool Leon Romanovsky
  2017-06-27 14:39 ` [PATCH iproute2 V1 2/6] rdma: Add dev object Leon Romanovsky
@ 2017-06-27 14:39 ` Leon Romanovsky
       [not found] ` <20170627143920.28020-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  3 siblings, 0 replies; 9+ messages in thread
From: Leon Romanovsky @ 2017-06-27 14:39 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Leon Romanovsky, Doug Ledford, Ariel Almog, Dennis Dalessandro,
	Jason Gunthorpe, Linux RDMA, Linux Netdev

From: Leon Romanovsky <leonro@mellanox.com>

Add link object interface together with port capability parsing command

$ rdma link
1/1: mlx5_0/1:
    caps: <AUTO_MIGR>
2/1: mlx5_1/1:
    caps: <AUTO_MIGR>
3/1: mlx5_2/1:
    caps: <AUTO_MIGR>
4/1: mlx5_3/1:
    caps: <CM, IP_BASED_GIDS>
5/1: mlx5_4/1:
    caps: <AUTO_MIGR>

$ rdma link show mlx5_4
5/1: mlx5_4/1:
    caps: <AUTO_MIGR>

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/Makefile |   2 +-
 rdma/link.c   | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 rdma/rdma.c   |   1 +
 rdma/rdma.h   |   4 ++
 rdma/utils.c  |   9 +++
 5 files changed, 217 insertions(+), 1 deletion(-)
 create mode 100644 rdma/link.c

diff --git a/rdma/Makefile b/rdma/Makefile
index 123d7ac5..1a9e4b1a 100644
--- a/rdma/Makefile
+++ b/rdma/Makefile
@@ -2,7 +2,7 @@ include ../Config
 
 ifeq ($(HAVE_MNL),y)
 
-RDMA_OBJ = rdma.o utils.o dev.o
+RDMA_OBJ = rdma.o utils.o dev.o link.o
 
 TARGETS=rdma
 CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
diff --git a/rdma/link.c b/rdma/link.c
new file mode 100644
index 00000000..1ffc83d4
--- /dev/null
+++ b/rdma/link.c
@@ -0,0 +1,202 @@
+/*
+ * link.c	RDMA tool
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Authors:     Leon Romanovsky <leonro@mellanox.com>
+ */
+
+#include "rdma.h"
+
+static int link_help(struct rdma *rd)
+{
+	pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
+	return 0;
+}
+
+static const char *link_caps[64] = {
+	"UNKNOWN",
+	"SM",
+	"NOTICE",
+	"TRAP",
+	"OPT_IPD",
+	"AUTO_MIGR",
+	"SL_MAP",
+	"MKEY_NVRAM",
+	"PKEY_NVRAM",
+	"LED_INFO",
+	"SM_DISABLED",
+	"SYS_IMAGE_GUID",
+	"PKEY_SW_EXT_PORT_TRAP",
+	"UNKNOWN",
+	"EXTENDED_SPEEDS",
+	"UNKNOWN",
+	"CM",
+	"SNMP_TUNNEL",
+	"REINIT",
+	"DEVICE_MGMT",
+	"VENDOR_CLASS",
+	"DR_NOTICE",
+	"CAP_MASK_NOTICE",
+	"BOOT_MGMT",
+	"LINK_LATENCY",
+	"CLIENT_REG",
+	"IP_BASED_GIDS",
+};
+
+static int link_print_caps(struct rdma *rd)
+{
+	uint64_t caps = rd->port_map_curr->caps;
+	bool found = false;
+	uint32_t idx;
+
+	pr_out("    caps: <");
+	for (idx = 0; idx < 64; idx++) {
+		if (caps & 0x1) {
+			pr_out("%s", link_caps[idx]?link_caps[idx]:"UNKNONW");
+			if (caps >> 0x1)
+				pr_out(", ");
+			found = true;
+		}
+		caps >>= 0x1;
+	}
+	if(!found)
+		pr_out("NONE");
+
+	pr_out(">\n");
+	return 0;
+}
+
+static int link_no_args(struct rdma *rd)
+{
+	struct port_map *port_map = rd->port_map_curr;
+	struct dev_map *dev_map = rd->dev_map_curr;
+
+	pr_out("%u/%u: %s/%u: \n", dev_map->idx, port_map->idx, dev_map->dev_name, port_map->idx);
+	return link_print_caps(rd);
+}
+
+static int link_one_show(struct rdma *rd)
+{
+	const struct rdma_cmd cmds[] = {
+		{ NULL,		link_no_args},
+		{ 0 }
+	};
+
+	return rdma_exec_cmd(rd, cmds, "parameter");
+
+}
+
+static int port_init_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct port_map *port_map;
+	struct dev_map *dev_map;
+	struct rdma *rd = data;
+	uint32_t port_idx;
+	uint32_t caps;
+
+	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;
+	if (!tb[RDMA_NLDEV_ATTR_PORT_INDEX]) {
+		pr_err("This tool doesn't support switches yet\n");
+		return MNL_CB_ERROR;
+	}
+
+	dev_map = rd->dev_map_curr;
+
+	port_idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
+	caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
+
+	list_for_each_entry(port_map, &dev_map->port_map_list, list) {
+		if (port_map->idx != port_idx)
+			continue;
+
+		port_map->caps = caps;
+	}
+
+	return MNL_CB_OK;
+}
+
+
+static int fill_port_map(struct rdma *rd)
+{
+	uint32_t seq;
+	int ret;
+
+	rdma_prepare_msg(rd, RDMA_NLDEV_CMD_PORT_GET, &seq, (NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP));
+	mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_map_curr->idx);
+	if ((ret = rdma_send_msg(rd)))
+		return ret;
+
+	return rdma_recv_msg(rd, port_init_cb, rd, seq);
+}
+
+static int link_show(struct rdma *rd)
+{
+	struct port_map *port_map;
+	struct dev_map *dev_map;
+	int ret = 0;
+
+	if (rd_no_arg(rd)) {
+		list_for_each_entry(dev_map, &rd->dev_map_list, list) {
+			rd->dev_map_curr = dev_map;
+			ret = fill_port_map(rd);
+			if (ret)
+				return ret;
+
+			list_for_each_entry(port_map, &dev_map->port_map_list, list) {
+				rd->port_map_curr = port_map;
+				ret = link_one_show(rd);
+				if (ret)
+					return ret;
+			}
+		}
+
+	}
+	else {
+		uint32_t port;
+		rd->dev_map_curr = dev_map_lookup(rd, true);
+		port = get_port_from_argv(rd);
+		if (!rd->dev_map_curr || port > rd->dev_map_curr->num_ports) {
+			pr_err("Wrong device name\n");
+			return -ENOENT;
+		}
+		rd_arg_inc(rd);
+
+		ret = fill_port_map(rd);
+		if (ret)
+			return ret;
+
+		list_for_each_entry(port_map, &rd->dev_map_curr->port_map_list, list) {
+			rd->port_map_curr = port_map;
+			if (port && port_map->idx != port)
+				continue;
+
+			if (!port || port_map->idx == port) {
+				ret = link_one_show(rd);
+				if (ret)
+					return ret;
+			}
+		}
+
+	}
+	return ret;
+}
+
+int cmd_link(struct rdma *rd)
+{
+	const struct rdma_cmd cmds[] = {
+		{ NULL,		link_show },
+		{ "show",	link_show },
+		{ "list",	link_show },
+		{ "help",	link_help },
+		{ 0 }
+	};
+
+	return rdma_exec_cmd(rd, cmds, "link command");
+}
diff --git a/rdma/rdma.c b/rdma/rdma.c
index f904532c..ec6c2edb 100644
--- a/rdma/rdma.c
+++ b/rdma/rdma.c
@@ -34,6 +34,7 @@ static int rd_cmd(struct rdma *rd)
 		{ NULL,		cmd_help },
 		{ "help",	cmd_help },
 		{ "dev",	cmd_dev },
+		{ "link",	cmd_link },
 		{ 0 }
 	};
 
diff --git a/rdma/rdma.h b/rdma/rdma.h
index 8cca0f28..553a4fc2 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -26,6 +26,7 @@
 struct port_map {
 	struct list_head list;
 	uint32_t idx;
+	uint64_t caps;
 };
 
 struct dev_map {
@@ -43,6 +44,7 @@ struct rdma {
 	char *filename;
 	struct list_head dev_map_list;
 	struct dev_map *dev_map_curr;
+	struct port_map *port_map_curr;
 	struct mnl_socket *nl;
 	struct nlmsghdr *nlh;
 	char *buff;
@@ -60,11 +62,13 @@ bool rd_no_arg(struct rdma *rd);
 bool rd_argv_match(struct rdma *rd, const char *pattern);
 void rd_arg_inc(struct rdma *rd);
 char *rd_argv(struct rdma *rd);
+uint32_t get_port_from_argv(struct rdma *rd);
 
 /*
  * Commands interface
  */
 int cmd_dev(struct rdma *rd);
+int cmd_link(struct rdma *rd);
 int rdma_exec_cmd(struct rdma *rd, const struct rdma_cmd *c, const char *str);
 
 /*
diff --git a/rdma/utils.c b/rdma/utils.c
index 94737c5c..68ae3d3e 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -62,6 +62,15 @@ bool rd_no_arg(struct rdma *rd)
 	return rd_argc(rd) == 0;
 }
 
+uint32_t get_port_from_argv(struct rdma *rd)
+{
+        char *slash;
+
+        slash = strchr(rd_argv(rd), '/');
+        /* if no port found, return 0 */
+        return (slash) ? (atoi(slash + 1)):0;
+}
+
 static struct dev_map *dev_map_alloc(const char *dev_name)
 {
 	struct dev_map *dev_map;
-- 
2.13.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH iproute2 V1 5/6] rdma: Add FW version to the device output
       [not found] ` <20170627143920.28020-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  2017-06-27 14:39   ` [PATCH iproute2 V1 3/6] rdma: Add device capability parsing Leon Romanovsky
@ 2017-06-27 14:39   ` Leon Romanovsky
  2017-06-27 14:39   ` [PATCH iproute2 V1 6/6] rdma: Add initial manual for the tool Leon Romanovsky
  2 siblings, 0 replies; 9+ messages in thread
From: Leon Romanovsky @ 2017-06-27 14:39 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Leon Romanovsky, Doug Ledford, Ariel Almog, Dennis Dalessandro,
	Jason Gunthorpe, Linux RDMA, Linux Netdev

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

$ rdma dev show mlx5_4
5: mlx5_4: fw 2.8.9999
    caps: <BAD_PKEY_CNTR, BAD_QKEY_CNTR, CHANGE_PHY_PORT, PORT_ACTIVE_EVENT, SYS_IMAGE_GUID, RC_RNR_NAK_GEN, MEM_WINDOW, UD_IP_CSUM, UD_TSO, XRC, MEM_MGT_EXTENSIONS, BLOCK_MULTICAST_LOOPBACK, MEM_WINDOW_TYPE_2B, RAW_IP_CSUM, SIGNATURE_HANDOVER, VIRTUAL_FUNCTION>

Signed-off-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 rdma/dev.c   | 9 ++++++++-
 rdma/rdma.h  | 1 +
 rdma/utils.c | 4 ++++
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/rdma/dev.c b/rdma/dev.c
index 76f4af88..45dc0b3f 100644
--- a/rdma/dev.c
+++ b/rdma/dev.c
@@ -83,7 +83,14 @@ static int dev_no_args(struct rdma *rd)
 {
 	struct dev_map *dev_map = rd->dev_map_curr;
 
-	pr_out("%u: %s: \n", dev_map->idx, dev_map->dev_name);
+	pr_out("%u: %s: ", dev_map->idx, dev_map->dev_name);
+	if (strlen(dev_map->fw_version) < 1)
+		/*
+		 * if no FW, the return string from RDMA netlink is "\0"
+		 */
+		pr_out("fw NONE\n");
+	else
+		pr_out("fw %s\n", dev_map->fw_version);
 	return dev_print_caps(rd);
 }
 
diff --git a/rdma/rdma.h b/rdma/rdma.h
index 553a4fc2..f221575e 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -36,6 +36,7 @@ struct dev_map {
 	struct list_head port_map_list;
 	uint32_t idx;
 	uint64_t caps;
+	char *fw_version;
 };
 
 struct rdma {
diff --git a/rdma/utils.c b/rdma/utils.c
index 68ae3d3e..47a6ab11 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -104,6 +104,7 @@ static void dev_map_free(struct dev_map *dev_map)
 		port_map_free(port_map);
 	}
 
+	free(dev_map->fw_version);
 	free(dev_map->dev_name);
 	free(dev_map);
 }
@@ -141,6 +142,7 @@ static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
 	[RDMA_NLDEV_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING,
 	[RDMA_NLDEV_ATTR_PORT_INDEX] = MNL_TYPE_U32,
 	[RDMA_NLDEV_ATTR_CAP_FLAGS] = MNL_TYPE_U64,
+	[RDMA_NLDEV_ATTR_FW_VERSION] = MNL_TYPE_NUL_STRING,
 };
 
 int rd_attr_cb(const struct nlattr *attr, void *data)
@@ -190,6 +192,8 @@ int rd_dev_init_cb(const struct nlmsghdr *nlh, void *data)
 	dev_map->idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
 	dev_map->caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
 
+	dev_map->fw_version = strdup(mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_FW_VERSION]));
+
 	return MNL_CB_OK;
 }
 
-- 
2.13.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH iproute2 V1 6/6] rdma: Add initial manual for the tool
       [not found] ` <20170627143920.28020-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  2017-06-27 14:39   ` [PATCH iproute2 V1 3/6] rdma: Add device capability parsing Leon Romanovsky
  2017-06-27 14:39   ` [PATCH iproute2 V1 5/6] rdma: Add FW version to the device output Leon Romanovsky
@ 2017-06-27 14:39   ` Leon Romanovsky
  2 siblings, 0 replies; 9+ messages in thread
From: Leon Romanovsky @ 2017-06-27 14:39 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Leon Romanovsky, Doug Ledford, Ariel Almog, Dennis Dalessandro,
	Jason Gunthorpe, Linux RDMA, Linux Netdev

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

Signed-off-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
---
 man/man8/Makefile |  3 +-
 man/man8/rdma.8   | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+), 1 deletion(-)
 create mode 100644 man/man8/rdma.8

diff --git a/man/man8/Makefile b/man/man8/Makefile
index f3318644..81979a07 100644
--- a/man/man8/Makefile
+++ b/man/man8/Makefile
@@ -19,7 +19,8 @@ MAN8PAGES = $(TARGETS) ip.8 arpd.8 lnstat.8 routel.8 rtacct.8 rtmon.8 rtpr.8 ss.
 	tc-simple.8 tc-skbedit.8 tc-vlan.8 tc-xt.8 tc-skbmod.8 tc-ife.8 \
 	tc-tunnel_key.8 tc-sample.8 \
 	devlink.8 devlink-dev.8 devlink-monitor.8 devlink-port.8 devlink-sb.8 \
-	ifstat.8
+	ifstat.8 \
+	rdma.8
 
 all: $(TARGETS)
 
diff --git a/man/man8/rdma.8 b/man/man8/rdma.8
new file mode 100644
index 00000000..7578c15e
--- /dev/null
+++ b/man/man8/rdma.8
@@ -0,0 +1,82 @@
+.TH RDMA 8 "28 Mar 2017" "iproute2" "Linux"
+.SH NAME
+rdma \- RDMA tool
+.SH SYNOPSIS
+.sp
+.ad l
+.in +8
+.ti -8
+.B rdma
+.RI "[ " OPTIONS " ] " OBJECT " { " COMMAND " | "
+.BR help " }"
+.sp
+
+.ti -8
+.IR OBJECT " := { "
+.BR dev " | " link " }"
+.sp
+
+.ti -8
+.IR OPTIONS " := { "
+\fB\-V\fR[\fIersion\fR] }
+
+.SH OPTIONS
+
+.TP
+.BR "\-V" , " -Version"
+Print the version of the
+.B rdma
+tool and exit.
+
+.SS
+.I OBJECT
+
+.TP
+.B dev
+- RDMA device.
+
+.TP
+.B link
+- RDMA port related.
+
+.PP
+The names of all objects may be written in full or
+abbreviated form, for example
+.B stats
+can be abbreviated as
+.B stat
+or just
+.B s.
+
+.SS
+.I COMMAND
+
+Specifies the action to perform on the object.
+The set of possible actions depends on the object type.
+As a rule, it is possible to
+.B show
+(or
+.B list
+) objects, but some objects do not allow all of these operations
+or have some additional commands. The
+.B help
+command is available for all objects. It prints
+out a list of available commands and argument syntax conventions.
+.sp
+If no command is given, some default command is assumed.
+Usually it is
+.B list
+or, if the objects of this class cannot be listed,
+.BR "help" .
+
+.SH EXIT STATUS
+Exit status is 0 if command was successful or a positive integer upon failure.
+
+.SH REPORTING BUGS
+Report any bugs to the Linux RDMA mailing list
+.B <linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
+where the development and maintenance is primarily done.
+You do not have to be subscribed to the list to send a message there.
+
+.SH AUTHOR
+Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
-- 
2.13.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH iproute2 V1 3/6] rdma: Add device capability parsing
       [not found]     ` <20170627143920.28020-4-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
@ 2017-06-27 23:04       ` Stephen Hemminger
  2017-06-28  4:16         ` Leon Romanovsky
  0 siblings, 1 reply; 9+ messages in thread
From: Stephen Hemminger @ 2017-06-27 23:04 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Leon Romanovsky, Doug Ledford, Ariel Almog, Dennis Dalessandro,
	Jason Gunthorpe, Linux RDMA, Linux Netdev

On Tue, 27 Jun 2017 17:39:17 +0300
Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:

> +static const char *dev_caps[64] = {
> +	"RESIZE_MAX_WR",
> +	"BAD_PKEY_CNTR",
> +	"BAD_QKEY_CNTR",
> +	"RAW_MULTI",
> +	"AUTO_PATH_MIG",
> +	"CHANGE_PHY_PORT",
> +	"UD_AV_PORT_ENFORCE",
> +	"CURR_QP_STATE_MOD",
> +	"SHUTDOWN_PORT",
> +	"INIT_TYPE",
> +	"PORT_ACTIVE_EVENT",
> +	"SYS_IMAGE_GUID",
> +	"RC_RNR_NAK_GEN",
> +	"SRQ_RESIZE",
> +	"N_NOTIFY_CQ",
> +	"LOCAL_DMA_LKEY",
> +	"RESERVED",
> +	"MEM_WINDOW",
> +	"UD_IP_CSUM",
> +	"UD_TSO",
> +	"XRC",
> +	"MEM_MGT_EXTENSIONS",
> +	"BLOCK_MULTICAST_LOOPBACK",
> +	"MEM_WINDOW_TYPE_2A",
> +	"MEM_WINDOW_TYPE_2B",
> +	"RC_IP_CSUM",
> +	"RAW_IP_CSUM",
> +	"CROSS_CHANNEL",
> +	"MANAGED_FLOW_STEERING",
> +	"SIGNATURE_HANDOVER",
> +	"ON_DEMAND_PAGING",
> +	"SG_GAPS_REG",
> +	"VIRTUAL_FUNCTION",
> +	"RAW_SCATTER_FCS",
> +	"RDMA_NETDEV_OPA_VNIC",
> +};

Please use array initializer so that header and capabilities don't get different values.
Are the bit values in some rdma header file?
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH iproute2 V1 3/6] rdma: Add device capability parsing
  2017-06-27 23:04       ` Stephen Hemminger
@ 2017-06-28  4:16         ` Leon Romanovsky
  0 siblings, 0 replies; 9+ messages in thread
From: Leon Romanovsky @ 2017-06-28  4:16 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Doug Ledford, Ariel Almog, Dennis Dalessandro, Jason Gunthorpe,
	Linux RDMA, Linux Netdev

[-- Attachment #1: Type: text/plain, Size: 1432 bytes --]

On Tue, Jun 27, 2017 at 04:04:49PM -0700, Stephen Hemminger wrote:
> On Tue, 27 Jun 2017 17:39:17 +0300
> Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>
> > +static const char *dev_caps[64] = {
> > +	"RESIZE_MAX_WR",
> > +	"BAD_PKEY_CNTR",
> > +	"BAD_QKEY_CNTR",
> > +	"RAW_MULTI",
> > +	"AUTO_PATH_MIG",
> > +	"CHANGE_PHY_PORT",
> > +	"UD_AV_PORT_ENFORCE",
> > +	"CURR_QP_STATE_MOD",
> > +	"SHUTDOWN_PORT",
> > +	"INIT_TYPE",
> > +	"PORT_ACTIVE_EVENT",
> > +	"SYS_IMAGE_GUID",
> > +	"RC_RNR_NAK_GEN",
> > +	"SRQ_RESIZE",
> > +	"N_NOTIFY_CQ",
> > +	"LOCAL_DMA_LKEY",
> > +	"RESERVED",
> > +	"MEM_WINDOW",
> > +	"UD_IP_CSUM",
> > +	"UD_TSO",
> > +	"XRC",
> > +	"MEM_MGT_EXTENSIONS",
> > +	"BLOCK_MULTICAST_LOOPBACK",
> > +	"MEM_WINDOW_TYPE_2A",
> > +	"MEM_WINDOW_TYPE_2B",
> > +	"RC_IP_CSUM",
> > +	"RAW_IP_CSUM",
> > +	"CROSS_CHANNEL",
> > +	"MANAGED_FLOW_STEERING",
> > +	"SIGNATURE_HANDOVER",
> > +	"ON_DEMAND_PAGING",
> > +	"SG_GAPS_REG",
> > +	"VIRTUAL_FUNCTION",
> > +	"RAW_SCATTER_FCS",
> > +	"RDMA_NETDEV_OPA_VNIC",
> > +};
>
> Please use array initializer so that header and capabilities don't get different values.
> Are the bit values in some rdma header file?

It is enum ib_device_cap_flags copied from include/rdma/ib_verbs.h.
These enum ib_device_cap_flags and enum ib_port_cap_flags are not exposed
to the user (include/uapi/rdma/*) and I'm planning to move them there in
next cycle.

Thanks

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-06-28  4:16 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-27 14:39 [PATCH iproute2 V1 0/5] RDMAtool Leon Romanovsky
2017-06-27 14:39 ` [PATCH iproute2 V1 1/6] rdma: Add basic infrastructure for RDMA tool Leon Romanovsky
2017-06-27 14:39 ` [PATCH iproute2 V1 2/6] rdma: Add dev object Leon Romanovsky
2017-06-27 14:39 ` [PATCH iproute2 V1 4/6] rdma: Add link option and parsing Leon Romanovsky
     [not found] ` <20170627143920.28020-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-06-27 14:39   ` [PATCH iproute2 V1 3/6] rdma: Add device capability parsing Leon Romanovsky
     [not found]     ` <20170627143920.28020-4-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2017-06-27 23:04       ` Stephen Hemminger
2017-06-28  4:16         ` Leon Romanovsky
2017-06-27 14:39   ` [PATCH iproute2 V1 5/6] rdma: Add FW version to the device output Leon Romanovsky
2017-06-27 14:39   ` [PATCH iproute2 V1 6/6] rdma: Add initial manual for the tool Leon Romanovsky

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.