PSARC/2012/200 OFUV SR-IOV support
authorAlex Chiu <Alex.Chiu@Oracle.COM>
Mon, 04 Jun 2012 12:59:44 -0700
changeset 851 5d9119e2b7e1
parent 850 66e4d7e438bd
child 852 0a7f3f0c7b6f
PSARC/2012/200 OFUV SR-IOV support 7173893 sol_uverbs is limited to 16 HCAs, and panics when more exist (userland) 7169005 sol_uverbs: IB_USER_VERBS_CMD_QUERY_GID & IB_USER_VERBS_CMD_QUERY_PKEY APIs are obsolete (userland)
components/open-fabrics/libibverbs/patches/base.patch
components/open-fabrics/libibverbs/solaris_compatibility.c
--- a/components/open-fabrics/libibverbs/patches/base.patch	Mon Jun 04 11:26:13 2012 -0700
+++ b/components/open-fabrics/libibverbs/patches/base.patch	Mon Jun 04 12:59:44 2012 -0700
@@ -378,7 +378,7 @@
 +#if defined(__SVR4) && defined(__sun)
 +#include <fcntl.h>
 +#include <sys/stat.h>
-+#include <sys/sysmacros.h>
++#include <sys/mkdev.h>
 +#endif
  
  #include "ibverbs.h"
@@ -556,7 +556,36 @@
 diff -r -u /tmp/846623/libibverbs-1.1.4/src/device.c libibverbs-1.1.4/src/device.c
 --- /tmp/846623/libibverbs-1.1.4/src/device.c	Thu Feb  3 01:53:17 2011
 +++ libibverbs-1.1.4/src/device.c	Fri Feb 11 04:02:31 2011
[email protected]@ -128,8 +128,13 @@
[email protected]@ -122,6 +122,28 @@
+ }
+ default_symver(__ibv_get_device_guid, ibv_get_device_guid);
+ 
++uint64_t __ibv_get_device_guid_external(struct ibv_device *device)
++{
++	char attr[24];
++	uint64_t guid = 0;
++	uint16_t parts[4];
++	int i;
++
++	if (ibv_read_sysfs_file(device->ibdev_path, "node_guid_external",
++				attr, sizeof attr) < 0)
++		return 0;
++
++	if (sscanf(attr, "%hx:%hx:%hx:%hx",
++		   parts, parts + 1, parts + 2, parts + 3) != 4)
++		return 0;
++
++	for (i = 0; i < 4; ++i)
++		guid = (guid << 16) | parts[i];
++
++	return htonll(guid);
++}
++default_symver(__ibv_get_device_guid_external, ibv_get_device_guid_external);
++
+ struct ibv_context *__ibv_open_device(struct ibv_device *device)
+ {
+ 	char *devpath;
[email protected]@ -128,8 +150,13 @@
  	int cmd_fd;
  	struct ibv_context *context;
  
@@ -570,7 +599,7 @@
  
  	/*
  	 * We'll only be doing writes, but we need O_RDWR in case the
[email protected]@ -163,6 +168,9 @@
[email protected]@ -163,6 +190,9 @@
  	int async_fd = context->async_fd;
  	int cmd_fd   = context->cmd_fd;
  	int cq_fd    = -1;
@@ -580,7 +609,7 @@
  
  	if (abi_ver <= 2) {
  		struct ibv_abi_compat_v2 *t = context->abi_compat;
[email protected]@ -172,6 +180,11 @@
[email protected]@ -172,6 +202,11 @@
  
  	context->device->ops.free_context(context);
  
@@ -660,7 +689,7 @@
 +#if defined(__SVR4) && defined(__sun)
 +#include <fcntl.h>
 +#include <sys/stat.h>
-+#include <sys/sysmacros.h>
++#include <sys/mkdev.h>
 +#endif
  
  #include "ibverbs.h"
@@ -766,7 +795,15 @@
  	return 0;
  }
  
[email protected]@ -218,6 +283,45 @@
[email protected]@ -120,6 +185,7 @@
+ 	memset(device_attr->fw_ver, 0, sizeof device_attr->fw_ver);
+ 	*raw_fw_ver			       = resp.fw_ver;
+ 	device_attr->node_guid 		       = resp.node_guid;
++	device_attr->node_guid_external	       = resp.node_guid_external;
+ 	device_attr->sys_image_guid 	       = resp.sys_image_guid;
+ 	device_attr->max_mr_size 	       = resp.max_mr_size;
+ 	device_attr->page_size_cap 	       = resp.page_size_cap;
[email protected]@ -218,6 +284,45 @@
  	return 0;
  }
  
@@ -812,7 +849,7 @@
  int ibv_cmd_dealloc_pd(struct ibv_pd *pd)
  {
  	struct ibv_dealloc_pd cmd;
[email protected]@ -259,6 +363,34 @@
[email protected]@ -259,6 +364,34 @@
  	return 0;
  }
  
@@ -847,7 +884,7 @@
  int ibv_cmd_dereg_mr(struct ibv_mr *mr)
  {
  	struct ibv_dereg_mr cmd;
[email protected]@ -272,6 +404,32 @@
[email protected]@ -272,6 +405,32 @@
  	return 0;
  }
  
@@ -880,7 +917,7 @@
  static int ibv_cmd_create_cq_v2(struct ibv_context *context, int cqe,
  				struct ibv_cq *cq,
  				struct ibv_create_cq *new_cmd, size_t new_cmd_size,
[email protected]@ -315,7 +473,19 @@
[email protected]@ -315,7 +474,19 @@
  	cmd->user_handle   = (uintptr_t) cq;
  	cmd->cqe           = cqe;
  	cmd->comp_vector   = comp_vector;
@@ -900,7 +937,7 @@
  	cmd->reserved      = 0;
  
  	if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
[email protected]@ -637,7 +807,19 @@
[email protected]@ -637,7 +808,19 @@
  	cmd->max_send_sge    = attr->cap.max_send_sge;
  	cmd->max_recv_sge    = attr->cap.max_recv_sge;
  	cmd->max_inline_data = attr->cap.max_inline_data;
@@ -920,7 +957,7 @@
  	cmd->qp_type 	     = attr->qp_type;
  	cmd->is_srq 	     = !!attr->srq;
  	cmd->srq_handle      = attr->qp_type == IBV_QPT_XRC ?
[email protected]@ -1406,4 +1588,3 @@
[email protected]@ -1406,4 +1589,3 @@
  		return errno;
  	return 0;
  }
@@ -1183,7 +1220,7 @@
  
  /*
   * This file must be kept in sync with the kernel's version of
[email protected]@ -94,6 +98,15 @@
[email protected]@ -94,6 +98,11 @@
  	IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP,
  	IB_USER_VERBS_CMD_REG_XRC_RCV_QP,
  	IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP,
@@ -1191,54 +1228,19 @@
 +	IB_USER_VERBS_CMD_DEREG_MR_RELAXED,
 +	IB_USER_VERBS_CMD_FLUSH_RELAXED_MR,
 +	IB_USER_VERBS_CMD_ALLOC_SHPD,
-+	IB_USER_VERBS_CMD_SHARE_PD,
-+#if defined(__SVR4) && defined(__sun)
-+	IB_USER_VERBS_CMD_QUERY_GID,
-+	IB_USER_VERBS_CMD_QUERY_PKEY
-+#endif
++	IB_USER_VERBS_CMD_SHARE_PD
  };
  
  /*
[email protected]@ -235,6 +248,38 @@
- 	__u8  reserved[2];
- };
- 
-+#if defined(__SVR4) && defined(__sun)
-+struct ibv_query_gid {
-+	__u32 command;
-+	__u16 in_words;
-+	__u16 out_words;
-+	__u64 response;
-+	__u32 gid_index;
-+	__u8  port_num;
-+	__u8  reserved[3];
-+	__u64 driver_data;
-+};
-+
-+struct ibv_query_gid_resp {
-+	__u8  gid[16];
-+};
-+
-+struct ibv_query_pkey {
-+	__u32 command;
-+	__u16 in_words;
-+	__u16 out_words;
-+	__u64 response;
-+	__u32 pkey_index;
-+	__u8  port_num;
-+	__u8  reserved[3];
-+	__u64 driver_data;
-+};
-+
-+struct ibv_query_pkey_resp {
-+	__u16 pkey;
-+	__u16 reserved;
-+};
-+#endif
- struct ibv_alloc_pd {
- 	__u32 command;
- 	__u16 in_words;
[email protected]@ -243,10 +288,57 @@
[email protected]@ -160,6 +169,7 @@
+ struct ibv_query_device_resp {
+ 	__u64 fw_ver;
+ 	__u64 node_guid;
++	__u64 node_guid_external;
+ 	__u64 sys_image_guid;
+ 	__u64 max_mr_size;
+ 	__u64 page_size_cap;
[email protected]@ -243,10 +253,57 @@
  	__u64 driver_data[0];
  };
  
@@ -1296,7 +1298,7 @@
  struct ibv_dealloc_pd {
  	__u32 command;
  	__u16 in_words;
[email protected]@ -280,6 +372,13 @@
[email protected]@ -280,6 +337,13 @@
  	__u32 mr_handle;
  };
  
@@ -1310,7 +1312,7 @@
  struct ibv_create_comp_channel {
  	__u32 command;
  	__u16 in_words;
[email protected]@ -304,10 +403,25 @@
[email protected]@ -304,10 +368,25 @@
  	__u64 driver_data[0];
  };
  
@@ -1336,7 +1338,7 @@
  
  struct ibv_kern_wc {
  	__u64  wr_id;
[email protected]@ -363,7 +477,11 @@
[email protected]@ -363,7 +442,11 @@
  struct ibv_resize_cq_resp {
  	__u32 cqe;
  	__u32 reserved;
@@ -1348,7 +1350,7 @@
  };
  
  struct ibv_destroy_cq {
[email protected]@ -460,6 +578,14 @@
[email protected]@ -460,6 +543,14 @@
  	__u64 driver_data[0];
  };
  
@@ -1363,7 +1365,7 @@
  struct ibv_create_qp_resp {
  	__u32 qp_handle;
  	__u32 qpn;
[email protected]@ -469,7 +595,20 @@
[email protected]@ -469,7 +560,20 @@
  	__u32 max_recv_sge;
  	__u32 max_inline_data;
  	__u32 reserved;
@@ -1384,7 +1386,7 @@
  
  struct ibv_qp_dest {
  	__u8  dgid[16];
[email protected]@ -817,12 +956,29 @@
[email protected]@ -817,12 +921,29 @@
  	__u64 driver_data[0];
  };
  
@@ -1414,7 +1416,7 @@
  
  struct ibv_modify_srq {
  	__u32 command;
[email protected]@ -946,6 +1102,11 @@
[email protected]@ -946,6 +1067,11 @@
  	IB_USER_VERBS_CMD_QUERY_XRC_RCV_QP_V2 = -1,
  	IB_USER_VERBS_CMD_REG_XRC_RCV_QP_V2 = -1,
  	IB_USER_VERBS_CMD_UNREG_XRC_RCV_QP_V2 = -1,
@@ -1484,7 +1486,15 @@
  
  #ifdef __cplusplus
  #  define BEGIN_C_DECLS extern "C" {
[email protected]@ -297,7 +300,8 @@
[email protected]@ -105,6 +108,7 @@
+ struct ibv_device_attr {
+ 	char			fw_ver[64];
+ 	uint64_t		node_guid;
++	uint64_t		node_guid_external;
+ 	uint64_t		sys_image_guid;
+ 	uint64_t		max_mr_size;
+ 	uint64_t		page_size_cap;
[email protected]@ -297,7 +301,8 @@
  	IBV_ACCESS_REMOTE_WRITE		= (1<<1),
  	IBV_ACCESS_REMOTE_READ		= (1<<2),
  	IBV_ACCESS_REMOTE_ATOMIC	= (1<<3),
@@ -1494,7 +1504,7 @@
  };
  
  struct ibv_pd {
[email protected]@ -305,6 +309,10 @@
[email protected]@ -305,6 +310,10 @@
  	uint32_t		handle;
  };
  
@@ -1505,7 +1515,7 @@
  enum ibv_rereg_mr_flags {
  	IBV_REREG_MR_CHANGE_TRANSLATION	= (1 << 0),
  	IBV_REREG_MR_CHANGE_PD		= (1 << 1),
[email protected]@ -425,6 +433,14 @@
[email protected]@ -425,6 +434,14 @@
  	uint32_t		max_inline_data;
  };
  
@@ -1520,7 +1530,7 @@
  struct ibv_qp_init_attr {
  	void		       *qp_context;
  	struct ibv_cq	       *send_cq;
[email protected]@ -743,6 +759,12 @@
[email protected]@ -743,6 +760,12 @@
  	int			(*detach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid,
  						uint16_t lid);
  	void			(*async_event)(struct ibv_async_event *event);
@@ -1533,7 +1543,7 @@
  };
  
  struct ibv_context {
[email protected]@ -749,6 +771,13 @@
[email protected]@ -749,6 +772,13 @@
  	struct ibv_device      *device;
  	struct ibv_context_ops	ops;
  	int			cmd_fd;
@@ -1547,7 +1557,19 @@
  	int			async_fd;
  	int			num_comp_vectors;
  	pthread_mutex_t		mutex;
[email protected]@ -858,6 +887,20 @@
[email protected]@ -797,6 +827,11 @@
+ uint64_t ibv_get_device_guid(struct ibv_device *device);
+ 
+ /**
++ * ibv_get_device_guid_external - Return device's node external GUID
++ */
++uint64_t ibv_get_device_guid_external(struct ibv_device *device);
++
++/**
+  * ibv_open_device - Initialize device for use
+  */
+ struct ibv_context *ibv_open_device(struct ibv_device *device);
[email protected]@ -858,6 +893,20 @@
  struct ibv_pd *ibv_alloc_pd(struct ibv_context *context);
  
  /**
@@ -1568,7 +1590,7 @@
   * ibv_dealloc_pd - Free a protection domain
   */
  int ibv_dealloc_pd(struct ibv_pd *pd);
[email protected]@ -869,11 +912,27 @@
[email protected]@ -869,11 +918,27 @@
  			  size_t length, int access);
  
  /**
@@ -1778,7 +1800,7 @@
 diff -r -u /tmp/846623/libibverbs-1.1.4/examples/device_list.c libibverbs-1.1.4/examples/device_list.c
 --- /tmp/846623/libibverbs-1.1.4/examples/device_list.c	Sun Nov  1 06:47:19 2009
 +++ libibverbs-1.1.4/examples/device_list.c	Fri Feb 11 04:02:18 2011
[email protected]@ -36,8 +36,10 @@
[email protected]@ -36,16 +36,32 @@
  
  #include <stdio.h>
  
@@ -1787,8 +1809,82 @@
  #include <byteswap.h>
 +#endif
  
++#include <stdlib.h>
++#include <string.h>
  #include <infiniband/verbs.h>
  #include <infiniband/arch.h>
+ 
++/*
++ * Structure to hold the data printed by ibv_devices.
++ */
++typedef struct dev_print_s {
++	char			name[24];
++	unsigned long long	guid;
++	uint8_t			is_pf;
++} dev_print_t;
++
+ int main(int argc, char *argv[])
+ {
+ 	struct ibv_device **dev_list;
+ 	int num_devices, i;
++	unsigned long long	guid_external;
++	dev_print_t	*dp;
++	int	print_col = 0;
+ 
+ 	dev_list = ibv_get_device_list(&num_devices);
+ 	if (!dev_list) {
[email protected]@ -53,15 +69,45 @@
+ 		return 1;
+ 	}
+ 
+-	printf("    %-16s\t   node GUID\n", "device");
+-	printf("    %-16s\t----------------\n", "------");
++	dp = (dev_print_t *)malloc(sizeof(dev_print_t) * num_devices);
+ 
+-	for (i = 0; i < num_devices; ++i) {
+-		printf("    %-16s\t%016llx\n",
+-		       ibv_get_device_name(dev_list[i]),
+-		       (unsigned long long) ntohll(ibv_get_device_guid(dev_list[i])));
++	for (i = (num_devices - 1); i >= 0; --i) {
++		strcpy(dp[i].name, ibv_get_device_name(dev_list[i]));
++
++		dp[i].guid = (unsigned long long) ntohll(ibv_get_device_guid(dev_list[i]));
++		guid_external = (unsigned long long) ntohll(ibv_get_device_guid_external(dev_list[i]));
++		if (dp[i].guid != guid_external) {
++			print_col = 1;
++			dp[i].is_pf = 0;
++		} else
++			dp[i].is_pf = 1;
+ 	}
+ 
++	if (print_col) {
++		printf("    %-16s\t   node GUID\t        type\n", "device");
++		printf("    %-16s\t----------------\t----\n", "------");
++		/* First print PFs */
++		for (i = (num_devices - 1); i >= 0; --i) {
++			if (dp[i].is_pf)
++				printf("    %-16s\t%016llx\t %s\n",
++					dp[i].name, dp[i].guid, "PF");
++		}
++		/* print VFs */
++		for (i = (num_devices - 1); i >= 0; --i) {
++			if (!dp[i].is_pf)
++				printf("    %-16s\t%016llx\t %s\n",
++					dp[i].name, dp[i].guid, "VF");
++		}
++	} else {
++		printf("    %-16s\t   node GUID\n", "device");
++		printf("    %-16s\t----------------\n", "------");
++		for (i = (num_devices - 1); i >= 0; --i) {
++			printf("    %-16s\t%016llx\n",
++				dp[i].name, dp[i].guid);
++		}
++	}
++	free(dp);
++
+ 	ibv_free_device_list(dev_list);
+ 
+ 	return 0;
 diff -r -u /tmp/846623/libibverbs-1.1.4/examples/devinfo.c libibverbs-1.1.4/examples/devinfo.c
 --- /tmp/846623/libibverbs-1.1.4/examples/devinfo.c	Thu Mar 10 06:58:21 2011
 +++ libibverbs-1.1.4/examples/devinfo.c	Fri Feb 11 04:02:19 2011
--- a/components/open-fabrics/libibverbs/solaris_compatibility.c	Mon Jun 04 11:26:13 2012 -0700
+++ b/components/open-fabrics/libibverbs/solaris_compatibility.c	Mon Jun 04 12:59:44 2012 -0700
@@ -64,30 +64,36 @@
  * The followings will be removed when changes in sol_uverbs_ioctl.h
  * are delivered through ON.
  */
-#if !defined(UVERBS_IOCTL_NO_CMDS) || (UVERBS_IOCTL_NO_CMDS < 3)
 
-#define	UVERBS_IOCTL_GET_PKEYS		UVERBS_IOCTL | 0x02
-#define	UVERBS_IOCTL_GET_GIDS		UVERBS_IOCTL | 0x03
+#if	(IB_USER_MAD_SOLARIS_ABI_VERSION == 1)
+#undef	IB_USER_MAD_SOLARIS_ABI_VERSION
+#define	IB_USER_MAD_SOLARIS_ABI_VERSION	2
+#endif
 
-typedef struct sol_uverbs_pkey_s {
-	int32_t		uverbs_solaris_abi_version;
-	int16_t		uverbs_port_num;
-	int16_t		uverbs_pkey_cnt;
-	int16_t		uverbs_pkey_start_index;
-	int8_t		uverbs_pad1[6];		/* Padding for alignment */
-	uint16_t	uverbs_pkey[];
-} sol_uverbs_pkey_t;
+#if	(IB_USER_VERBS_SOLARIS_ABI_VERSION == 1)
+#undef	IB_USER_VERBS_SOLARIS_ABI_VERSION
+#define	IB_USER_VERBS_SOLARIS_ABI_VERSION	2
+#define	IB_USER_VERBS_V2_IN_V1
+typedef struct sol_uverbs_hca_info_v2_s {
+	char		uverbs_hca_psid_string[MAXNAMELEN];
+	char		uverbs_hca_ibdev_name[MAXNAMELEN];
+	char		uverbs_hca_driver_name[MAXNAMELEN];
+	uint32_t	uverbs_hca_driver_instance;
+	uint32_t	uverbs_hca_vendorid;
+	uint16_t	uverbs_hca_deviceid;
+	uint16_t	uverbs_hca_devidx;
+	uint8_t		uverbs_hca_pad1[4];
+} sol_uverbs_hca_info_v2_t;
 
-typedef struct sol_uverbs_gid_s {
-	int32_t		uverbs_solaris_abi_version;
-	int16_t		uverbs_port_num;
-	int16_t		uverbs_gid_cnt;
-	int16_t		uverbs_gid_start_index;
-	int8_t		uverbs_pad1[6];		/* Padding for alignment */
-	uint8_t		uverbs_gids[][16];
-} sol_uverbs_gid_t;
+typedef struct sol_uverbs_info_v2_s {
+	int32_t			uverbs_abi_version;
+	int32_t			uverbs_solaris_abi_version;
+	int16_t			uverbs_hca_cnt;
+	int8_t			uverbs_pad1[6];    /* Padding for alignment */
+	sol_uverbs_hca_info_v2_t	uverbs_hca_info[];
+} sol_uverbs_info_v2_t;
+#endif
 
-#endif	/* !defined(UVERBS_IOCTL_NO_CMDS) || (UVERBS_IOCTL_NO_CMDS < 3) */
 /* end of sol_uverbs_ioctl.h contents */
 
 /*
@@ -99,7 +105,7 @@
 #define	RDMA_USER_CM_MAX_ABI_VERSION	4 /* rdma_cma_abi.h */
 
 #define	MLX4	0
-#define	MAX_HCAS				16
+#define	MAX_HCAS				260
 #define	MAX_HCA_PORTS				16
 #define	HW_DRIVER_MAX_NAME_LEN			20
 #define	UVERBS_KERNEL_SYSFS_NAME_BASE		"uverbs"
@@ -159,6 +165,7 @@
 	uint_t		ibd_valid;
 	uint_t		ibd_hw_rev;
 	char		ibd_node_guid_str[20];
+	char		ibd_node_guid_external_str[20];
 	char		ibd_sys_image_guid[20];
 	char		ibd_fw_ver[16];
 	char		ibd_name[8];
@@ -517,6 +524,13 @@
 		    (unsigned)(guid >> 16) & 0xffff,
 		    (unsigned)(guid >>  0) & 0xffff);
 
+		guid = ntohll(device_attr.node_guid_external);
+		sprintf(info.ibd_node_guid_external_str, "%04x:%04x:%04x:%04x",
+		    (unsigned)(guid >> 48) & 0xffff,
+		    (unsigned)(guid >> 32) & 0xffff,
+		    (unsigned)(guid >> 16) & 0xffff,
+		    (unsigned)(guid >>  0) & 0xffff);
+
 		guid = ntohll(device_attr.sys_image_guid);
 		sprintf(info.ibd_sys_image_guid, "%04x:%04x:%04x:%04x",
 		    (unsigned)(guid >> 48) & 0xffff,
@@ -528,7 +542,12 @@
 		info.ibd_hw_rev = device_attr.hw_ver;
 
 		ibdev = ibv_get_device_name(*dev_list);
-		p = ibdev + (strlen(ibdev)-1);
+		if (strncmp(ibdev, "mlx4_", 5) == 0) {
+			p = ibdev + (strlen("mlx4_"));
+		} else {
+			fprintf(stderr, "Invalid device %s\n", ibdev);
+			goto error_exit3;
+		}
 		dev_num = atoi(p);
 		(void) strcpy(info.ibd_name, ibdev);
 
@@ -560,8 +579,13 @@
 	uverbs_cache_info_t	info;
 	int			dev_num, fd, i, bufsize, hca_cnt;
 	char			uverbs_devpath[MAXPATHLEN];
+#ifndef	IB_USER_VERBS_V2_IN_V1
 	sol_uverbs_info_t	*uverbs_infop;
 	sol_uverbs_hca_info_t	*hca_infop;
+#else
+	sol_uverbs_info_v2_t	*uverbs_infop;
+	sol_uverbs_hca_info_v2_t	*hca_infop;
+#endif
 	char *buf;
 
 	snprintf(uverbs_devpath, MAXPATHLEN, "%s/%s%d",
@@ -578,12 +602,20 @@
 		goto error_exit1;
 	}
 
+#ifndef	IB_USER_VERBS_V2_IN_V1
 	bufsize = sizeof (sol_uverbs_info_t) + sizeof (sol_uverbs_hca_info_t) *
 	    MAX_HCAS;
-
+#else
+	bufsize = sizeof (sol_uverbs_info_v2_t) +
+	    sizeof (sol_uverbs_hca_info_v2_t) * MAX_HCAS;
+#endif
 	buf = malloc(bufsize);
 	memset(buf, 0, bufsize);
+#ifndef	IB_USER_VERBS_V2_IN_V1
 	uverbs_infop = (sol_uverbs_info_t *)buf;
+#else
+	uverbs_infop = (sol_uverbs_info_v2_t *)buf;
+#endif
 	uverbs_infop->uverbs_hca_cnt = MAX_HCAS;
 
 	if (ioctl(fd, UVERBS_IOCTL_GET_HCA_INFO, uverbs_infop) != 0) {
@@ -619,7 +651,7 @@
 		    hca_infop->uverbs_hca_driver_name,
 		    hca_infop->uverbs_hca_driver_instance);
 
-		if (! strncmp(hca_infop->uverbs_hca_ibdev_name, "mlx4_", 5))
+		if (strncmp(hca_infop->uverbs_hca_ibdev_name, "mlx4_", 5) == 0)
 			info.uvc_ibdev_abi_version =
 			    MLX4_UVERBS_MAX_ABI_VERSION;
 		else {
@@ -879,7 +911,13 @@
 	}
 	(void) pthread_mutex_unlock(&ibdev_cache_mutex);
 
-	p = p+(strlen(p)-1);
+	if (strncmp(p, "mlx4_", 5) == 0) {
+		p = p+(strlen("mlx4_"));
+	} else {
+		fprintf(stderr, "libibverbs: sol_uverbs unsupported "
+		    "device: %s\n", p);
+		return (NULL);
+	}
 	dev_num = atoi(p);
 
 	if (dev_num >= MAX_HCAS) {
@@ -1083,8 +1121,14 @@
 	if (!uverbs_cache_initialized) {
 		if (uverbs_cache_init())
 			uverbs_cache_initialized = B_TRUE;
-		else
+		else {
+			(void) pthread_mutex_unlock(&uverbs_cache_mutex);
+#ifdef	DEBUG
+			fprintf(stderr, "failed: to init uverbs cache %s\n",
+			    strerror(errno));
+#endif
 			goto exit;
+		}
 	}
 	(void) pthread_mutex_unlock(&uverbs_cache_mutex);
 
@@ -1353,8 +1397,16 @@
 		goto boardid_err;
 	}
 	if (!uverbs_cache_initialized) {
-		uverbs_cache_init();
-		uverbs_cache_initialized = B_TRUE;
+		if (uverbs_cache_init())
+			uverbs_cache_initialized = B_TRUE;
+		else {
+			(void) pthread_mutex_unlock(&uverbs_cache_mutex);
+#ifdef	DEBUG
+			fprintf(stderr, "failed: to init uverbs cache %s\n",
+			    strerror(errno));
+#endif
+			goto boardid_err;
+		}
 	}
 	(void) pthread_mutex_unlock(&uverbs_cache_mutex);
 
@@ -1431,6 +1483,9 @@
 
 		if (strcmp(path, "node_guid") == 0) {
 			len = 1 + sprintf(buf, "%s", info->ibd_node_guid_str);
+		} else if (strcmp(path, "node_guid_external") == 0) {
+			len = 1 + sprintf(buf, "%s",
+			    info->ibd_node_guid_external_str);
 		} else if (strcmp(path, "sys_image_guid") == 0) {
 			len = 1 + sprintf(buf, "%s", info->ibd_sys_image_guid);
 		} else if (strcmp(path, "fw_ver") == 0) {
@@ -1468,8 +1523,14 @@
 	if (!umad_cache_initialized) {
 		if (umad_cache_init())
 			umad_cache_initialized = B_TRUE;
-		else
+		else {
+			(void) pthread_mutex_unlock(&umad_cache_mutex);
+#ifdef	DEBUG
+			fprintf(stderr, "failed: to init umad cache %s\n",
+			    strerror(errno));
+#endif
 			goto exit;
+		}
 	}
 	(void) pthread_mutex_unlock(&umad_cache_mutex);