]> git.openfabrics.org - ~shefty/libibverbs.git/commitdiff
refresh
authorSean Hefty <sean.hefty@intel.com>
Fri, 28 Sep 2012 17:41:36 +0000 (10:41 -0700)
committerSean Hefty <sean.hefty@intel.com>
Fri, 28 Sep 2012 17:41:36 +0000 (10:41 -0700)
meta
patches/refresh-temp [deleted file]
patches/srq_ex

diff --git a/meta b/meta
index f79cca2c31fcf4d3e3f23be0ef9195eb9f0f4b5a..29b8095666617814c76d9c0dc2e28e1f4cedaf23 100644 (file)
--- a/meta
+++ b/meta
@@ -1,11 +1,10 @@
 Version: 1
-Previous: 4f0cafca2f51d6bd10b0a60518f5451f75b29e83
-Head: a438216d61a184cd5a12ad5ea3da4588d5c35c4e
+Previous: 952c5e0eac7b4b521c1596d0fa320e781a4ec845
+Head: 91fdc5b4aaf078280ff31bd0cf35760a6ae5dd10
 Applied:
   verbs-ext: b1cc207d04e9df91c000aadd20d3612f3cb58552
   xrcd: f2b48b365d126d1c4bc61b3b3ea1ab9b7f2544f4
-  srq_ex: a69bc0a89969285407e4301bb674ded66e42759e
-  refresh-temp: a438216d61a184cd5a12ad5ea3da4588d5c35c4e
+  srq_ex: 91fdc5b4aaf078280ff31bd0cf35760a6ae5dd10
 Unapplied:
   xrc_qp: 41c4a902e322da2cc08caabd0ba56a1ffff4c43e
   open_qp: 02ed1a5b57528c104aefa6608f45bdf2d718ded3
diff --git a/patches/refresh-temp b/patches/refresh-temp
deleted file mode 100644 (file)
index 8f80531..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-Bottom: 261f148eb3217529a654c1d876ec3902e40bcc3d
-Top:    f12a9640338b48e3a608e0b2ec69517ecd34327e
-Author: Sean Hefty <sean.hefty@intel.com>
-Date:   2012-09-28 10:41:36 -0700
-
-Refresh of srq_ex
-
----
-
-diff --git a/include/infiniband/driver.h b/include/infiniband/driver.h
-index ce88442..05ff730 100644
---- a/include/infiniband/driver.h
-+++ b/include/infiniband/driver.h
-@@ -64,6 +64,23 @@ struct verbs_xrcd {
-       uint32_t                handle;
- };
-+enum verbs_srq_mask {
-+      VERBS_SRQ_TYPE          = 1 << 0,
-+      VERBS_SRQ_XRCD          = 1 << 1,
-+      VERBS_SRQ_CQ            = 1 << 2,
-+      VERBS_SRQ_NUM           = 1 << 3,
-+      VERBS_SRQ_RESERVED      = 1 << 4
-+};
-+
-+struct verbs_srq {
-+      struct ibv_srq          srq;
-+      uint32_t                comp_mask;
-+      enum ibv_srq_type       srq_type;
-+      struct verbs_xrcd      *xrcd;
-+      struct ibv_cq          *cq;
-+      uint32_t                srq_num;
-+};
-+
- typedef struct ibv_device *(*ibv_driver_init_func)(const char *uverbs_sys_path,
-                                                  int abi_version);
- typedef struct verbs_device *(*verbs_driver_init_func)(const char *uverbs_sys_path,
-@@ -118,6 +135,10 @@ int ibv_cmd_create_srq(struct ibv_pd *pd,
-                      struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
-                      struct ibv_create_srq *cmd, size_t cmd_size,
-                      struct ibv_create_srq_resp *resp, size_t resp_size);
-+int ibv_cmd_create_srq_ex(struct ibv_context *context,
-+                        struct verbs_srq *srq, struct ibv_srq_init_attr_ex *attr_ex,
-+                        struct ibv_create_xsrq *cmd, size_t cmd_size,
-+                        struct ibv_create_srq_resp *resp, size_t resp_size);
- int ibv_cmd_modify_srq(struct ibv_srq *srq,
-                      struct ibv_srq_attr *srq_attr,
-                      int srq_attr_mask,
-@@ -162,4 +183,10 @@ const char *ibv_get_sysfs_path(void);
- int ibv_read_sysfs_file(const char *dir, const char *file,
-                       char *buf, size_t size);
-+static inline uint32_t verbs_get_srq_num(struct ibv_srq *srq)
-+{
-+      struct verbs_srq *vsrq = container_of(srq, struct verbs_srq, srq);
-+      return (vsrq->comp_mask & VERBS_SRQ_NUM) ? vsrq->srq_num : 0;
-+}
-+
- #endif /* INFINIBAND_DRIVER_H */
-diff --git a/include/infiniband/kern-abi.h b/include/infiniband/kern-abi.h
-index d7c673f..3d72fa7 100644
---- a/include/infiniband/kern-abi.h
-+++ b/include/infiniband/kern-abi.h
-@@ -88,6 +88,7 @@ enum {
-       IB_USER_VERBS_CMD_POST_SRQ_RECV,
-       IB_USER_VERBS_CMD_OPEN_XRCD,
-       IB_USER_VERBS_CMD_CLOSE_XRCD,
-+      IB_USER_VERBS_CMD_CREATE_XSRQ
- };
- /*
-@@ -730,11 +731,28 @@ struct ibv_create_srq {
-       __u64 driver_data[0];
- };
-+struct ibv_create_xsrq {
-+      __u32 command;
-+      __u16 in_words;
-+      __u16 out_words;
-+      __u64 response;
-+      __u64 user_handle;
-+      __u32 srq_type;
-+      __u32 pd_handle;
-+      __u32 max_wr;
-+      __u32 max_sge;
-+      __u32 srq_limit;
-+      __u32 reserved;
-+      __u32 xrcd_handle;
-+      __u32 cq_handle;
-+      __u64 driver_data[0];
-+};
-+
- struct ibv_create_srq_resp {
-       __u32 srq_handle;
-       __u32 max_wr;
-       __u32 max_sge;
--      __u32 reserved;
-+      __u32 srqn;
- };
- struct ibv_modify_srq {
-@@ -829,6 +847,7 @@ enum {
-       IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL_V2 = -1,
-       IB_USER_VERBS_CMD_OPEN_XRCD_V2 = -1,
-       IB_USER_VERBS_CMD_CLOSE_XRCD_V2 = -1,
-+      IB_USER_VERBS_CMD_CREATE_XSRQ_V2 = -1
- };
- struct ibv_destroy_cq_v1 {
-diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h
-index 7e32e64..6465aae 100644
---- a/include/infiniband/verbs.h
-+++ b/include/infiniband/verbs.h
-@@ -420,6 +420,30 @@ struct ibv_srq_init_attr {
-       struct ibv_srq_attr attr;
- };
-+enum ibv_srq_type {
-+      IBV_SRQT_BASIC,
-+      IBV_SRQT_XRC
-+};
-+
-+enum ibv_srq_init_attr_mask {
-+      IBV_SRQ_INIT_ATTR_TYPE          = 1 << 0,
-+      IBV_SRQ_INIT_ATTR_PD            = 1 << 1,
-+      IBV_SRQ_INIT_ATTR_XRCD          = 1 << 2,
-+      IBV_SRQ_INIT_ATTR_CQ            = 1 << 3,
-+      IBV_SRQ_INIT_ATTR_RESERVED      = 1 << 4
-+};
-+
-+struct ibv_srq_init_attr_ex {
-+      void                   *srq_context;
-+      struct ibv_srq_attr     attr;
-+
-+      uint32_t                comp_mask;
-+      enum ibv_srq_type       srq_type;
-+      struct ibv_pd          *pd;
-+      struct ibv_xrcd        *xrcd;
-+      struct ibv_cq          *cq;
-+};
-+
- enum ibv_qp_type {
-       IBV_QPT_RC = 2, IBV_QPT_UC, IBV_QPT_UD
- };
-@@ -730,21 +754,28 @@ struct ibv_context {
- enum verbs_context_mask {
-       VERBS_CONTEXT_XRCD      = 1 << 0,
--      VERBS_CONTEXT_RESERVED  = 1 << 1
-+      VERBS_CONTEXT_SRQ       = 1 << 1,
-+      VERBS_CONTEXT_RESERVED  = 1 << 2
- };
- struct verbs_context {
-       /*  "grows up" - new fields go here
--       int (*drv_new_func1) ();       new corresponding provider call of func1
--       int (*lib_new_func1) ();       New library call func1
--       */
-+      int (*drv_new_func1) ();        new corresponding provider call of func1
-+      int (*lib_new_func1) ();        New library call func1
-+      */
-+      uint32_t                (*get_srq_num)(struct ibv_srq *srq);
-+      struct ibv_srq *        (*create_srq_ex)(struct ibv_context *context,
-+                                               struct ibv_srq_init_attr_ex *srq_init_attr_ex);
-+      struct ibv_xrcd *       (*open_xrcd)(struct ibv_context *context,
-+                                           int fd, int oflags);
-+      int                     (*close_xrcd)(struct ibv_xrcd *xrcd);
-       struct ibv_xrcd * (*open_xrcd)(struct ibv_context *context,
-                                      struct ibv_xrcd_init_attr *xrcd_init_attr);
-       int (*close_xrcd)(struct ibv_xrcd *xrcd);
-       uint64_t has_comp_mask;
--      size_t sz; /* Set by library on struct allocation,must be
--       * located right before struct ibv_context
--       */
-+      size_t sz;      /* Set by library on struct allocation,must be
-+                      * located right before struct ibv_context
-+                      */
-       struct ibv_context context;/* Must be last field in the struct */
- };
-@@ -1014,6 +1045,27 @@ static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only) {
- struct ibv_srq *ibv_create_srq(struct ibv_pd *pd,
-               struct ibv_srq_init_attr *srq_init_attr);
-+static inline struct ibv_srq *
-+ibv_create_srq_ex(struct ibv_context *context,
-+                struct ibv_srq_init_attr_ex *srq_init_attr_ex)
-+{
-+      struct verbs_context *vctx;
-+      uint32_t mask = srq_init_attr_ex->comp_mask;
-+
-+      if (!(mask & ~(IBV_SRQ_INIT_ATTR_PD | IBV_SRQ_INIT_ATTR_TYPE)) &&
-+          (mask & IBV_SRQ_INIT_ATTR_PD) &&
-+          (!(mask & IBV_SRQ_INIT_ATTR_TYPE) ||
-+           (srq_init_attr_ex->srq_type == IBV_SRQT_BASIC)))
-+              return ibv_create_srq(srq_init_attr_ex->pd,
-+                                    (struct ibv_srq_init_attr *) srq_init_attr_ex);
-+
-+      if (!(vctx = verbs_get_ctx_op(context, create_srq_ex))) {
-+              errno = ENOSYS;
-+              return NULL;
-+      }
-+      return vctx->create_srq_ex(context, srq_init_attr_ex);
-+}
-+
- /**
-  * ibv_modify_srq - Modifies the attributes for the specified SRQ.
-  * @srq: The SRQ to modify.
-@@ -1037,6 +1089,16 @@ int ibv_modify_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr,
-  */
- int ibv_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr);
-+static inline uint32_t ibv_get_srq_num(struct ibv_srq *srq)
-+{
-+      struct verbs_context *vctx = verbs_get_ctx_op(srq->context, get_srq_num);
-+      if (!vctx) {
-+              errno = ENOSYS;
-+              return 0;
-+      }
-+      return vctx->get_srq_num(srq);
-+}
-+
- /**
-  * ibv_destroy_srq - Destroys the specified SRQ.
-  * @srq: The SRQ to destroy.
-diff --git a/src/cmd.c b/src/cmd.c
-index f0fb1dc..641ab28 100644
---- a/src/cmd.c
-+++ b/src/cmd.c
-@@ -488,6 +488,75 @@ int ibv_cmd_create_srq(struct ibv_pd *pd,
-       return 0;
- }
-+int ibv_cmd_create_srq_ex(struct ibv_context *context,
-+                        struct verbs_srq *srq, struct ibv_srq_init_attr_ex *attr_ex,
-+                        struct ibv_create_xsrq *cmd, size_t cmd_size,
-+                        struct ibv_create_srq_resp *resp, size_t resp_size)
-+{
-+      struct verbs_xrcd *vxrcd = NULL;
-+
-+      IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_XSRQ, resp, resp_size);
-+
-+      if (attr_ex->comp_mask >= IBV_SRQ_INIT_ATTR_RESERVED)
-+              return ENOSYS;
-+
-+      if (!(attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_PD))
-+              return EINVAL;
-+
-+      cmd->user_handle = (uintptr_t) srq;
-+      cmd->pd_handle   = attr_ex->pd->handle;
-+      cmd->max_wr      = attr_ex->attr.max_wr;
-+      cmd->max_sge     = attr_ex->attr.max_sge;
-+      cmd->srq_limit   = attr_ex->attr.srq_limit;
-+
-+      cmd->srq_type = (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_TYPE) ?
-+                      attr_ex->srq_type : IBV_SRQT_BASIC;
-+      if (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_XRCD) {
-+              if (!(attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_XRCD) ||
-+                  !(attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_CQ))
-+                      return EINVAL;
-+
-+              vxrcd = container_of(attr_ex->xrcd, struct verbs_xrcd, xrcd);
-+              cmd->xrcd_handle = vxrcd->handle;
-+              cmd->cq_handle   = attr_ex->cq->handle;
-+      }
-+
-+      if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
-+              return errno;
-+
-+      VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
-+
-+      srq->srq.handle           = resp->srq_handle;
-+      srq->srq.context          = context;
-+      srq->srq.srq_context      = attr_ex->srq_context;
-+      srq->srq.pd               = attr_ex->pd;
-+      srq->srq.events_completed = 0;
-+      pthread_mutex_init(&srq->srq.mutex, NULL);
-+      pthread_cond_init(&srq->srq.cond, NULL);
-+
-+      srq->comp_mask = IBV_SRQ_INIT_ATTR_TYPE;
-+      srq->srq_type = (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_TYPE) ?
-+                      attr_ex->srq_type : IBV_SRQT_BASIC;
-+      if (srq->srq_type == IBV_SRQT_XRC) {
-+              srq->comp_mask |= VERBS_SRQ_NUM;
-+              srq->srq_num = resp->srqn;
-+      }
-+      if (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_XRCD) {
-+              srq->comp_mask |= VERBS_SRQ_XRCD;
-+              srq->xrcd = vxrcd;
-+      }
-+      if (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_CQ) {
-+              srq->comp_mask |= VERBS_SRQ_CQ;
-+              srq->cq = attr_ex->cq;
-+      }
-+
-+      attr_ex->attr.max_wr = resp->max_wr;
-+      attr_ex->attr.max_sge = resp->max_sge;
-+
-+      return 0;
-+}
-+
-+
- static int ibv_cmd_modify_srq_v3(struct ibv_srq *srq,
-                                struct ibv_srq_attr *srq_attr,
-                                int srq_attr_mask,
-diff --git a/src/libibverbs.map b/src/libibverbs.map
-index 9a15f3f..c8ec645 100644
---- a/src/libibverbs.map
-+++ b/src/libibverbs.map
-@@ -100,5 +100,6 @@ IBVERBS_1.1 {
-               
-               ibv_cmd_open_xrcd;
-               ibv_cmd_close_xrcd;
-+              ibv_cmd_create_srq_ex;
-               
- } IBVERBS_1.0;
index 982b672ab16066750e8b4bb0fdc48fc2a1815ae3..87856eea94fc130594d7449316fb0224e84f300f 100644 (file)
@@ -1,5 +1,5 @@
 Bottom: 261f148eb3217529a654c1d876ec3902e40bcc3d
-Top:    261f148eb3217529a654c1d876ec3902e40bcc3d
+Top:    f12a9640338b48e3a608e0b2ec69517ecd34327e
 Author: Sean Hefty <sean.hefty@intel.com>
 Date:   2012-09-17 12:34:55 -0700
 
@@ -22,4 +22,310 @@ Signed-off-by: Sean Hefty <sean.hefty@intel.com>
 
 ---
 
-
+diff --git a/include/infiniband/driver.h b/include/infiniband/driver.h
+index ce88442..05ff730 100644
+--- a/include/infiniband/driver.h
++++ b/include/infiniband/driver.h
+@@ -64,6 +64,23 @@ struct verbs_xrcd {
+       uint32_t                handle;
+ };
++enum verbs_srq_mask {
++      VERBS_SRQ_TYPE          = 1 << 0,
++      VERBS_SRQ_XRCD          = 1 << 1,
++      VERBS_SRQ_CQ            = 1 << 2,
++      VERBS_SRQ_NUM           = 1 << 3,
++      VERBS_SRQ_RESERVED      = 1 << 4
++};
++
++struct verbs_srq {
++      struct ibv_srq          srq;
++      uint32_t                comp_mask;
++      enum ibv_srq_type       srq_type;
++      struct verbs_xrcd      *xrcd;
++      struct ibv_cq          *cq;
++      uint32_t                srq_num;
++};
++
+ typedef struct ibv_device *(*ibv_driver_init_func)(const char *uverbs_sys_path,
+                                                  int abi_version);
+ typedef struct verbs_device *(*verbs_driver_init_func)(const char *uverbs_sys_path,
+@@ -118,6 +135,10 @@ int ibv_cmd_create_srq(struct ibv_pd *pd,
+                      struct ibv_srq *srq, struct ibv_srq_init_attr *attr,
+                      struct ibv_create_srq *cmd, size_t cmd_size,
+                      struct ibv_create_srq_resp *resp, size_t resp_size);
++int ibv_cmd_create_srq_ex(struct ibv_context *context,
++                        struct verbs_srq *srq, struct ibv_srq_init_attr_ex *attr_ex,
++                        struct ibv_create_xsrq *cmd, size_t cmd_size,
++                        struct ibv_create_srq_resp *resp, size_t resp_size);
+ int ibv_cmd_modify_srq(struct ibv_srq *srq,
+                      struct ibv_srq_attr *srq_attr,
+                      int srq_attr_mask,
+@@ -162,4 +183,10 @@ const char *ibv_get_sysfs_path(void);
+ int ibv_read_sysfs_file(const char *dir, const char *file,
+                       char *buf, size_t size);
++static inline uint32_t verbs_get_srq_num(struct ibv_srq *srq)
++{
++      struct verbs_srq *vsrq = container_of(srq, struct verbs_srq, srq);
++      return (vsrq->comp_mask & VERBS_SRQ_NUM) ? vsrq->srq_num : 0;
++}
++
+ #endif /* INFINIBAND_DRIVER_H */
+diff --git a/include/infiniband/kern-abi.h b/include/infiniband/kern-abi.h
+index d7c673f..3d72fa7 100644
+--- a/include/infiniband/kern-abi.h
++++ b/include/infiniband/kern-abi.h
+@@ -88,6 +88,7 @@ enum {
+       IB_USER_VERBS_CMD_POST_SRQ_RECV,
+       IB_USER_VERBS_CMD_OPEN_XRCD,
+       IB_USER_VERBS_CMD_CLOSE_XRCD,
++      IB_USER_VERBS_CMD_CREATE_XSRQ
+ };
+ /*
+@@ -730,11 +731,28 @@ struct ibv_create_srq {
+       __u64 driver_data[0];
+ };
++struct ibv_create_xsrq {
++      __u32 command;
++      __u16 in_words;
++      __u16 out_words;
++      __u64 response;
++      __u64 user_handle;
++      __u32 srq_type;
++      __u32 pd_handle;
++      __u32 max_wr;
++      __u32 max_sge;
++      __u32 srq_limit;
++      __u32 reserved;
++      __u32 xrcd_handle;
++      __u32 cq_handle;
++      __u64 driver_data[0];
++};
++
+ struct ibv_create_srq_resp {
+       __u32 srq_handle;
+       __u32 max_wr;
+       __u32 max_sge;
+-      __u32 reserved;
++      __u32 srqn;
+ };
+ struct ibv_modify_srq {
+@@ -829,6 +847,7 @@ enum {
+       IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL_V2 = -1,
+       IB_USER_VERBS_CMD_OPEN_XRCD_V2 = -1,
+       IB_USER_VERBS_CMD_CLOSE_XRCD_V2 = -1,
++      IB_USER_VERBS_CMD_CREATE_XSRQ_V2 = -1
+ };
+ struct ibv_destroy_cq_v1 {
+diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h
+index 7e32e64..6465aae 100644
+--- a/include/infiniband/verbs.h
++++ b/include/infiniband/verbs.h
+@@ -420,6 +420,30 @@ struct ibv_srq_init_attr {
+       struct ibv_srq_attr attr;
+ };
++enum ibv_srq_type {
++      IBV_SRQT_BASIC,
++      IBV_SRQT_XRC
++};
++
++enum ibv_srq_init_attr_mask {
++      IBV_SRQ_INIT_ATTR_TYPE          = 1 << 0,
++      IBV_SRQ_INIT_ATTR_PD            = 1 << 1,
++      IBV_SRQ_INIT_ATTR_XRCD          = 1 << 2,
++      IBV_SRQ_INIT_ATTR_CQ            = 1 << 3,
++      IBV_SRQ_INIT_ATTR_RESERVED      = 1 << 4
++};
++
++struct ibv_srq_init_attr_ex {
++      void                   *srq_context;
++      struct ibv_srq_attr     attr;
++
++      uint32_t                comp_mask;
++      enum ibv_srq_type       srq_type;
++      struct ibv_pd          *pd;
++      struct ibv_xrcd        *xrcd;
++      struct ibv_cq          *cq;
++};
++
+ enum ibv_qp_type {
+       IBV_QPT_RC = 2, IBV_QPT_UC, IBV_QPT_UD
+ };
+@@ -730,21 +754,28 @@ struct ibv_context {
+ enum verbs_context_mask {
+       VERBS_CONTEXT_XRCD      = 1 << 0,
+-      VERBS_CONTEXT_RESERVED  = 1 << 1
++      VERBS_CONTEXT_SRQ       = 1 << 1,
++      VERBS_CONTEXT_RESERVED  = 1 << 2
+ };
+ struct verbs_context {
+       /*  "grows up" - new fields go here
+-       int (*drv_new_func1) ();       new corresponding provider call of func1
+-       int (*lib_new_func1) ();       New library call func1
+-       */
++      int (*drv_new_func1) ();        new corresponding provider call of func1
++      int (*lib_new_func1) ();        New library call func1
++      */
++      uint32_t                (*get_srq_num)(struct ibv_srq *srq);
++      struct ibv_srq *        (*create_srq_ex)(struct ibv_context *context,
++                                               struct ibv_srq_init_attr_ex *srq_init_attr_ex);
++      struct ibv_xrcd *       (*open_xrcd)(struct ibv_context *context,
++                                           int fd, int oflags);
++      int                     (*close_xrcd)(struct ibv_xrcd *xrcd);
+       struct ibv_xrcd * (*open_xrcd)(struct ibv_context *context,
+                                      struct ibv_xrcd_init_attr *xrcd_init_attr);
+       int (*close_xrcd)(struct ibv_xrcd *xrcd);
+       uint64_t has_comp_mask;
+-      size_t sz; /* Set by library on struct allocation,must be
+-       * located right before struct ibv_context
+-       */
++      size_t sz;      /* Set by library on struct allocation,must be
++                      * located right before struct ibv_context
++                      */
+       struct ibv_context context;/* Must be last field in the struct */
+ };
+@@ -1014,6 +1045,27 @@ static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only) {
+ struct ibv_srq *ibv_create_srq(struct ibv_pd *pd,
+               struct ibv_srq_init_attr *srq_init_attr);
++static inline struct ibv_srq *
++ibv_create_srq_ex(struct ibv_context *context,
++                struct ibv_srq_init_attr_ex *srq_init_attr_ex)
++{
++      struct verbs_context *vctx;
++      uint32_t mask = srq_init_attr_ex->comp_mask;
++
++      if (!(mask & ~(IBV_SRQ_INIT_ATTR_PD | IBV_SRQ_INIT_ATTR_TYPE)) &&
++          (mask & IBV_SRQ_INIT_ATTR_PD) &&
++          (!(mask & IBV_SRQ_INIT_ATTR_TYPE) ||
++           (srq_init_attr_ex->srq_type == IBV_SRQT_BASIC)))
++              return ibv_create_srq(srq_init_attr_ex->pd,
++                                    (struct ibv_srq_init_attr *) srq_init_attr_ex);
++
++      if (!(vctx = verbs_get_ctx_op(context, create_srq_ex))) {
++              errno = ENOSYS;
++              return NULL;
++      }
++      return vctx->create_srq_ex(context, srq_init_attr_ex);
++}
++
+ /**
+  * ibv_modify_srq - Modifies the attributes for the specified SRQ.
+  * @srq: The SRQ to modify.
+@@ -1037,6 +1089,16 @@ int ibv_modify_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr,
+  */
+ int ibv_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr);
++static inline uint32_t ibv_get_srq_num(struct ibv_srq *srq)
++{
++      struct verbs_context *vctx = verbs_get_ctx_op(srq->context, get_srq_num);
++      if (!vctx) {
++              errno = ENOSYS;
++              return 0;
++      }
++      return vctx->get_srq_num(srq);
++}
++
+ /**
+  * ibv_destroy_srq - Destroys the specified SRQ.
+  * @srq: The SRQ to destroy.
+diff --git a/src/cmd.c b/src/cmd.c
+index f0fb1dc..641ab28 100644
+--- a/src/cmd.c
++++ b/src/cmd.c
+@@ -488,6 +488,75 @@ int ibv_cmd_create_srq(struct ibv_pd *pd,
+       return 0;
+ }
++int ibv_cmd_create_srq_ex(struct ibv_context *context,
++                        struct verbs_srq *srq, struct ibv_srq_init_attr_ex *attr_ex,
++                        struct ibv_create_xsrq *cmd, size_t cmd_size,
++                        struct ibv_create_srq_resp *resp, size_t resp_size)
++{
++      struct verbs_xrcd *vxrcd = NULL;
++
++      IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_XSRQ, resp, resp_size);
++
++      if (attr_ex->comp_mask >= IBV_SRQ_INIT_ATTR_RESERVED)
++              return ENOSYS;
++
++      if (!(attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_PD))
++              return EINVAL;
++
++      cmd->user_handle = (uintptr_t) srq;
++      cmd->pd_handle   = attr_ex->pd->handle;
++      cmd->max_wr      = attr_ex->attr.max_wr;
++      cmd->max_sge     = attr_ex->attr.max_sge;
++      cmd->srq_limit   = attr_ex->attr.srq_limit;
++
++      cmd->srq_type = (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_TYPE) ?
++                      attr_ex->srq_type : IBV_SRQT_BASIC;
++      if (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_XRCD) {
++              if (!(attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_XRCD) ||
++                  !(attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_CQ))
++                      return EINVAL;
++
++              vxrcd = container_of(attr_ex->xrcd, struct verbs_xrcd, xrcd);
++              cmd->xrcd_handle = vxrcd->handle;
++              cmd->cq_handle   = attr_ex->cq->handle;
++      }
++
++      if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
++              return errno;
++
++      VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
++
++      srq->srq.handle           = resp->srq_handle;
++      srq->srq.context          = context;
++      srq->srq.srq_context      = attr_ex->srq_context;
++      srq->srq.pd               = attr_ex->pd;
++      srq->srq.events_completed = 0;
++      pthread_mutex_init(&srq->srq.mutex, NULL);
++      pthread_cond_init(&srq->srq.cond, NULL);
++
++      srq->comp_mask = IBV_SRQ_INIT_ATTR_TYPE;
++      srq->srq_type = (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_TYPE) ?
++                      attr_ex->srq_type : IBV_SRQT_BASIC;
++      if (srq->srq_type == IBV_SRQT_XRC) {
++              srq->comp_mask |= VERBS_SRQ_NUM;
++              srq->srq_num = resp->srqn;
++      }
++      if (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_XRCD) {
++              srq->comp_mask |= VERBS_SRQ_XRCD;
++              srq->xrcd = vxrcd;
++      }
++      if (attr_ex->comp_mask & IBV_SRQ_INIT_ATTR_CQ) {
++              srq->comp_mask |= VERBS_SRQ_CQ;
++              srq->cq = attr_ex->cq;
++      }
++
++      attr_ex->attr.max_wr = resp->max_wr;
++      attr_ex->attr.max_sge = resp->max_sge;
++
++      return 0;
++}
++
++
+ static int ibv_cmd_modify_srq_v3(struct ibv_srq *srq,
+                                struct ibv_srq_attr *srq_attr,
+                                int srq_attr_mask,
+diff --git a/src/libibverbs.map b/src/libibverbs.map
+index 9a15f3f..c8ec645 100644
+--- a/src/libibverbs.map
++++ b/src/libibverbs.map
+@@ -100,5 +100,6 @@ IBVERBS_1.1 {
+               
+               ibv_cmd_open_xrcd;
+               ibv_cmd_close_xrcd;
++              ibv_cmd_create_srq_ex;
+               
+ } IBVERBS_1.0;