]> git.openfabrics.org - ~shefty/libibverbs.git/commitdiff
Change from ibv_get_devices() to ibv_get_device_list()
authorRoland Dreier <rolandd@cisco.com>
Wed, 14 Dec 2005 20:44:36 +0000 (20:44 +0000)
committerRoland Dreier <rolandd@cisco.com>
Thu, 9 Nov 2006 19:35:58 +0000 (11:35 -0800)
Change libibverbs API for listing all known devices from
ibv_get_devices() to ibv_get_device_list(), and update all in-tree
uses of this API.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
13 files changed:
ChangeLog
examples/asyncwatch.c
examples/device_list.c
examples/devinfo.c
examples/rc_pingpong.c
examples/srq_pingpong.c
examples/uc_pingpong.c
examples/ud_pingpong.c
include/infiniband/verbs.h
src/device.c
src/ibverbs.h
src/init.c
src/libibverbs.map

index b167835abc372d696cc30086b11070342b8bbbe5..4a069e12b3927a0718fd3dbdd85dabfe7042bb61 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,15 @@
-2005-11-10  Sean Hefty <sean.hefty@intel.com>
+2005-11-11  Roland Dreier  <roland@cisco.com>
+
+       * examples/asyncwatch.c, examples/rc_pingpong.c,
+       examples/srq_pingpong.c, examples/uc_pingpong.c,
+       examples/ud_pingpong.c, examples/device_list.c,
+       examples/devinfo.c: Update examples to match new API.
+       
+       * include/infiniband/verbs.h, src/device.c, src/init.c,
+       src/ibverbs.h: Change from dlist-based ibv_get_devices() API to
+       simpler ibv_get_device_list() and ibv_free_device_list() API.
+
+2005-11-10  Sean Hefty  <sean.hefty@intel.com>
 
        * include/infiniband/sa-kern-abi.h: New include file to contain
        definitions of SA structures passed between userspace and kernel.
index d4943ca2b9d104d5ef075b970c879987c93c17ad..734d018ca232e83447b449628a2af11f131c6910 100644 (file)
@@ -50,34 +50,30 @@ static inline uint64_t be64_to_cpu(uint64_t x) { return x; }
 
 int main(int argc, char *argv[])
 {
-       struct dlist *dev_list;
-       struct ibv_device *ib_dev;
+       struct ibv_device **dev_list;
        struct ibv_context *context;
        struct ibv_async_event event;
 
-       dev_list = ibv_get_devices();
+       dev_list = ibv_get_device_list(NULL);
        if (!dev_list) {
                fprintf(stderr, "No IB devices found\n");
                return 1;
        }
 
-       dlist_start(dev_list);
-       ib_dev = dlist_next(dev_list);
-
-       if (!ib_dev) {
+       if (!*dev_list) {
                fprintf(stderr, "No IB devices found\n");
                return 1;
        }
 
-       context = ibv_open_device(ib_dev);
+       context = ibv_open_device(*dev_list);
        if (!context) {
                fprintf(stderr, "Couldn't get context for %s\n",
-                       ibv_get_device_name(ib_dev));
+                       ibv_get_device_name(*dev_list));
                return 1;
        }
 
        printf("%s: async event FD %d\n",
-              ibv_get_device_name(ib_dev), context->async_fd);
+              ibv_get_device_name(*dev_list), context->async_fd);
 
        while (1) {
                if (ibv_get_async_event(context, &event))
index 37f3a40db77b0b2f939f1eebca2d14d0fa7d4c12..f04fba4628178c32ac0aaba02994fd4c342b3777 100644 (file)
@@ -51,10 +51,9 @@ static inline uint64_t be64_to_cpu(uint64_t x) { return x; }
 
 int main(int argc, char *argv[])
 {
-       struct dlist *dev_list;
-       struct ibv_device *ib_dev;
+       struct ibv_device **dev_list;
 
-       dev_list = ibv_get_devices();
+       dev_list = ibv_get_device_list(NULL);
        if (!dev_list) {
                fprintf(stderr, "No IB devices found\n");
                return 1;
@@ -63,10 +62,12 @@ int main(int argc, char *argv[])
        printf("    %-16s\t   node GUID\n", "device");
        printf("    %-16s\t----------------\n", "------");
 
-       dlist_for_each_data(dev_list, ib_dev, struct ibv_device)
+       while (*dev_list) {
                printf("    %-16s\t%016llx\n",
-                      ibv_get_device_name(ib_dev),
-                      (unsigned long long) be64_to_cpu(ibv_get_device_guid(ib_dev)));
+                      ibv_get_device_name(*dev_list),
+                      (unsigned long long) be64_to_cpu(ibv_get_device_guid(*dev_list)));
+               ++dev_list;
+       }
 
        return 0;
 }
index 7ad5dad16dded73e00798a56e0154f2272d93b78..0e3e02022c23f26840c11effe2678cb825e0618b 100644 (file)
@@ -299,11 +299,11 @@ cleanup:
 
 static void usage(const char *argv0)
 {
-        printf("Usage: %s             print the ca attributes\n", argv0);
-        printf("\n");
-        printf("Options:\n");
-        printf("  -d, --ib-dev=<dev>     use IB device <dev> (default first device found)\n");
-        printf("  -i, --ib-port=<port>   use port <port> of IB device (default all ports)\n");
+       printf("Usage: %s             print the ca attributes\n", argv0);
+       printf("\n");
+       printf("Options:\n");
+       printf("  -d, --ib-dev=<dev>     use IB device <dev> (default first device found)\n");
+       printf("  -i, --ib-port=<port>   use port <port> of IB device (default all ports)\n");
        printf("  -l, --list             print only the IB devices names\n");
        printf("  -v, --verbose          print all the attributes of the IB device(s)\n");
 }
@@ -312,60 +312,56 @@ int main(int argc, char *argv[])
 {
        char *ib_devname = NULL;
        int ret = 0;
-       struct dlist *dev_list;
-       struct ibv_device *ib_dev;
+       struct ibv_device **dev_list;
        int num_of_hcas;
        int ib_port = 0;
 
        /* parse command line options */
        while (1) {
                int c;
-                static struct option long_options[] = {
-                        { .name = "ib-dev",   .has_arg = 1, .val = 'd' },
-                        { .name = "ib-port",  .has_arg = 1, .val = 'i' },
+               static struct option long_options[] = {
+                       { .name = "ib-dev",   .has_arg = 1, .val = 'd' },
+                       { .name = "ib-port",  .has_arg = 1, .val = 'i' },
                        { .name = "list",     .has_arg = 0, .val = 'l' },
-                        { .name = "verbose",  .has_arg = 0, .val = 'v' },
-                        { 0, 0, 0, 0}
-                };
+                       { .name = "verbose",  .has_arg = 0, .val = 'v' },
+                       { 0, 0, 0, 0}
+               };
                
-                c = getopt_long(argc, argv, "d:i:lv", long_options, NULL);
-                if (c == -1)
-                        break;
-
-                switch (c) {
-                case 'd':
-                        ib_devname = strdup(optarg);
-                        break;
-
-                case 'i':
-                        ib_port = strtol(optarg, NULL, 0);
-                        if (ib_port < 0) {
-                                usage(argv[0]);
-                                return 1;
-                        }
-                        break;
+               c = getopt_long(argc, argv, "d:i:lv", long_options, NULL);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 'd':
+                       ib_devname = strdup(optarg);
+                       break;
+
+               case 'i':
+                       ib_port = strtol(optarg, NULL, 0);
+                       if (ib_port < 0) {
+                               usage(argv[0]);
+                               return 1;
+                       }
+                       break;
 
                case 'v':
-                        verbose = 1;
-                        break;
+                       verbose = 1;
+                       break;
 
                case 'l':
-                       dev_list = ibv_get_devices();
+                       dev_list = ibv_get_device_list(&num_of_hcas);
                        if (!dev_list) {
                                fprintf(stderr, "Failed to get IB devices list");
                                return -1;
                        }
 
-                       num_of_hcas = 0;
-                       dlist_for_each_data(dev_list, ib_dev, struct ibv_device)
-                               num_of_hcas ++;
-
                        printf("%d HCA%s found:\n", num_of_hcas,
                               num_of_hcas != 1 ? "s" : "");
 
-                       dlist_start(dev_list);
-                       dlist_for_each_data(dev_list, ib_dev, struct ibv_device)
-                               printf("\t%s\n", ibv_get_device_name(ib_dev));
+                       while (*dev_list) {
+                               printf("\t%s\n", ibv_get_device_name(*dev_list));
+                               ++dev_list;
+                       }
 
                        printf("\n");
                        return 0;
@@ -376,28 +372,31 @@ int main(int argc, char *argv[])
                }
        }
 
-       dev_list = ibv_get_devices();
+       dev_list = ibv_get_device_list(NULL);
        if (!dev_list) {
                fprintf(stderr, "Failed to get IB device list\n");
                return -1;
        }
-       dlist_start(dev_list);
+
        if (ib_devname) {
-               dlist_for_each_data(dev_list, ib_dev, struct ibv_device)
-                       if (!strcmp(ibv_get_device_name(ib_dev), ib_devname))
+               while (*dev_list) {
+                       if (!strcmp(ibv_get_device_name(*dev_list), ib_devname))
                                break;
-               if (!ib_dev) {
+                       ++dev_list;
+               }
+
+               if (!*dev_list) {
                        fprintf(stderr, "IB device '%s' wasn't found\n", ib_devname);
                        return -1;
                }
-               ret |= print_hca_cap(ib_dev, ib_port);
+
+               ret |= print_hca_cap(*dev_list, ib_port);
        } else {
-                ib_dev = dlist_next(dev_list);
-                if (!ib_dev) {
-                        fprintf(stderr, "No IB devices found\n");
-                        return -1;
-                }
-               ret |= print_hca_cap(ib_dev, ib_port);
+               if (!*dev_list) {
+                       fprintf(stderr, "No IB devices found\n");
+                       return -1;
+               }
+               ret |= print_hca_cap(*dev_list, ib_port);
        }
 
        if (ib_devname)
index 947ae54003facaca1045a0d3461b439298030c04..7c5e448c1a4ffcba0202dd3701abc8bfa444dec0 100644 (file)
@@ -447,7 +447,7 @@ static void usage(const char *argv0)
 
 int main(int argc, char *argv[])
 {
-       struct dlist            *dev_list;
+       struct ibv_device      **dev_list;
        struct ibv_device       *ib_dev;
        struct pingpong_context *ctx;
        struct pingpong_dest     my_dest;
@@ -536,21 +536,20 @@ int main(int argc, char *argv[])
 
        page_size = sysconf(_SC_PAGESIZE);
 
-       dev_list = ibv_get_devices();
+       dev_list = ibv_get_device_list(NULL);
        if (!dev_list) {
                fprintf(stderr, "No IB devices found\n");
                return 1;
        }
 
-       dlist_start(dev_list);
        if (!ib_devname) {
-               ib_dev = dlist_next(dev_list);
+               ib_dev = *dev_list;
                if (!ib_dev) {
                        fprintf(stderr, "No IB devices found\n");
                        return 1;
                }
        } else {
-               dlist_for_each_data(dev_list, ib_dev, struct ibv_device)
+               for (ib_dev = *dev_list; ib_dev; ++dev_list)
                        if (!strcmp(ibv_get_device_name(ib_dev), ib_devname))
                                break;
                if (!ib_dev) {
index f922be94980e31b847700efa4ad294c0ef4cdb94..8a68dd77c453c54377eb88e56da0a4137bb33cb5 100644 (file)
@@ -509,7 +509,7 @@ static void usage(const char *argv0)
 
 int main(int argc, char *argv[])
 {
-       struct dlist            *dev_list;
+       struct ibv_device      **dev_list;
        struct ibv_device       *ib_dev;
        struct pingpong_context *ctx;
        struct pingpong_dest     my_dest[MAX_QP];
@@ -605,21 +605,20 @@ int main(int argc, char *argv[])
 
        page_size = sysconf(_SC_PAGESIZE);
 
-       dev_list = ibv_get_devices();
+       dev_list = ibv_get_device_list(NULL);
        if (!dev_list) {
                fprintf(stderr, "No IB devices found\n");
                return 1;
        }
 
-       dlist_start(dev_list);
        if (!ib_devname) {
-               ib_dev = dlist_next(dev_list);
+               ib_dev = *dev_list;
                if (!ib_dev) {
                        fprintf(stderr, "No IB devices found\n");
                        return 1;
                }
        } else {
-               dlist_for_each_data(dev_list, ib_dev, struct ibv_device)
+               for (ib_dev = *dev_list; ib_dev; ++dev_list)
                        if (!strcmp(ibv_get_device_name(ib_dev), ib_devname))
                                break;
                if (!ib_dev) {
index a18cc4f7c6314dadb294d861f19e00bd0414a2d1..fdaa3cb961ee83fc78a03f8d37ebd84722a9f1f8 100644 (file)
@@ -435,7 +435,7 @@ static void usage(const char *argv0)
 
 int main(int argc, char *argv[])
 {
-       struct dlist            *dev_list;
+       struct ibv_device      **dev_list;
        struct ibv_device       *ib_dev;
        struct pingpong_context *ctx;
        struct pingpong_dest     my_dest;
@@ -524,21 +524,20 @@ int main(int argc, char *argv[])
 
        page_size = sysconf(_SC_PAGESIZE);
 
-       dev_list = ibv_get_devices();
+       dev_list = ibv_get_device_list(NULL);
        if (!dev_list) {
                fprintf(stderr, "No IB devices found\n");
                return 1;
        }
 
-       dlist_start(dev_list);
        if (!ib_devname) {
-               ib_dev = dlist_next(dev_list);
+               ib_dev = *dev_list;
                if (!ib_dev) {
                        fprintf(stderr, "No IB devices found\n");
                        return 1;
                }
        } else {
-               dlist_for_each_data(dev_list, ib_dev, struct ibv_device)
+               for (ib_dev = *dev_list; ib_dev; ++dev_list)
                        if (!strcmp(ibv_get_device_name(ib_dev), ib_devname))
                                break;
                if (!ib_dev) {
index 4fcf854f79a75a3eb7394a9d25057c995c393b6b..0ddd839ad1dc65a5eaeb1421078b9fcf1b37727d 100644 (file)
@@ -443,7 +443,7 @@ static void usage(const char *argv0)
 
 int main(int argc, char *argv[])
 {
-       struct dlist            *dev_list;
+       struct ibv_device      **dev_list;
        struct ibv_device       *ib_dev;
        struct pingpong_context *ctx;
        struct pingpong_dest     my_dest;
@@ -532,21 +532,20 @@ int main(int argc, char *argv[])
 
        page_size = sysconf(_SC_PAGESIZE);
 
-       dev_list = ibv_get_devices();
+       dev_list = ibv_get_device_list(NULL);
        if (!dev_list) {
                fprintf(stderr, "No IB devices found\n");
                return 1;
        }
 
-       dlist_start(dev_list);
        if (!ib_devname) {
-               ib_dev = dlist_next(dev_list);
+               ib_dev = *dev_list;
                if (!ib_dev) {
                        fprintf(stderr, "No IB devices found\n");
                        return 1;
                }
        } else {
-               dlist_for_each_data(dev_list, ib_dev, struct ibv_device)
+               for (ib_dev = *dev_list; ib_dev; ++dev_list)
                        if (!strcmp(ibv_get_device_name(ib_dev), ib_devname))
                                break;
                if (!ib_dev) {
index e88043ca5c435a9ba9c9cf1a4078705f9ed15b4a..cd86b2a4a9c065d20538ee73b8f232aabbfdf174 100644 (file)
@@ -585,9 +585,21 @@ struct ibv_context {
 };
 
 /**
- * ibv_get_devices - Return list of IB devices
+ * ibv_get_device_list - Get list of IB devices currently available
+ * @num_devices: optional.  if non-NULL, set to the number of devices
+ * returned in the array.
+ *
+ * Return a NULL-terminated array of IB devices.  The array can be
+ * released with ibv_free_device_list().
+ */
+extern struct ibv_device **ibv_get_device_list(int *num_devices);
+
+/**
+ * ibv_free_device_list - Free list from ibv_get_device_list()
+ *
+ * Free an array of devices returned from ibv_get_device_list()
  */
-extern struct dlist *ibv_get_devices(void);
+extern void ibv_free_device_list(struct ibv_device **list);
 
 /**
  * ibv_get_device_name - Return kernel device name
index c425b06e4aecac5a3554b2da5d3a3b721f9e712d..e31b4b7a6821d91585b1b15a75c91bd2e177c2e8 100644 (file)
 #include "ibverbs.h"
 
 static pthread_mutex_t device_list_lock = PTHREAD_MUTEX_INITIALIZER;
-static struct dlist *device_list;
+static int num_devices;
+static struct ibv_device **device_list;
 
-struct dlist *ibv_get_devices(void)
+struct ibv_device **ibv_get_device_list(int *num)
 {
-       struct dlist *l;
+       struct ibv_device **l;
+       int i;
 
        pthread_mutex_lock(&device_list_lock);
-       if (!device_list)
-               device_list = ibverbs_init();
-       l = device_list;
+
+       if (!num_devices)
+               num_devices = ibverbs_init(&device_list);
+
+       l = calloc(num_devices, sizeof (struct ibv_device *));
+       for (i = 0; i < num_devices; ++i)
+               l[i] = device_list[i];
+
        pthread_mutex_unlock(&device_list_lock);
 
+       if (num)
+               *num = l ? num_devices : 0;
+
        return l;
 }
 
+void ibv_free_device_list(struct ibv_device **list)
+{
+       free(list);
+}
+
 const char *ibv_get_device_name(struct ibv_device *device)
 {
        return device->ibdev->name;
index 96a88b3b8d22f8fd4fc2dc84cbb2aa2613295c40..2849da770b546a7ab166c74a96514788cac940d3 100644 (file)
@@ -47,7 +47,8 @@
 #define PFX            "libibverbs: "
 
 struct ibv_driver {
-       ibv_driver_init_func init_func;
+       ibv_driver_init_func    init_func;
+       struct ibv_driver      *next;
 };
 
 struct ibv_abi_compat_v2 {
@@ -57,11 +58,11 @@ struct ibv_abi_compat_v2 {
 
 extern HIDDEN int abi_ver;
 
-extern struct dlist *ibverbs_init(void);
+extern HIDDEN int ibverbs_init(struct ibv_device ***list);
 
-extern int ibv_init_mem_map(void);
-extern int ibv_lock_range(void *base, size_t size);
-extern int ibv_unlock_range(void *base, size_t size);
+extern HIDDEN int ibv_init_mem_map(void);
+extern HIDDEN int ibv_lock_range(void *base, size_t size);
+extern HIDDEN int ibv_unlock_range(void *base, size_t size);
 
 #define IBV_INIT_CMD(cmd, size, opcode)                                        \
        do {                                                            \
index f4d4fc0af2ab1aeb3dff53bd12127c511218cfa6..eb5ce1705e9d027ea9ae58a39526fa915416aad1 100644 (file)
@@ -55,7 +55,7 @@ HIDDEN int abi_ver;
 static char default_path[] = DRIVER_PATH;
 static const char *user_path;
 
-static struct dlist *driver_list;
+static struct ibv_driver *driver_list;
 
 static void load_driver(char *so_path)
 {
@@ -82,7 +82,8 @@ static void load_driver(char *so_path)
        }
 
        driver->init_func = init_func;
-       dlist_push(driver_list, driver);
+       driver->next      = driver_list;
+       driver_list       = driver;
 }
 
 static void find_drivers(char *dir)
@@ -112,8 +113,7 @@ static void find_drivers(char *dir)
                load_driver(so_glob.gl_pathv[i]);
 }
 
-static void init_drivers(struct sysfs_class_device *verbs_dev,
-                        struct dlist *device_list)
+static struct ibv_device *init_drivers(struct sysfs_class_device *verbs_dev)
 {
        struct sysfs_class_device *ib_dev; 
        struct sysfs_attribute *attr;
@@ -125,7 +125,7 @@ static void init_drivers(struct sysfs_class_device *verbs_dev,
        if (!attr) {
                fprintf(stderr, PFX "Warning: no ibdev class attr for %s\n",
                        verbs_dev->name);
-               return;
+               return NULL;
        }
 
        sscanf(attr->value, "%63s", ibdev_name);
@@ -134,19 +134,17 @@ static void init_drivers(struct sysfs_class_device *verbs_dev,
        if (!ib_dev) {
                fprintf(stderr, PFX "Warning: no infiniband class device %s for %s\n",
                        attr->value, verbs_dev->name);
-               return;
+               return NULL;
        }
 
-       dlist_for_each_data(driver_list, driver, struct ibv_driver) {
+       for (driver = driver_list; driver; driver = driver->next) {
                dev = driver->init_func(verbs_dev);
                if (dev) {
                        dev->dev    = verbs_dev;
                        dev->ibdev  = ib_dev;
                        dev->driver = driver;
 
-                       dlist_push(device_list, dev);
-
-                       return;
+                       return dev;
                }
        }
 
@@ -155,6 +153,8 @@ static void init_drivers(struct sysfs_class_device *verbs_dev,
        if (user_path)
                fprintf(stderr, "%s:", user_path);
        fprintf(stderr, "%s\n", default_path);
+
+       return NULL;
 }
 
 static int check_abi_version(void)
@@ -188,28 +188,23 @@ static int check_abi_version(void)
 }
 
 
-struct dlist *ibverbs_init(void)
+HIDDEN int ibverbs_init(struct ibv_device ***list)
 {
        char *wr_path, *dir;
        struct sysfs_class *cls;
        struct dlist *verbs_dev_list;
-       struct dlist *device_list;
        struct sysfs_class_device *verbs_dev;
+       struct ibv_device *device;
+       struct ibv_device **new_list;
+       int num_devices = 0;
+       int list_size = 0;
 
-       driver_list = dlist_new(sizeof (struct ibv_driver));
-       device_list = dlist_new(sizeof (struct ibv_device));
-       if (!driver_list || !device_list) {
-               fprintf(stderr, PFX "Fatal: couldn't allocate device/driver list.\n");
-               abort();
-       }
+       *list = NULL;
 
        if (ibv_init_mem_map())
-               return NULL;
+               return 0;
 
-       /*
-        * Check if a driver is statically linked, and if so load it first.
-        */
-       load_driver(NULL);
+       find_drivers(default_path);
 
        /*
         * Only follow the path passed in through the calling user's
@@ -224,25 +219,42 @@ struct dlist *ibverbs_init(void)
                }
        }
 
-       find_drivers(default_path);
+       /*
+        * Now check if a driver is statically linked.  Since we push
+        * drivers onto our driver list, the last driver we find will
+        * be the first one we try.
+        */
+       load_driver(NULL);
 
        cls = sysfs_open_class("infiniband_verbs");
        if (!cls) {
                fprintf(stderr, PFX "Fatal: couldn't open sysfs class 'infiniband_verbs'.\n");
-               return NULL;
+               return 0;
        }
 
        if (check_abi_version())
-               return NULL;
+               return 0;
 
        verbs_dev_list = sysfs_get_class_devices(cls);
        if (!verbs_dev_list) {
                fprintf(stderr, PFX "Fatal: no infiniband class devices found.\n");
-               return NULL;
+               return 0;
        }
 
-       dlist_for_each_data(verbs_dev_list, verbs_dev, struct sysfs_class_device)
-               init_drivers(verbs_dev, device_list);
+       dlist_for_each_data(verbs_dev_list, verbs_dev, struct sysfs_class_device) {
+               device = init_drivers(verbs_dev);
+               if (device) {
+                       if (list_size <= num_devices) {
+                               list_size = list_size ? list_size * 2 : 1;
+                               new_list = realloc(*list, list_size * sizeof (struct ibv_device *));
+                               if (!new_list)
+                                       goto out;
+                               *list = new_list;
+                       }
+                       *list[num_devices++] = device;
+               }
+       }
 
-       return device_list;
+out:
+       return num_devices;
 }
index 56314ed0fdaac9caf602b3ddd57b6843d69799f5..e72b0f93964b80ed760c55d2582bb00e7cbe235c 100644 (file)
@@ -1,6 +1,7 @@
 IBVERBS_1.0 {
        global:
-               ibv_get_devices;
+               ibv_get_device_list;
+               ibv_free_device_list;
                ibv_get_device_name;
                ibv_get_device_guid;
                ibv_open_device;