diff mbox

[iproute2,3/5] rdma: Add device capability parsing

Message ID 20170626182128.24964-4-leon@kernel.org
State RFC, archived
Delegated to: stephen hemminger
Headers show

Commit Message

Leon Romanovsky June 26, 2017, 6:21 p.m. UTC
From: Leon Romanovsky <leonro@mellanox.com>

Add parsing interface for the device capability flags

$ rdma dev show
1: mlx5_0: caps 0x1257e1c26
2: mlx5_1: caps 0x1257e1c26
3: mlx5_2: caps 0x1257e1c26
4: mlx5_3: caps 0x1257e1c26
5: mlx5_4: caps 0x1257e1c26

$ rdma dev show mlx5_4
5: mlx5_4: caps 0x1257e1c26

$ rdma dev show mlx5_4 caps
5: mlx5_4: caps 0x1257e1c26
Bit	Description
------------------------------------------
 01	DEVICE_BAD_PKEY_CNTR
 02	DEVICE_BAD_QKEY_CNTR
 05	DEVICE_CHANGE_PHY_PORT
 10	DEVICE_PORT_ACTIVE_EVENT
 11	DEVICE_SYS_IMAGE_GUID
 12	DEVICE_RC_RNR_NAK_GEN
 17	DEVICE_MEM_WINDOW
 18	DEVICE_UD_IP_CSUM
 19	DEVICE_UD_TSO
 20	DEVICE_XRC
 21	DEVICE_MEM_MGT_EXTENSIONS
 22	DEVICE_BLOCK_MULTICAST_LOOPBACK
 24	DEVICE_MEM_WINDOW_TYPE_2B
 26	DEVICE_RAW_IP_CSUM
 29	DEVICE_SIGNATURE_HANDOVER
 32	DEVICE_VIRTUAL_FUNCTION

$ rdma dev show mlx5_4 cap_flags
Unknown parameter 'caps_flags'.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/dev.c   | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 rdma/rdma.h  |  3 ++
 rdma/utils.c |  3 +-
 3 files changed, 93 insertions(+), 9 deletions(-)

--
2.13.1

Comments

Jason Gunthorpe June 26, 2017, 6:29 p.m. UTC | #1
On Mon, Jun 26, 2017 at 09:21:26PM +0300, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@mellanox.com>
> 
> Add parsing interface for the device capability flags
> 
> $ rdma dev show
> 1: mlx5_0: caps 0x1257e1c26

This seems very un ip-like. I wouldn't show an undecoded hex value
like that, it isn't really useful.

> $ rdma dev show mlx5_4 caps
> 5: mlx5_4: caps 0x1257e1c26
> Bit	Description
>  01	DEVICE_BAD_PKEY_CNTR
>  02	DEVICE_BAD_QKEY_CNTR

This table also seems un ip-like, the usual format is a list of words,
I think.

> $ rdma dev show mlx5_4 cap_flags
> Unknown parameter 'caps_flags'.

?

Jason
Leon Romanovsky June 26, 2017, 7:21 p.m. UTC | #2
On Mon, Jun 26, 2017 at 12:29:24PM -0600, Jason Gunthorpe wrote:
> On Mon, Jun 26, 2017 at 09:21:26PM +0300, Leon Romanovsky wrote:
> > From: Leon Romanovsky <leonro@mellanox.com>
> >
> > Add parsing interface for the device capability flags
> >
> > $ rdma dev show
> > 1: mlx5_0: caps 0x1257e1c26
>
> This seems very un ip-like. I wouldn't show an undecoded hex value
> like that, it isn't really useful.

It is first supported field, after new fields will be added, we will
have very similar to ip interface.

1: mlx5_0: caps 0x1257e1c2 key_1 val_1 key_2 val_2 ....

The value are presented as is can be usable as an input for different scripts.

>
> > $ rdma dev show mlx5_4 caps
> > 5: mlx5_4: caps 0x1257e1c26
> > Bit	Description
> >  01	DEVICE_BAD_PKEY_CNTR
> >  02	DEVICE_BAD_QKEY_CNTR
>
> This table also seems un ip-like, the usual format is a list of words,
> I think.

It is true for key<->value data, but it is less obvious for bit parsing.
Internally, I tried to present them as list and it was ugly like hell
without any chance (without extra parsing) to actual see if specific
capability is present or no.

The question is: is such presentation usable and does it make sense?

>
> > $ rdma dev show mlx5_4 cap_flags
> > Unknown parameter 'caps_flags'.
>
> ?

An example of "wrong" parameter. There is no such caps_flags.

>
> Jason
Jason Gunthorpe June 26, 2017, 8:36 p.m. UTC | #3
On Mon, Jun 26, 2017 at 10:21:03PM +0300, Leon Romanovsky wrote:
> On Mon, Jun 26, 2017 at 12:29:24PM -0600, Jason Gunthorpe wrote:
> > On Mon, Jun 26, 2017 at 09:21:26PM +0300, Leon Romanovsky wrote:
> > > From: Leon Romanovsky <leonro@mellanox.com>
> > >
> > > Add parsing interface for the device capability flags
> > >
> > > $ rdma dev show
> > > 1: mlx5_0: caps 0x1257e1c26
> >
> > This seems very un ip-like. I wouldn't show an undecoded hex value
> > like that, it isn't really useful.
> 
> It is first supported field, after new fields will be added, we will
> have very similar to ip interface.
> 
> 1: mlx5_0: caps 0x1257e1c2 key_1 val_1 key_2 val_2 ....
> 
> The value are presented as is can be usable as an input for different scripts.

I still wouldn't show an undecoded hex value.. It isn't useful.

> > > $ rdma dev show mlx5_4 caps
> > > 5: mlx5_4: caps 0x1257e1c26
> > > Bit	Description
> > >  01	DEVICE_BAD_PKEY_CNTR
> > >  02	DEVICE_BAD_QKEY_CNTR
> >
> > This table also seems un ip-like, the usual format is a list of words,
> > I think.
> 
> It is true for key<->value data, but it is less obvious for bit
> parsing.

Several of the word decodes are from bit fields..

> Internally, I tried to present them as list and it was ugly like hell
> without any chance (without extra parsing) to actual see if specific
> capability is present or no.

lspci seems to have no problem being readable while doing this..

Jason
Leon Romanovsky June 27, 2017, 4:06 a.m. UTC | #4
On Mon, Jun 26, 2017 at 02:36:10PM -0600, Jason Gunthorpe wrote:
> On Mon, Jun 26, 2017 at 10:21:03PM +0300, Leon Romanovsky wrote:
> > On Mon, Jun 26, 2017 at 12:29:24PM -0600, Jason Gunthorpe wrote:
> > > On Mon, Jun 26, 2017 at 09:21:26PM +0300, Leon Romanovsky wrote:
> > > > From: Leon Romanovsky <leonro@mellanox.com>
> > > >
> > > > Add parsing interface for the device capability flags
> > > >
> > > > $ rdma dev show
> > > > 1: mlx5_0: caps 0x1257e1c26
> > >
> > > This seems very un ip-like. I wouldn't show an undecoded hex value
> > > like that, it isn't really useful.
> >
> > It is first supported field, after new fields will be added, we will
> > have very similar to ip interface.
> >
> > 1: mlx5_0: caps 0x1257e1c2 key_1 val_1 key_2 val_2 ....
> >
> > The values are presented as is can be usable as an input for different scripts.
>
> I still wouldn't show an undecoded hex value.. It isn't useful.
>
> > > > $ rdma dev show mlx5_4 caps
> > > > 5: mlx5_4: caps 0x1257e1c26
> > > > Bit	Description
> > > >  01	DEVICE_BAD_PKEY_CNTR
> > > >  02	DEVICE_BAD_QKEY_CNTR
> > >
> > > This table also seems un ip-like, the usual format is a list of words,
> > > I think.
> >
> > It is true for key<->value data, but it is less obvious for bit
> > parsing.
>
> Several of the word decodes are from bit fields..
>
> > Internally, I tried to present them as list and it was ugly like hell
> > without any chance (without extra parsing) to actual see if specific
> > capability is present or no.
>
> lspci seems to have no problem being readable while doing this..

No problem,
If i understand you correctly, you are suggesting to drop parsing of
"caps" as a separate command and embed it into general show <devname>.

Can you help me and give an example of how would you present those caps?
What will be the output of such command?
 $ rdma dev show mlx5_4

 Thanks

>
> Jason
Leon Romanovsky June 27, 2017, 9:21 a.m. UTC | #5
On Tue, Jun 27, 2017 at 07:06:04AM +0300, Leon Romanovsky wrote:
> On Mon, Jun 26, 2017 at 02:36:10PM -0600, Jason Gunthorpe wrote:
> > On Mon, Jun 26, 2017 at 10:21:03PM +0300, Leon Romanovsky wrote:
> > > On Mon, Jun 26, 2017 at 12:29:24PM -0600, Jason Gunthorpe wrote:
> > > > On Mon, Jun 26, 2017 at 09:21:26PM +0300, Leon Romanovsky wrote:
> > > > > From: Leon Romanovsky <leonro@mellanox.com>
> > > > >
> > > > > Add parsing interface for the device capability flags
> > > > >
> > > > > $ rdma dev show
> > > > > 1: mlx5_0: caps 0x1257e1c26
> > > >
> > > > This seems very un ip-like. I wouldn't show an undecoded hex value
> > > > like that, it isn't really useful.
> > >
> > > It is first supported field, after new fields will be added, we will
> > > have very similar to ip interface.
> > >
> > > 1: mlx5_0: caps 0x1257e1c2 key_1 val_1 key_2 val_2 ....
> > >
> > > The values are presented as is can be usable as an input for different scripts.
> >
> > I still wouldn't show an undecoded hex value.. It isn't useful.
> >
> > > > > $ rdma dev show mlx5_4 caps
> > > > > 5: mlx5_4: caps 0x1257e1c26
> > > > > Bit	Description
> > > > >  01	DEVICE_BAD_PKEY_CNTR
> > > > >  02	DEVICE_BAD_QKEY_CNTR
> > > >
> > > > This table also seems un ip-like, the usual format is a list of words,
> > > > I think.
> > >
> > > It is true for key<->value data, but it is less obvious for bit
> > > parsing.
> >
> > Several of the word decodes are from bit fields..
> >
> > > Internally, I tried to present them as list and it was ugly like hell
> > > without any chance (without extra parsing) to actual see if specific
> > > capability is present or no.
> >
> > lspci seems to have no problem being readable while doing this..
>
> No problem,
> If i understand you correctly, you are suggesting to drop parsing of
> "caps" as a separate command and embed it into general show <devname>.
>
> Can you help me and give an example of how would you present those caps?
> What will be the output of such command?
>  $ rdma dev show mlx5_4

ip-like style:

$ 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>
$ rdma link show mlx5_3
4/1: mlx5_3/1:
    caps: <CM, IP_BASED_GIDS>

Thanks

>
>  Thanks
>
> >
> > Jason
Jason Gunthorpe June 27, 2017, 4:41 p.m. UTC | #6
On Tue, Jun 27, 2017 at 12:21:29PM +0300, Leon Romanovsky wrote:
> > What will be the output of such command?
> >  $ rdma dev show mlx5_4
> 
> ip-like style:
> 
> $ 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>
> $ rdma link show mlx5_3
> 4/1: mlx5_3/1:
>     caps: <CM, IP_BASED_GIDS>

I think that is better, maybe it should only show under some kind of
verbose mode, I don't know, it depends what other stuff ends up being
displayed..

Are you going to dump the gid table and pkey table too in one of these commands?

Jason
Leon Romanovsky June 27, 2017, 5:33 p.m. UTC | #7
On Tue, Jun 27, 2017 at 10:41:50AM -0600, Jason Gunthorpe wrote:
> On Tue, Jun 27, 2017 at 12:21:29PM +0300, Leon Romanovsky wrote:
> > > What will be the output of such command?
> > >  $ rdma dev show mlx5_4
> >
> > ip-like style:
> >
> > $ 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>
> > $ rdma link show mlx5_3
> > 4/1: mlx5_3/1:
> >     caps: <CM, IP_BASED_GIDS>
>
> I think that is better, maybe it should only show under some kind of
> verbose mode, I don't know, it depends what other stuff ends up being
> displayed..
>
> Are you going to dump the gid table and pkey table too in one of these commands?

My initial plan was to put all parsers under their respective names, in
the similar way as I did for caps: $ rdma dev show mlx5_4 caps

So for large dumps, I'm going to use that technique again and maybe print summary as a default.
For example, for gids, we can print utilization as a summary while whole
table if someone really wants it: $ rdma link show mlx5_4/1 gids <index>

Something like that.

Thanks

>
> Jason
Jason Gunthorpe June 27, 2017, 5:37 p.m. UTC | #8
On Tue, Jun 27, 2017 at 08:33:01PM +0300, Leon Romanovsky wrote:

> My initial plan was to put all parsers under their respective names, in
> the similar way as I did for caps: $ rdma dev show mlx5_4 caps

I think you should have a useful summary display similar to 'ip a' and
other commands.

guid(s), subnet prefix or default gid for IB, lid/lmc, link state,
speed, mtu, pkeys protocol(s)

A show gid table command makes sense for rocee where it can show the
gid and the IP binding for it, rocee mode, etc..

Jason
Leon Romanovsky June 27, 2017, 5:46 p.m. UTC | #9
On Tue, Jun 27, 2017 at 11:37:35AM -0600, Jason Gunthorpe wrote:
> On Tue, Jun 27, 2017 at 08:33:01PM +0300, Leon Romanovsky wrote:
>
> > My initial plan was to put all parsers under their respective names, in
> > the similar way as I did for caps: $ rdma dev show mlx5_4 caps
>
> I think you should have a useful summary display similar to 'ip a' and
> other commands.
>
> guid(s), subnet prefix or default gid for IB, lid/lmc, link state,
> speed, mtu, pkeys protocol(s)

It will, but before I would like to see this tool be a part of
iproute2, so other people will be able to extend it in addition
to me.

Are you fine with the proposed code?

>
> A show gid table command makes sense for rocee where it can show the
> gid and the IP binding for it, rocee mode, etc..
>
> Jason
Stephen Hemminger June 27, 2017, 10:16 p.m. UTC | #10
On Tue, 27 Jun 2017 20:33:01 +0300
Leon Romanovsky <leon@kernel.org> wrote:

> On Tue, Jun 27, 2017 at 10:41:50AM -0600, Jason Gunthorpe wrote:
> > On Tue, Jun 27, 2017 at 12:21:29PM +0300, Leon Romanovsky wrote:  
> > > > What will be the output of such command?
> > > >  $ rdma dev show mlx5_4  
> > >
> > > ip-like style:
> > >
> > > $ 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>
> > > $ rdma link show mlx5_3
> > > 4/1: mlx5_3/1:
> > >     caps: <CM, IP_BASED_GIDS>  
> >
> > I think that is better, maybe it should only show under some kind of
> > verbose mode, I don't know, it depends what other stuff ends up being
> > displayed..
> >
> > Are you going to dump the gid table and pkey table too in one of these commands?  
> 
> My initial plan was to put all parsers under their respective names, in
> the similar way as I did for caps: $ rdma dev show mlx5_4 caps
> 
> So for large dumps, I'm going to use that technique again and maybe print summary as a default.
> For example, for gids, we can print utilization as a summary while whole
> table if someone really wants it: $ rdma link show mlx5_4/1 gids <index>
> 
> Something like that.
> 
> Thanks
> 
> >
> > Jason  

Agree with discussion so far.

For iproute2 style commands, the show and set commands need to have similar arguments.
Ideally, everything after the colon in the show would be parameters to set command.

Please consider having a concise form for normal users and a detail form (with -d) for 
configuration and setup cases. The caps should not need to be displayed in normal show
output.
Stephen Hemminger June 27, 2017, 10:18 p.m. UTC | #11
On Tue, 27 Jun 2017 20:46:15 +0300
Leon Romanovsky <leon@kernel.org> wrote:

> On Tue, Jun 27, 2017 at 11:37:35AM -0600, Jason Gunthorpe wrote:
> > On Tue, Jun 27, 2017 at 08:33:01PM +0300, Leon Romanovsky wrote:
> >  
> > > My initial plan was to put all parsers under their respective names, in
> > > the similar way as I did for caps: $ rdma dev show mlx5_4 caps  
> >
> > I think you should have a useful summary display similar to 'ip a' and
> > other commands.
> >
> > guid(s), subnet prefix or default gid for IB, lid/lmc, link state,
> > speed, mtu, pkeys protocol(s)  
> 
> It will, but before I would like to see this tool be a part of
> iproute2, so other people will be able to extend it in addition
> to me.
> 
> Are you fine with the proposed code?
> 

Output formats need to be nailed down. The output of iproute2 commands is almost
like an ABI. Users build scripts to parse it (whether that is a great idea or not
is debateable, it mostly shows the weakness in programatic API's). Therefore fully
changing output formats in later revisions is likely to get users upset.

The first version doesn't have to be perfect, just close to the overall goal
of what is planned.
Leon Romanovsky June 28, 2017, 4:33 a.m. UTC | #12
On Tue, Jun 27, 2017 at 03:18:59PM -0700, Stephen Hemminger wrote:
> On Tue, 27 Jun 2017 20:46:15 +0300
> Leon Romanovsky <leon@kernel.org> wrote:
>
> > On Tue, Jun 27, 2017 at 11:37:35AM -0600, Jason Gunthorpe wrote:
> > > On Tue, Jun 27, 2017 at 08:33:01PM +0300, Leon Romanovsky wrote:
> > >
> > > > My initial plan was to put all parsers under their respective names, in
> > > > the similar way as I did for caps: $ rdma dev show mlx5_4 caps
> > >
> > > I think you should have a useful summary display similar to 'ip a' and
> > > other commands.
> > >
> > > guid(s), subnet prefix or default gid for IB, lid/lmc, link state,
> > > speed, mtu, pkeys protocol(s)
> >
> > It will, but before I would like to see this tool be a part of
> > iproute2, so other people will be able to extend it in addition
> > to me.
> >
> > Are you fine with the proposed code?
> >
>
> Output formats need to be nailed down. The output of iproute2 commands is almost
> like an ABI. Users build scripts to parse it (whether that is a great idea or not
> is debateable, it mostly shows the weakness in programatic API's). Therefore fully
> changing output formats in later revisions is likely to get users upset.
>
> The first version doesn't have to be perfect, just close to the overall goal
> of what is planned.

In this version, I'm going to use arrays without indexes, because I prefer
to expose the bare minimum from the kernel, which is RDMA netlink. After
everything else is settled, I'll move those defines to UAPI and reuse them
in rdmatool.

I'll send new version with -d/--details flag and enrich minimal summary.
It won't include anything related to tables gids, pkey yet.

Thanks
Jason Gunthorpe June 28, 2017, 4:11 p.m. UTC | #13
On Tue, Jun 27, 2017 at 03:18:59PM -0700, Stephen Hemminger wrote:
> On Tue, 27 Jun 2017 20:46:15 +0300
> Leon Romanovsky <leon@kernel.org> wrote:
> 
> > On Tue, Jun 27, 2017 at 11:37:35AM -0600, Jason Gunthorpe wrote:
> > > On Tue, Jun 27, 2017 at 08:33:01PM +0300, Leon Romanovsky wrote:
> > >  
> > > > My initial plan was to put all parsers under their respective names, in
> > > > the similar way as I did for caps: $ rdma dev show mlx5_4 caps  
> > >
> > > I think you should have a useful summary display similar to 'ip a' and
> > > other commands.
> > >
> > > guid(s), subnet prefix or default gid for IB, lid/lmc, link state,
> > > speed, mtu, pkeys protocol(s)  
> > 
> > It will, but before I would like to see this tool be a part of
> > iproute2, so other people will be able to extend it in addition
> > to me.
> > 
> > Are you fine with the proposed code?
> > 
> 
> Output formats need to be nailed down. The output of iproute2 commands is almost
> like an ABI. Users build scripts to parse it (whether that is a great idea or not
> is debateable, it mostly shows the weakness in programatic API's). Therefore fully
> changing output formats in later revisions is likely to get users upset.

It would be nice to see an example of what the completed command
should output to make judgements on the format.. Going bit by bit
doesn't really give a full picture, IHO.

Jason
Leon Romanovsky June 28, 2017, 7:11 p.m. UTC | #14
On Wed, Jun 28, 2017 at 10:11:12AM -0600, Jason Gunthorpe wrote:
> On Tue, Jun 27, 2017 at 03:18:59PM -0700, Stephen Hemminger wrote:
> > On Tue, 27 Jun 2017 20:46:15 +0300
> > Leon Romanovsky <leon@kernel.org> wrote:
> >
> > > On Tue, Jun 27, 2017 at 11:37:35AM -0600, Jason Gunthorpe wrote:
> > > > On Tue, Jun 27, 2017 at 08:33:01PM +0300, Leon Romanovsky wrote:
> > > >
> > > > > My initial plan was to put all parsers under their respective names, in
> > > > > the similar way as I did for caps: $ rdma dev show mlx5_4 caps
> > > >
> > > > I think you should have a useful summary display similar to 'ip a' and
> > > > other commands.
> > > >
> > > > guid(s), subnet prefix or default gid for IB, lid/lmc, link state,
> > > > speed, mtu, pkeys protocol(s)
> > >
> > > It will, but before I would like to see this tool be a part of
> > > iproute2, so other people will be able to extend it in addition
> > > to me.
> > >
> > > Are you fine with the proposed code?
> > >
> >
> > Output formats need to be nailed down. The output of iproute2 commands is almost
> > like an ABI. Users build scripts to parse it (whether that is a great idea or not
> > is debateable, it mostly shows the weakness in programatic API's). Therefore fully
> > changing output formats in later revisions is likely to get users upset.
>
> It would be nice to see an example of what the completed command
> should output to make judgements on the format.. Going bit by bit
> doesn't really give a full picture, IHO.

Bit by bit expansion allow easily control of what is needed. Mostly,
those full examples have nothing close to real use case.

>
> Jason
diff mbox

Patch

diff --git a/rdma/dev.c b/rdma/dev.c
index 5a3ee126..31c235e8 100644
--- a/rdma/dev.c
+++ b/rdma/dev.c
@@ -14,6 +14,7 @@ 
 static int dev_help(struct rdma *rd)
 {
 	pr_out("Usage: %s dev show [DEV]\n", rd->filename);
+	pr_out("       %s dev show DEV caps\n", rd->filename);

 	/*
 	 * Example of set command:
@@ -22,28 +23,107 @@  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] = {
+	"DEVICE_RESIZE_MAX_WR",
+	"DEVICE_BAD_PKEY_CNTR",
+	"DEVICE_BAD_QKEY_CNTR",
+	"DEVICE_RAW_MULTI",
+	"DEVICE_AUTO_PATH_MIG",
+	"DEVICE_CHANGE_PHY_PORT",
+	"DEVICE_UD_AV_PORT_ENFORCE",
+	"DEVICE_CURR_QP_STATE_MOD",
+	"DEVICE_SHUTDOWN_PORT",
+	"DEVICE_INIT_TYPE",
+	"DEVICE_PORT_ACTIVE_EVENT",
+	"DEVICE_SYS_IMAGE_GUID",
+	"DEVICE_RC_RNR_NAK_GEN",
+	"DEVICE_SRQ_RESIZE",
+	"DEVICE_N_NOTIFY_CQ",
+	"DEVICE_LOCAL_DMA_LKEY",
+	"DEVICE_RESERVED",
+	"DEVICE_MEM_WINDOW",
+	"DEVICE_UD_IP_CSUM",
+	"DEVICE_UD_TSO",
+	"DEVICE_XRC",
+	"DEVICE_MEM_MGT_EXTENSIONS",
+	"DEVICE_BLOCK_MULTICAST_LOOPBACK",
+	"DEVICE_MEM_WINDOW_TYPE_2A",
+	"DEVICE_MEM_WINDOW_TYPE_2B",
+	"DEVICE_RC_IP_CSUM",
+	"DEVICE_RAW_IP_CSUM",
+	"DEVICE_CROSS_CHANNEL",
+	"DEVICE_MANAGED_FLOW_STEERING",
+	"DEVICE_SIGNATURE_HANDOVER",
+	"DEVICE_ON_DEMAND_PAGING",
+	"DEVICE_SG_GAPS_REG",
+	"DEVICE_VIRTUAL_FUNCTION",
+	"DEVICE_RAW_SCATTER_FCS",
+	"DEVICE_RDMA_NETDEV_OPA_VNIC",
+};
+
+static int dev_print_caps(struct rdma *rd)
+{
+	struct dev_map *dev_map = rd->dev_map_curr;
+	uint64_t caps = dev_map->caps;
+	uint32_t idx;
+
+	pr_out("%u: %s: ", dev_map->idx, dev_map->dev_name);
+	pr_out("caps 0x%" PRIx64 "\n", dev_map->caps);
+	pr_out("Bit\tDescription\n");
+	pr_out("------------------------------------------\n");
+	for (idx = 0; idx < 64; idx++) {
+		if (caps & 0x1)
+			pr_out(" %02u\t%s\n", idx, dev_caps[idx]?dev_caps[idx]:"UNKNONW");
+		caps >>= 0x1;
+	}
+	return 0;
+}
+
+static int dev_no_args(struct rdma *rd)
+{
+	struct dev_map *dev_map = rd->dev_map_curr;
+
+	pr_out("%u: %s: ", dev_map->idx, dev_map->dev_name);
+	pr_out("caps 0x%" PRIx64 "\n", dev_map->caps);
+	return 0;
+}
+
+static int dev_one_show(struct rdma *rd)
 {
-	pr_out("%u: %s:\n", dev_map->idx, dev_map->dev_name);
+	const struct rdma_cmd cmds[] = {
+		{ NULL,		dev_no_args},
+		{ "caps",	dev_print_caps},
+		{ 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 e5c3dd6c..e7f257e3 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;
@@ -128,6 +128,7 @@  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,
 };