@@ -120,8 +120,9 @@ uint64_t __ibv_get_device_guid(struct ibv_device *device)
}
default_symver(__ibv_get_device_guid, ibv_get_device_guid);
-struct ibv_cq_ex *__lib_ibv_create_cq_ex(struct ibv_context *context,
- struct ibv_cq_init_attr_ex *cq_attr)
+struct ibv_cq_ex *ibv_vendor_create_cq_ex(struct ibv_context *context,
+ struct ibv_cq_init_attr_ex *cq_attr,
+ void *vendor_data)
{
struct verbs_context *vctx = verbs_get_ctx(context);
struct ibv_cq_ex *cq;
@@ -133,7 +134,16 @@ struct ibv_cq_ex *__lib_ibv_create_cq_ex(struct ibv_context *context,
pthread_mutex_lock(&context->mutex);
- cq = vctx->priv->create_cq_ex(context, cq_attr);
+ if (!vendor_data) {
+ cq = vctx->priv->create_cq_ex(context, cq_attr);
+ } else {
+ if (!vctx->priv->create_cq_ex_vendor) {
+ errno = ENOSYS;
+ return NULL;
+ }
+
+ cq = vctx->priv->create_cq_ex_vendor(context, cq_attr, vendor_data);
+ }
if (cq) {
cq->context = context;
@@ -152,6 +162,12 @@ struct ibv_cq_ex *__lib_ibv_create_cq_ex(struct ibv_context *context,
return cq;
}
+struct ibv_cq_ex *__lib_ibv_create_cq_ex(struct ibv_context *context,
+ struct ibv_cq_init_attr_ex *cq_attr)
+{
+ return ibv_vendor_create_cq_ex(context, cq_attr, NULL);
+}
+
struct ibv_context *__ibv_open_device(struct ibv_device *device)
{
struct verbs_device *verbs_device = verbs_get_device(device);
@@ -46,6 +46,14 @@
# define END_C_DECLS
#endif /* __cplusplus */
+struct verbs_ex_private {
+ struct ibv_cq_ex *(*create_cq_ex)(struct ibv_context *context,
+ struct ibv_cq_init_attr_ex *init_attr);
+ struct ibv_cq_ex *(*create_cq_ex_vendor)(struct ibv_context *context,
+ struct ibv_cq_init_attr_ex *init_attr,
+ void *vendor_data);
+};
+
/*
* Extension that low-level drivers should add to their .so filename
* (probably via libtool "-release" option). For example a low-level
@@ -319,4 +327,7 @@ static inline int verbs_get_srq_num(struct ibv_srq *srq, uint32_t *srq_num)
int ibv_query_gid_type(struct ibv_context *context, uint8_t port_num,
unsigned int index, enum ibv_gid_type *type);
+struct ibv_cq_ex *ibv_vendor_create_cq_ex(struct ibv_context *context,
+ struct ibv_cq_init_attr_ex *cq_attr,
+ void *vendor_data);
#endif /* INFINIBAND_DRIVER_H */
@@ -48,7 +48,7 @@
#define default_symver(name, api) \
asm(".symver " #name "," #api "@@" DEFAULT_ABI)
#define private_symver(name, api) \
- asm(".symver " #name "," #api "@@IBVERBS_PRIVATE_13")
+ asm(".symver " #name "," #api "@@IBVERBS_PRIVATE_14")
#define PFX "libibverbs: "
@@ -61,11 +61,6 @@ extern int abi_ver;
int ibverbs_init(struct ibv_device ***list);
-struct verbs_ex_private {
- struct ibv_cq_ex *(*create_cq_ex)(struct ibv_context *context,
- struct ibv_cq_init_attr_ex *init_attr);
-};
-
#define IBV_INIT_CMD(cmd, size, opcode) \
do { \
if (abi_ver > 2) \
@@ -139,3 +139,8 @@ IBVERBS_PRIVATE_13 {
ibv_register_driver;
verbs_register_driver;
};
+
+IBVERBS_PRIVATE_14 {
+ global:
+ ibv_vendor_create_cq_ex;
+} IBVERBS_PRIVATE_13;
@@ -1505,6 +1505,10 @@ static inline struct verbs_context *verbs_get_ctx(struct ibv_context *ctx)
if (vctx && (vctx->sz >= sizeof(*vctx) - offsetof(struct verbs_context, op))) \
vctx->op = ptr; })
+#define verbs_set_ctx_private_op(_vctx, op, ptr)({ \
+ struct verbs_context *vctx = _vctx; \
+ vctx->priv->op = ptr; })
+
/**
* ibv_get_device_list - Get list of IB devices currently available
* @num_devices: optional. if non-NULL, set to the number of devices
This patch enables providers to register a private create_cq API with some private data with libibverbs. The idea is to force type checking of the private data in the provider but to share the libibverbs code (e.g. locking, reference counting) which is used by the public ibv_create_cq_ex API. As the private API is not exposed to applications they will need to link explicitly with the provider and use its direct API supplying the explicit input structure. The solution: - Provider will expose some direct API with its explicit signature to force the type checking. - Provider will register its private API with libibverbs using the priv pointer (i.e. struct verbs_ex_private). For that a new macro named verbs_set_ctx_private_op was added and the above structure was moved to drivers.h to be accessed by the providers. - Upon an application call to the provider, it will call to a new API named ibv_vendor_create_cq_ex which is exported from libibverbs only to providers (i.e. using the private section in the map file) to a create vendor cq. - libibverbs will use the registered private API to call back the provider. - Libibverbs will share the code between the public and the private calls. Signed-off-by: Yishai Hadas <yishaih@mellanox.com> --- libibverbs/device.c | 22 +++++++++++++++++++--- libibverbs/driver.h | 11 +++++++++++ libibverbs/ibverbs.h | 7 +------ libibverbs/libibverbs.map | 5 +++++ libibverbs/verbs.h | 4 ++++ 5 files changed, 40 insertions(+), 9 deletions(-)