I'm not quite sure I understand the use for "enum ibv_extension_type". Where/how is this used?
Ira On Jun 3, 2011, at 5:34 PM, Hefty, Sean wrote: > In order to support OFED or vendor specific calls, define a > generic extension mechanism. This allows OFED, an RDMA vendor, > or another registered 3rd party (for example, the librdmacm) > to define RDMA extensions. > > Users which make use extensions are aware that they are not > only using an extended call, but are given information regarding > how widely the extension by be supported. Support for extended > functions, data structures, and enums are defined. > > Extensions are referenced by name. There is an assumption that > extension names are prefixed relative to the supporting party. > Until an extension has been incorporated into libibverbs, it > should be defined in an appropriate external header file. > > For example, OFA could provide a header file with their definition > for XRC extensions. A partial view of such a header file might > look something similar to: > > #ifndef OFA_XRC_H > #define OFA_XRC_H > #include <infiniband/verbs.h> > > #define OFA_XRC_OPS "ofa-xrc" > > /* Extend IBV_QP_TYPE for XRC */ > #define OFA_QPT_XRC ((enum ibv_qp_type) \ > (IBV_EXTENSION_OFA << IBV_EXTENSION_BASE_SHIFT) + 6) > > struct ofa_xrcd { > struct ibv_context *context; > }; > > struct ofa_xrc_ops { > struct ofa_xrcd * (*open_xrcd)(struct ibv_context *context, > inf fd, int oflags); > int * (*close_xrcd)(struct ofa_xrcd *xrcd); > /* other functions left as exercise to the reader */ > }; > > #endif /* OFA_XRC_H */ > > Driver libraries that support extensions are given a new > registration call, ibv_register_device_ext(). Use of this call > indicates to libibverbs that the library allocates extended > versions of struct ibv_device and struct ibv_context. > > The following new APIs are added to libibverbs to applications > to use to determine if an extension is supported and to obtain the > extended function calls. > > ibv_have_ext_ops - returns true if an extension is supported > ibv_get_device_ext_ops - return extended operations for a device > ibv_get_ext_ops - return extended operations for an open context > > To maintain backwards compatibility with existing applications, > internally, the library uses the last byte of the device name > to record if the device was registered with extension support. > > Signed-off-by: Sean Hefty <sean.he...@intel.com> > --- > Compile tested only at this point. I'm still working on writing > an XRC sample program. > > include/infiniband/driver.h | 1 + > include/infiniband/verbs.h | 40 +++++++++++++++++++++++++++++++++++++++- > src/device.c | 18 ++++++++++++++++++ > src/ibverbs.h | 18 ++++++++++++++++++ > src/init.c | 17 ++++++++++++++++- > src/libibverbs.map | 5 +++++ > src/verbs.c | 9 +++++++++ > 7 files changed, 106 insertions(+), 2 deletions(-) > > diff --git a/include/infiniband/driver.h b/include/infiniband/driver.h > index 9a81416..e48abfd 100644 > --- a/include/infiniband/driver.h > +++ b/include/infiniband/driver.h > @@ -57,6 +57,7 @@ typedef struct ibv_device *(*ibv_driver_init_func)(const > char *uverbs_sys_path, > int abi_version); > > void ibv_register_driver(const char *name, ibv_driver_init_func init_func); > +void ibv_register_driver_ext(const char *name, ibv_driver_init_func > init_func); > int ibv_cmd_get_context(struct ibv_context *context, struct ibv_get_context > *cmd, > size_t cmd_size, struct ibv_get_context_resp *resp, > size_t resp_size); > diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h > index 0f1cb2e..b82cd3a 100644 > --- a/include/infiniband/verbs.h > +++ b/include/infiniband/verbs.h > @@ -55,6 +55,15 @@ > > BEGIN_C_DECLS > > +enum ibv_extension_type { > + IBV_EXTENSION_COMMON, > + IBV_EXTENSION_VENDOR, > + IBV_EXTENSION_OFA, > + IBV_EXTENSION_RDMA_CM > +}; > +#define IBV_EXTENSION_BASE_SHIFT 24 > +#define IBV_EXTENSION_MASK 0xFF000000 > + > union ibv_gid { > uint8_t raw[16]; > struct { > @@ -92,7 +101,8 @@ enum ibv_device_cap_flags { > IBV_DEVICE_SYS_IMAGE_GUID = 1 << 11, > IBV_DEVICE_RC_RNR_NAK_GEN = 1 << 12, > IBV_DEVICE_SRQ_RESIZE = 1 << 13, > - IBV_DEVICE_N_NOTIFY_CQ = 1 << 14 > + IBV_DEVICE_N_NOTIFY_CQ = 1 << 14, > + IBV_DEVICE_EXTENSIONS = 1 << (IBV_EXTENSION_BASE_SHIFT - 1) > }; > > enum ibv_atomic_cap { > @@ -623,6 +633,13 @@ struct ibv_device { > char dev_path[IBV_SYSFS_PATH_MAX]; > /* Path to infiniband class device in sysfs */ > char ibdev_path[IBV_SYSFS_PATH_MAX]; > + > + /* Following fields only available if device supports extensions */ > + void *private; > + int (*have_ext_ops)(struct ibv_device *device, > + const char *ext_name); > + void * (*get_device_ext_ops)(struct ibv_device *device, > + const char *ext_name); > }; > > struct ibv_context_ops { > @@ -691,6 +708,11 @@ struct ibv_context { > int num_comp_vectors; > pthread_mutex_t mutex; > void *abi_compat; > + > + /* Following fields only available if device supports extensions */ > + void *private; > + void * (*get_ext_ops)(struct ibv_context *context, > + const char *ext_name); > }; > > /** > @@ -724,6 +746,17 @@ const char *ibv_get_device_name(struct ibv_device > *device); > uint64_t ibv_get_device_guid(struct ibv_device *device); > > /** > + * ibv_have_ext_ops - Return true if device supports the requested > + * extended operations. > + */ > +int ibv_have_ext_ops(struct ibv_device *device, const char *name); > + > +/** > + * ibv_get_device_ext_ops - Return extended operations. > + */ > +void *ibv_get_device_ext_ops(struct ibv_device *device, const char *name); > + > +/** > * ibv_open_device - Initialize device for use > */ > struct ibv_context *ibv_open_device(struct ibv_device *device); > @@ -734,6 +767,11 @@ struct ibv_context *ibv_open_device(struct ibv_device > *device); > int ibv_close_device(struct ibv_context *context); > > /** > + * ibv_get_ext_ops - Return extended operations. > + */ > +void *ibv_get_ext_ops(struct ibv_context *context, const char *name); > + > +/** > * ibv_get_async_event - Get next async event > * @event: Pointer to use to return async event > * > diff --git a/src/device.c b/src/device.c > index 185f4a6..78d9d35 100644 > --- a/src/device.c > +++ b/src/device.c > @@ -181,6 +181,24 @@ int __ibv_close_device(struct ibv_context *context) > } > default_symver(__ibv_close_device, ibv_close_device); > > +int __ibv_have_ext_ops(struct ibv_device *device, const char *name) > +{ > + if (!ibv_get_ext_support(device)) > + return ENOSYS; > + > + return device->have_ext_ops(device, name); > +} > +default_symver(__ibv_have_ext_ops, ibv_have_ext_ops); > + > +void *__ibv_get_device_ext_ops(struct ibv_device *device, const char *name) > +{ > + if (!ibv_get_ext_support(device) || !device->get_device_ext_ops) > + return NULL; > + > + return device->get_device_ext_ops(device, name); > +} > +default_symver(__ibv_get_device_ext_ops, ibv_get_device_ext_ops); > + > int __ibv_get_async_event(struct ibv_context *context, > struct ibv_async_event *event) > { > diff --git a/src/ibverbs.h b/src/ibverbs.h > index 6a6e3c8..33bdee2 100644 > --- a/src/ibverbs.h > +++ b/src/ibverbs.h > @@ -35,6 +35,7 @@ > #define IB_VERBS_H > > #include <pthread.h> > +#include <string.h> > > #include <infiniband/driver.h> > > @@ -102,4 +103,21 @@ HIDDEN int ibverbs_init(struct ibv_device ***list); > (cmd)->response = (uintptr_t) (out); \ > } while (0) > > +/* > + * Support for extended operations is recorded at the end of > + * the name character array. This way we don't need to query > + * for the device capabilities with every call. > + */ > +static inline int ibv_get_ext_support(struct ibv_device *device) > +{ > + return device->name[IBV_SYSFS_NAME_MAX - 1]; > +} > + > +static inline void ibv_set_ext_support(struct ibv_device *device, > + int ext_supported) > +{ > + if (strlen(device->name) < IBV_SYSFS_NAME_MAX - 1) > + device->name[IBV_SYSFS_NAME_MAX - 1] = (char) ext_supported; > +} > + > #endif /* IB_VERBS_H */ > diff --git a/src/init.c b/src/init.c > index 4f0130e..419ab31 100644 > --- a/src/init.c > +++ b/src/init.c > @@ -71,6 +71,7 @@ struct ibv_driver { > const char *name; > ibv_driver_init_func init_func; > struct ibv_driver *next; > + int ext_support; > }; > > static struct ibv_sysfs_dev *sysfs_dev_list; > @@ -153,7 +154,8 @@ static int find_sysfs_devs(void) > return ret; > } > > -void ibv_register_driver(const char *name, ibv_driver_init_func init_func) > +static void __ibv_register_driver(const char *name, ibv_driver_init_func > init_func, > + int ext_support) > { > struct ibv_driver *driver; > > @@ -166,6 +168,7 @@ void ibv_register_driver(const char *name, > ibv_driver_init_func init_func) > driver->name = name; > driver->init_func = init_func; > driver->next = NULL; > + driver->ext_support = ext_support; > > if (tail_driver) > tail_driver->next = driver; > @@ -174,6 +177,16 @@ void ibv_register_driver(const char *name, > ibv_driver_init_func init_func) > tail_driver = driver; > } > > +void ibv_register_driver(const char *name, ibv_driver_init_func init_func) > +{ > + __ibv_register_driver(name, init_func, 0); > +} > + > +void ibv_register_driver_ext(const char *name, ibv_driver_init_func > init_func) > +{ > + __ibv_register_driver(name, init_func, 1); > +} > + > static void load_driver(const char *name) > { > char *so_name; > @@ -368,6 +381,8 @@ static struct ibv_device *try_driver(struct ibv_driver > *driver, > strcpy(dev->name, sysfs_dev->ibdev_name); > strcpy(dev->ibdev_path, sysfs_dev->ibdev_path); > > + ibv_set_ext_support(dev, driver->ext_support); > + > return dev; > } > > diff --git a/src/libibverbs.map b/src/libibverbs.map > index 1827da0..422e07f 100644 > --- a/src/libibverbs.map > +++ b/src/libibverbs.map > @@ -96,4 +96,9 @@ IBVERBS_1.1 { > ibv_port_state_str; > ibv_event_type_str; > ibv_wc_status_str; > + > + ibv_register_driver_ext; > + ibv_have_ext_ops; > + ibv_get_device_ext_ops; > + ibv_get_ext_ops; > } IBVERBS_1.0; > diff --git a/src/verbs.c b/src/verbs.c > index ba3c0a4..a34a784 100644 > --- a/src/verbs.c > +++ b/src/verbs.c > @@ -76,6 +76,15 @@ enum ibv_rate mult_to_ibv_rate(int mult) > } > } > > +void *__ibv_get_ext_ops(struct ibv_context *context, const char *name) > +{ > + if (!ibv_get_ext_support(context->device) || !context->get_ext_ops) > + return NULL; > + > + return context->get_ext_ops(context, name); > +} > +default_symver(__ibv_get_ext_ops, ibv_get_ext_ops); > + > int __ibv_query_device(struct ibv_context *context, > struct ibv_device_attr *device_attr) > { > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html