RDMAtool
Subsystems (4)
v2 cover RDMAtool
From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>
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].
The following is an example of various runs on my machine with 5 devices (4 in IB mode and one in Ethernet mode)
### Without parameters
$ rdma
Usage: rdma [ OPTIONS ] OBJECT { COMMAND | help }
where OBJECT := { dev | link | help }
OPTIONS := { -V[ersion] | -d[etails]}### With unspecified device name
$ rdma dev 1: mlx5_0: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:3457 sys_image_guid 5254:00c0:fe12:3457 2: mlx5_1: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:3458 sys_image_guid 5254:00c0:fe12:3458 3: mlx5_2: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:3459 sys_image_guid 5254:00c0:fe12:3459 4: mlx5_3: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:345a sys_image_guid 5254:00c0:fe12:345a 5: mlx5_4: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:345b sys_image_guid 5254:00c0:fe12:345b
### Detailed mode
$ rdma -d dev
1: mlx5_0: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:3457 sys_image_guid 5254:00c0:fe12:3457
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: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:3458 sys_image_guid 5254:00c0:fe12:3458
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: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:3459 sys_image_guid 5254:00c0:fe12:3459
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: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:345a sys_image_guid 5254:00c0:fe12:345a
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: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:345b sys_image_guid 5254:00c0:fe12:345b
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>### Specific device
$ rdma dev show mlx5_4 5: mlx5_4: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:345b sys_image_guid 5254:00c0:fe12:345b
### Specific device in detailed mode
$ rdma dev show mlx5_4 -d
5: mlx5_4: node_type SWITCH fw 2.8.9999 node_guid 5254:00c0:fe12:345b sys_image_guid 5254:00c0:fe12:345b
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>### Unknown command (caps)
$ rdma dev show mlx5_4 caps Unknown parameter 'caps'.
### Link properties without device name
$ rdma link 1/1: mlx5_0/1: subnet_prefix fe80:0000:0000:0000 lid 13399 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP 2/1: mlx5_1/1: subnet_prefix fe80:0000:0000:0000 lid 13400 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP 3/1: mlx5_2/1: subnet_prefix fe80:0000:0000:0000 lid 13401 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP 4/1: mlx5_3/1: state DOWN physical_state DISABLED 5/1: mlx5_4/1: subnet_prefix fe80:0000:0000:0000 lid 13403 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP
### Link properties in detailed mode
$ rdma link -d
1/1: mlx5_0/1: subnet_prefix fe80:0000:0000:0000 lid 13399 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP
caps: <AUTO_MIGR>
2/1: mlx5_1/1: subnet_prefix fe80:0000:0000:0000 lid 13400 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP
caps: <AUTO_MIGR>
3/1: mlx5_2/1: subnet_prefix fe80:0000:0000:0000 lid 13401 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP
caps: <AUTO_MIGR>
4/1: mlx5_3/1: state DOWN physical_state DISABLED
caps: <CM, IP_BASED_GIDS>
5/1: mlx5_4/1: subnet_prefix fe80:0000:0000:0000 lid 13403 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP
caps: <AUTO_MIGR>### All links for specific device
$ rdma link show mlx5_3 1/1: mlx5_0/1: subnet_prefix fe80:0000:0000:0000 lid 13399 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP
### Detailed link properties for specific device
$ rdma link -d show mlx5_3
1/1: mlx5_0/1: subnet_prefix fe80:0000:0000:0000 lid 13399 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP
caps: <AUTO_MIGR>### Specific port for specific device
$ rdma link show mlx5_4/1 1/1: mlx5_0/1: subnet_prefix fe80:0000:0000:0000 lid 13399 sm_lid 49151 lmc 0 state ACTIVE physical_state LINK_UP
### Unknown parameter
$ rdma link show mlx5_4/1 caps Unknown parameter 'caps'.
Thanks
Changelogv1->v2:
* Squashed multiple (and similar) patches to be one patch for dev object and one patch for link object.
* Removed port_map struct
* Removed global netlink dump during initialization, it removed the need to store the intermediate variables and reuse ability of netlink to signal if variable exists or doesn't.
* Added "-d" --details option and put all CAPs under it.
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 listRFC->v0:
* Removed everything that is not implemented yet.
* Abandoned sysfs interfaces in favor of netlink.
Available in the "topic/rdmatool-netlink-v2" 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-v2
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/]
Leon Romanovsky (4):
rdma: Add basic infrastructure for RDMA tool
rdma: Add dev object
rdma: Add link object
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 | 235 +++++++++++++++++++++++++++++++++++++++++++++ rdma/link.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ rdma/rdma.c | 118 +++++++++++++++++++++++ rdma/rdma.h | 81 ++++++++++++++++ rdma/utils.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 1101 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
--
2.13.2
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20170703140658.4091-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
PATCH v2 1/4 rdma: Add basic infrastructure for RDMA tool
From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>
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.
--- Makefile | 2 +- rdma/.gitignore | 1 + rdma/Makefile | 22 ++++++ rdma/rdma.c | 116 ++++++++++++++++++++++++++++ rdma/rdma.h | 71 +++++++++++++++++ rdma/utils.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 443 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
Makefile +1 -1
@@ -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)
rdma/.gitignore new file +1 -0
@@ -0,0 +1 @@ +rdma
rdma/Makefile new file +22 -0
@@ -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)
rdma/rdma.c new file +116 -0
116 lines not on this page · raw message
rdma/rdma.h new file +71 -0
71 lines not on this page · raw message
rdma/utils.c new file +232 -0
232 lines not on this page · raw message
Signature · 6 lines
2.13.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH iproute2 V2 1/4] rdma: Add basic infrastructure for RDMA tool
Quoted 99 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
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 <[email protected]>--- Makefile | 2 +- rdma/.gitignore | 1 + rdma/Makefile | 22 ++++++ rdma/rdma.c | 116 ++++++++++++++++++++++++++++ rdma/rdma.h | 71 +++++++++++++++++ rdma/utils.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 443 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.cMakefile +1
-1@@ -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)rdma/.gitignore new file +1
-0@@ -0,0 +1 @@ +rdmardma/Makefile new file +22
-0@@ -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)rdma/rdma.c new file +18
-0@@ -0,0 +1,116 @@ +/* +* 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 <[email protected]> +*/ + +#include <limits.h> +#include <rdma/rdma_netlink.h> + +#include "rdma.h" +#include "SNAPSHOT.h" + +static void help (char *name)
rdma/rdma.c line 28
Quoted 10 lines
rdma/rdma.c new file +10
-0+{ +pr_out ("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n" +"where OBJECT := { help }\n" +" OPTIONS := { -V[ersion] | -d[etails]}\n" , name); +} + +static int cmd_help (struct rdma *rd) +{ +help (rd->filename); +return 0 ;
Can we change it to void?
Quoted 19 lines
rdma/rdma.c new file +19
-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;
rdma/rdma.c line 57
Quoted 10 lines
rdma/rdma.c new file +10
-0+ 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;
Maybe it is only my perspective but as i see it - if some init function fails at one of the steps it needs to rollback to starting point before returning an error. A caller expect that if init fails then no reason to call the free.
Caller here calls free when init fails so we are fine but just razing a point here.
Quoted 156 lines
rdma/rdma.c new file +59
-0+ +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) +{ +static const struct option long_options[] = { + {"version" , no_argument,NULL ,'V' }, + {"help" , no_argument,NULL ,'h' }, + {"details" , no_argument,NULL ,'d' }, + {NULL ,0 ,NULL ,0 } + }; +bool show_details = false; +char *filename; +struct rdma rd; +int opt; +int err; + + filename =basename (argv[0 ]); + +while ((opt =getopt_long (argc, argv,"Vhd" , + long_options,NULL )) >=0 ) { + +switch (opt) { +case 'V' : +printf ("%s utility, iproute2-ss%s\n" , filename,SNAPSHOT ); +return EXIT_SUCCESS ; +case 'd' : + show_details = true; +break ; +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; + + rd.show_details = show_details; + err =rd_cmd (&rd); +out: +/* Always cleanup */ +rd_free (&rd); +return (err) ?EXIT_FAILURE :EXIT_SUCCESS ; +}rdma/rdma.h new file +71
-0@@ -0,0 +1,71 @@ +/* +* 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 <[email protected]> +*/ +#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 dev_map { +struct list_head list; +char *dev_name; +uint32_t num_ports; +uint32_t idx; +}; + +struct rdma { +int argc; +char **argv; +char *filename; +bool show_details; +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_ */ rdma/utils.c new file +14
-0@@ -0,0 +1,232 @@ +/* +* 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 <[email protected]> +*/ + +#include <sys/types.h> +#include <dirent.h> +#include <time.h>
rdma/utils.c line 24
Quoted 10 lines
rdma/utils.c new file +10
-0+ +#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))
Can we use /usr/include/sys/param.h?
Quoted 15 lines
rdma/utils.c new file +15
-0+ +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) +{
rdma/utils.c line 49
Quoted 10 lines
rdma/utils.c new file +10
-0+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 ;
rd_argv might return NULL.
Quoted 94 lines
rdma/utils.c new file +94
-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); + +return dev_map; +} + +static void dev_map_free (struct dev_map *dev_map) +{ +if (!dev_map) +return ; + +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 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; + +mnl_attr_parse (nlh,0 , rd_attr_cb, tb); +if (!tb[RDMA_NLDEV_ATTR_DEV_NAME ] || !tb[RDMA_NLDEV_ATTR_DEV_INDEX ]) +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 ]); + + 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->num_ports =mnl_attr_get_u32 (tb[RDMA_NLDEV_ATTR_PORT_INDEX ]); + dev_map->idx =mnl_attr_get_u32 (tb[RDMA_NLDEV_ATTR_DEV_INDEX ]);
rdma/utils.c line 153
Quoted 10 lines
rdma/utils.c new file +10
-0+ +return MNL_CB_OK ; +} + +void rdma_free_devmap (struct rdma *rd) +{ +if (!rd) +return ; +dev_map_cleanup (rd); +return ;
Redundant
Quoted 22 lines
rdma/utils.c new file +22
-0+} + +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 ; +} +
rdma/utils.c line 185
Quoted 10 lines
rdma/utils.c new file +10
-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 ;
Can we change it to void?
Quoted 16 lines
rdma/utils.c new file +16
-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;
rdma/utils.c line 211
Quoted 10 lines
rdma/utils.c new file +10
-0+ } + + 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);
Suggesting to break the above line.
Quoted 28 lines
rdma/utils.c new file +21
-0+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; +}Signature · 6 lines
2.13.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH iproute2 V2 1/4] rdma: Add basic infrastructure for RDMA tool
Quoted 104 lines · Yuval Shaia
Quoted 103 lines · Leon Romanovsky
From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>
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.
--- Makefile | 2 +- rdma/.gitignore | 1 + rdma/Makefile | 22 ++++++ rdma/rdma.c | 116 ++++++++++++++++++++++++++++ rdma/rdma.h | 71 +++++++++++++++++ rdma/utils.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 443 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.cMakefile +1
-1@@ -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)rdma/.gitignore new file +1
-0@@ -0,0 +1 @@ +rdmardma/Makefile new file +22
-0@@ -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)rdma/rdma.c new file +22
-0@@ -0,0 +1,116 @@ +/* +* 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-VPRAkNaXOzVWk0Htik3J/[email protected]> +*/ + +#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] | -d[etails]}\n" , name);
Quoted 8 lines
rdma/rdma.c line 28
Quoted 6 lines
rdma/rdma.c new file +6
-0+} + +static int cmd_help (struct rdma *rd) +{ +help (rd->filename); +return 0 ;Can we change it to void?
I did it on purpose to reuse the common command executor code (rdma_exec_cmd) and don't introduce explicit if-else constructions just for the "help" command.
<...>
Quoted 8 lines
rdma/rdma.c line 34
Quoted 6 lines
rdma/rdma.c new file +6
-0+/* +* 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))Can we use
/usr/include/sys/param.h?
Thanks for pointing it to me. This is leftover from previous versions when I filled all structures during init phase. It is not used anymore and I'll remove it.
Quoted 20 lines
Quoted 20 lines
rdma/rdma.c new file +19
-0+ +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)); +}
Quoted 8 lines
rdma/rdma.c line 59
Quoted 6 lines
rdma/rdma.c new file +6
-0+ +bool rd_argv_match (struct rdma *rd,const char *pattern) +{ +if (!rd_argc (rd)) +return false; +return strcmpx (rd_argv (rd), pattern) ==0 ;
rd_argvmight return NULL.
This function is called only once in this file (in new version, I'll mark it as "static") and it is called only after we checked that "rd" has arguments (see function rdma_exec_cmd).
Quoted 99 lines
Quoted 99 lines
rdma/rdma.c new file +98
-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); + +return dev_map; +} + +static void dev_map_free (struct dev_map *dev_map) +{ +if (!dev_map) +return ; + +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 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; + +mnl_attr_parse (nlh,0 , rd_attr_cb, tb); +if (!tb[RDMA_NLDEV_ATTR_DEV_NAME ] || !tb[RDMA_NLDEV_ATTR_DEV_INDEX ]) +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 ]); + + 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->num_ports =mnl_attr_get_u32 (tb[RDMA_NLDEV_ATTR_PORT_INDEX ]); + dev_map->idx =mnl_attr_get_u32 (tb[RDMA_NLDEV_ATTR_DEV_INDEX ]); + +return MNL_CB_OK ; +} +
Quoted 8 lines
rdma/rdma.c
Quoted 6 lines
rdma/rdma.c new file +6
-0+void rdma_free_devmap (struct rdma *rd) +{ +if (!rd) +return ; +dev_map_cleanup (rd); +return ;Redundant
Fixed
Quoted 27 lines
Quoted 27 lines
rdma/rdma.c new file +26
-0+} + +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 ); +
Quoted 8 lines
rdma/rdma.c
Quoted 6 lines
rdma/rdma.c new file +6
-0+ 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 ;Can we change it to void?
Done
Quoted 21 lines
Quoted 21 lines
rdma/rdma.c new file +20
-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 ) {
Quoted 8 lines
rdma/rdma.c
Quoted 6 lines
rdma/rdma.c new file +6
-0+pr_err ("Failed to send to socket with err %d\n" , ret); + goto err; + } +return 0 ; + +err:mnl_socket_close (rd->nl);Suggesting to break the above line.
Done
Quoted 29 lines
Quoted 29 lines
rdma/rdma.c new file +21
-1+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.2
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 4/4 rdma: Add initial manual for the tool
In reply to a message not in the archiveFrom: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>
--- man/man8/Makefile | 3 +- man/man8/rdma.8 | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 man/man8/rdma.8
man/man8/Makefile +2 -1
@@ -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)
man/man8/rdma.8 new file +82 -0
82 lines not on this page · raw message
Signature · 6 lines
2.13.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 2/4 rdma: Add dev object
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Device (dev) object represents struct ib_device to the user space.
Device properties:
* Device capabilities
* FW version to the device output
* node_guid and sys_image_guid
* node_type
--- rdma/Makefile | 2 +- rdma/dev.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rdma/rdma.c | 3 +- rdma/rdma.h | 12 ++- rdma/utils.c | 46 +++++++++++- 5 files changed, 293 insertions(+), 5 deletions(-) create mode 100644 rdma/dev.c
rdma/Makefile +1 -1
@@ -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)
rdma/dev.c new file +235 -0
235 lines not on this page · raw message
rdma/rdma.c +2 -1
@@ -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] | -d[etails]}\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 } };
rdma/rdma.h +11 -1
@@ -16,7 +16,6 @@#include <errno.h> #include <getopt.h> #include <libmnl/libmnl.h> -#include <rdma/rdma_netlink.h> #include "list.h"
@@ -36,6 +35,8 @@ struct rdma {char *filename;bool show_details;struct list_head dev_map_list; +uint32_t dev_idx; +uint32_t port_idx;struct mnl_socket *nl;struct nlmsghdr *nlh;char *buff;
@@ -52,13 +53,22 @@ 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); +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);/* * 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
rdma/utils.c +44 -2
75 lines not on this page · raw message
Signature · 1 line
2.13.2
PATCH v2 3/4 rdma: Add link object
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Link (port) object represent struct ib_port to the user space.
Link properties:
* Port capabilities
* IB subnet prefix
* LID, SM_LID and LMC
* Port state
* Physical state
--- rdma/Makefile | 2 +- rdma/link.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rdma/rdma.c | 3 +- rdma/utils.c | 5 ++ 4 files changed, 288 insertions(+), 2 deletions(-) create mode 100644 rdma/link.c
rdma/Makefile +1 -1
@@ -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)
rdma/link.c new file +280 -0
280 lines not on this page · raw message
rdma/rdma.c +2 -1
@@ -18,7 +18,7 @@static void help (char *name) {pr_out ("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n" -"where OBJECT := { dev | help }\n" +"where OBJECT := { dev | link | help }\n" " OPTIONS := { -V[ersion] | -d[etails]}\n" , name); }
@@ -34,6 +34,7 @@ static int rd_cmd(struct rdma *rd) { NULL, cmd_help }, { "help", cmd_help }, { "dev", cmd_dev }, + { "link", cmd_link }, { 0 } };
rdma/utils.c +5 -0
@@ -111,6 +111,11 @@ static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = { [RDMA_NLDEV_ATTR_FW_VERSION] = MNL_TYPE_NUL_STRING, [RDMA_NLDEV_ATTR_NODE_GUID] = MNL_TYPE_U64, [RDMA_NLDEV_ATTR_SYS_IMAGE_GUID] = MNL_TYPE_U64, + [RDMA_NLDEV_ATTR_LID] = MNL_TYPE_U32, + [RDMA_NLDEV_ATTR_SM_LID] = MNL_TYPE_U32, + [RDMA_NLDEV_ATTR_LMC] = MNL_TYPE_U8, + [RDMA_NLDEV_ATTR_PORT_STATE] = MNL_TYPE_U8, + [RDMA_NLDEV_ATTR_PORT_PHYS_STATE] = MNL_TYPE_U8, [RDMA_NLDEV_ATTR_DEV_NODE_TYPE] = MNL_TYPE_U8, };
Signature · 1 line
2.13.2