--- /dev/null
+Bottom: 99652de79f6e570f6df54f6ac0bcb32159c9afc5
+Top: 8375a2135fb3ff8da1bb99921fe042c311ea0dbb
+Author: Sean Hefty <sean.hefty@intel.com>
+Date: 2014-04-09 21:52:59 -0700
+
+Refresh of lazy-init
+
+---
+
+diff --git a/src/cma.c b/src/cma.c
+index 886d04a..aacc809 100644
+--- a/src/cma.c
++++ b/src/cma.c
+@@ -122,6 +122,7 @@ struct cma_event {
+
+ static struct cma_device *cma_dev_array;
+ static int cma_dev_cnt;
++static int cma_init_cnt;
+ static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
+ static int abi_ver = RDMA_USER_CM_MAX_ABI_VERSION;
+ int af_ib_support;
+@@ -140,6 +141,7 @@ static void ucma_cleanup(void)
+ if (cma_dev_array[cma_dev_cnt].refcnt)
+ ibv_dealloc_pd(cma_dev_array[cma_dev_cnt].pd);
+ ibv_close_device(cma_dev_array[cma_dev_cnt].verbs);
++ cma_init_cnt--;
+ }
+
+ fastlock_destroy(&idm_lock);
+@@ -205,6 +207,62 @@ static void ucma_set_af_ib_support(void)
+ rdma_destroy_id(id);
+ }
+
++int ucma_init(void)
++{
++ struct ibv_device **dev_list = NULL;
++ int i, ret, dev_cnt;
++
++ /* Quick check without lock to see if we're already initialized */
++ if (cma_dev_cnt)
++ return 0;
++
++ pthread_mutex_lock(&mut);
++ if (cma_dev_cnt) {
++ pthread_mutex_unlock(&mut);
++ return 0;
++ }
++
++ fastlock_init(&idm_lock);
++ ret = check_abi_version();
++ if (ret)
++ goto err1;
++
++ dev_list = ibv_get_device_list(&dev_cnt);
++ if (!dev_list) {
++ fprintf(stderr, PFX "Fatal: unable to get RDMA device list\n");
++ ret = ERR(ENODEV);
++ goto err1;
++ }
++
++ if (!dev_cnt) {
++ fprintf(stderr, PFX "Fatal: no RDMA devices found\n");
++ ret = ERR(ENODEV);
++ goto err2;
++ }
++
++ cma_dev_array = calloc(dev_cnt, sizeof *cma_dev_array);
++ if (!cma_dev_array) {
++ ret = ERR(ENOMEM);
++ goto err2;
++ }
++
++ for (i = 0; dev_list[i]; i++)
++ cma_dev_array[i].guid = ibv_get_device_guid(dev_list[i]);
++
++ cma_dev_cnt = dev_cnt;
++ ucma_set_af_ib_support();
++ pthread_mutex_unlock(&mut);
++ ibv_free_device_list(dev_list);
++ return 0;
++
++err2:
++ ibv_free_device_list(dev_list);
++err1:
++ fastlock_destroy(&idm_lock);
++ pthread_mutex_unlock(&mut);
++ return ret;
++}
++
+ static struct ibv_context *ucma_open_device(uint64_t guid)
+ {
+ struct ibv_device **dev_list;
+@@ -231,102 +289,62 @@ static struct ibv_context *ucma_open_device(uint64_t guid)
+ return verbs;
+ }
+
+-static int ucma_dev_init(struct cma_device *cma_dev)
++static int ucma_init_device(struct cma_device *cma_dev)
+ {
+ struct ibv_device_attr attr;
+ int ret;
+
+- /* Quick check without lock to see if we're already initialized */
+ if (cma_dev->verbs)
+ return 0;
+
+- pthread_mutex_lock(&mut);
+- if (cma_dev->verbs) {
+- pthread_mutex_unlock(&mut);
+- return 0;
+- }
+-
+ cma_dev->verbs = ucma_open_device(cma_dev->guid);
+- if (!cma_dev->verbs) {
+- ret = ERR(ENODEV);
+- goto err1;
+- }
++ if (!cma_dev->verbs)
++ return ERR(ENODEV);
+
+ ret = ibv_query_device(cma_dev->verbs, &attr);
+ if (ret) {
+ fprintf(stderr, PFX "Fatal: unable to query RDMA device\n");
+ ret = ERR(ret);
+- goto err2;
++ goto err;
+ }
+
+ cma_dev->port_cnt = attr.phys_port_cnt;
+ cma_dev->max_qpsize = attr.max_qp_wr;
+ cma_dev->max_initiator_depth = (uint8_t) attr.max_qp_init_rd_atom;
+ cma_dev->max_responder_resources = (uint8_t) attr.max_qp_rd_atom;
+-
+- pthread_mutex_unlock(&mut);
++ cma_init_cnt++;
+ return 0;
+
+-err2:
++err:
+ ibv_close_device(cma_dev->verbs);
+ cma_dev->verbs = NULL;
+-err1:
+- pthread_mutex_unlock(&mut);
+ return ret;
+ }
+
+-int ucma_init(void)
++int ucma_init_all(void)
+ {
+- struct ibv_device **dev_list = NULL;
+- int i, ret, dev_cnt;
++ int i, ret;
+
+- /* Quick check without lock to see if we're already initialized */
+- if (cma_dev_cnt)
++ if (!cma_dev_cnt) {
++ ret = ucma_init();
++ if (ret)
++ return ret;
++ }
++
++ if (cma_init_cnt == cma_dev_cnt)
+ return 0;
+
+ pthread_mutex_lock(&mut);
+- if (cma_dev_cnt) {
++ if (cma_init_cnt == cma_dev_cnt) {
+ pthread_mutex_unlock(&mut);
+ return 0;
+ }
+
+- fastlock_init(&idm_lock);
+- ret = check_abi_version();
+- if (ret)
+- goto err1;
+-
+- dev_list = ibv_get_device_list(&dev_cnt);
+- if (!dev_list) {
+- fprintf(stderr, PFX "Fatal: unable to get RDMA device list\n");
+- ret = ERR(ENODEV);
+- goto err1;
+- }
+-
+- if (!dev_cnt) {
+- fprintf(stderr, PFX "Fatal: no RDMA devices found\n");
+- ret = ERR(ENODEV);
+- goto err2;
+- }
+-
+- cma_dev_array = calloc(dev_cnt, sizeof *cma_dev_array);
+- if (!cma_dev_array) {
+- ret = ERR(ENOMEM);
+- goto err2;
++ for (i = 0; i < cma_dev_cnt; i++) {
++ ret = ucma_init_device(ucma_dev_array[i]);
++ if (ret)
++ break;
+ }
+-
+- for (i = 0; dev_list[i]; i++)
+- cma_dev_array[i].guid = ibv_get_device_guid(dev_list[i]);
+-
+- cma_dev_cnt = dev_cnt;
+- ucma_set_af_ib_support();
+- pthread_mutex_unlock(&mut);
+- ibv_free_device_list(dev_list);
+- return 0;
+-
+-err2:
+- ibv_free_device_list(dev_list);
+-err1:
+- fastlock_destroy(&idm_lock);
+ pthread_mutex_unlock(&mut);
+ return ret;
+ }
+@@ -336,7 +354,7 @@ struct ibv_context **rdma_get_devices(int *num_devices)
+ struct ibv_context **devs;
+ int i;
+
+- if (ucma_init())
++ if (ucma_init_all())
+ goto err1;
+
+ devs = malloc(sizeof *devs * (cma_dev_cnt + 1));
+@@ -344,7 +362,6 @@ struct ibv_context **rdma_get_devices(int *num_devices)
+ goto err1;
+
+ for (i = 0; i < cma_dev_cnt; i++) {
+- ucma_dev_init(&cma_dev_array[i]);
+ devs[i] = cma_dev_array[i].verbs;
+ if (!devs[i])
+ goto err2;
+@@ -401,7 +418,7 @@ void rdma_destroy_event_channel(struct rdma_event_channel *channel)
+ static int ucma_get_device(struct cma_id_private *id_priv, uint64_t guid)
+ {
+ struct cma_device *cma_dev;
+- int i, ret = 0;
++ int i, ret;
+
+ for (i = 0; i < cma_dev_cnt; i++) {
+ cma_dev = &cma_dev_array[i];
+@@ -411,8 +428,8 @@ static int ucma_get_device(struct cma_id_private *id_priv, uint64_t guid)
+
+ return ERR(ENODEV);
+ match:
+- if (ucma_dev_init(cma_dev))
+- return ERR(ENODEV);
++ if ((ret = ucma_dev_init(cma_dev)))
++ return ret;
+
+ pthread_mutex_lock(&mut);
+ if (!cma_dev->refcnt++) {
+@@ -2348,7 +2365,7 @@ int ucma_max_qpsize(struct rdma_cm_id *id)
+ if (id && id_priv->cma_dev) {
+ max_size = id_priv->cma_dev->max_qpsize;
+ } else {
+- ucma_init();
++ ucma_init_all();
+ for (i = 0; i < cma_dev_cnt; i++) {
+ if (!max_size || max_size > cma_dev_array[i].max_qpsize)
+ max_size = cma_dev_array[i].max_qpsize;
+diff --git a/src/cma.h b/src/cma.h
+index 4c991b4..e4fe3f5 100644
+--- a/src/cma.h
++++ b/src/cma.h
+@@ -158,7 +158,7 @@ static inline int ERR(int err)
+ return -1;
+ }
+
+-int ucma_init();
++int ucma_init(int lazy);
+ extern int af_ib_support;
+
+ #define RAI_ROUTEONLY 0x01000000