From: Sean Hefty Date: Fri, 28 Sep 2012 17:36:41 +0000 (-0700) Subject: refresh X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=d4181d561f06d8e9576ee68044de98d1afbd90d3;p=~shefty%2Flibibverbs.git refresh --- diff --git a/meta b/meta index f2334ce..955459a 100644 --- a/meta +++ b/meta @@ -1,10 +1,9 @@ Version: 1 -Previous: ddec78af9efabfbf3ebf75e9692de414d8be11fb -Head: 3595cafbfad1312c07b91d0ca980cace5ea38e34 +Previous: b244ffff5544d968a0add7dadc8f7f6fed8d79d1 +Head: f2b48b365d126d1c4bc61b3b3ea1ab9b7f2544f4 Applied: verbs-ext: b1cc207d04e9df91c000aadd20d3612f3cb58552 - xrcd: 6c21151cd85b48c75ab2dfe6f7c5cee59e5be3dc - refresh-temp: 3595cafbfad1312c07b91d0ca980cace5ea38e34 + xrcd: f2b48b365d126d1c4bc61b3b3ea1ab9b7f2544f4 Unapplied: srq_ex: 404e74c3eec99818cf38bff5f2534dc48ad56627 xrc_qp: 41c4a902e322da2cc08caabd0ba56a1ffff4c43e diff --git a/patches/refresh-temp b/patches/refresh-temp deleted file mode 100644 index d2cdd4b..0000000 --- a/patches/refresh-temp +++ /dev/null @@ -1,1467 +0,0 @@ -Bottom: ff25a98f5caa5889dfa52d7e2a6a9aa3e69b3ee5 -Top: 261f148eb3217529a654c1d876ec3902e40bcc3d -Author: Sean Hefty -Date: 2012-09-28 10:36:41 -0700 - -Refresh of xrcd - ---- - -diff --git a/include/infiniband/driver.h b/include/infiniband/driver.h -index f22f287..ce88442 100644 ---- a/include/infiniband/driver.h -+++ b/include/infiniband/driver.h -@@ -53,6 +53,17 @@ - */ - #define IBV_DEVICE_LIBRARY_EXTENSION rdmav2 - -+enum verbs_xrcd_mask { -+ VERBS_XRCD_HANDLE = 1 << 0, -+ VERBS_XRCD_RESERVED = 1 << 1 -+}; -+ -+struct verbs_xrcd { -+ struct ibv_xrcd xrcd; -+ uint64_t comp_mask; -+ uint32_t handle; -+}; -+ - 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, -@@ -78,6 +89,11 @@ int ibv_cmd_alloc_pd(struct ibv_context *context, struct ibv_pd *pd, - struct ibv_alloc_pd *cmd, size_t cmd_size, - struct ibv_alloc_pd_resp *resp, size_t resp_size); - int ibv_cmd_dealloc_pd(struct ibv_pd *pd); -+int ibv_cmd_open_xrcd(struct ibv_context *context, struct verbs_xrcd *xrcd, -+ struct ibv_xrcd_init_attr *attr, -+ struct ibv_open_xrcd *cmd, size_t cmd_size, -+ struct ibv_open_xrcd_resp *resp, size_t resp_size); -+int ibv_cmd_close_xrcd(struct verbs_xrcd *xrcd); - #define IBV_CMD_REG_MR_HAS_RESP_PARAMS - int ibv_cmd_reg_mr(struct ibv_pd *pd, void *addr, size_t length, - uint64_t hca_va, int access, -diff --git a/include/infiniband/kern-abi.h b/include/infiniband/kern-abi.h -index 619ea7e..d7c673f 100644 ---- a/include/infiniband/kern-abi.h -+++ b/include/infiniband/kern-abi.h -@@ -85,7 +85,9 @@ enum { - IB_USER_VERBS_CMD_MODIFY_SRQ, - IB_USER_VERBS_CMD_QUERY_SRQ, - IB_USER_VERBS_CMD_DESTROY_SRQ, -- IB_USER_VERBS_CMD_POST_SRQ_RECV -+ IB_USER_VERBS_CMD_POST_SRQ_RECV, -+ IB_USER_VERBS_CMD_OPEN_XRCD, -+ IB_USER_VERBS_CMD_CLOSE_XRCD, - }; - - /* -@@ -246,6 +248,27 @@ struct ibv_dealloc_pd { - __u32 pd_handle; - }; - -+struct ibv_open_xrcd { -+ __u32 command; -+ __u16 in_words; -+ __u16 out_words; -+ __u64 response; -+ __u32 fd; -+ __u32 oflags; -+ __u64 driver_data[0]; -+}; -+ -+struct ibv_open_xrcd_resp { -+ __u32 xrcd_handle; -+}; -+ -+struct ibv_close_xrcd { -+ __u32 command; -+ __u16 in_words; -+ __u16 out_words; -+ __u32 xrcd_handle; -+}; -+ - struct ibv_reg_mr { - __u32 command; - __u16 in_words; -@@ -804,6 +827,8 @@ enum { - * trick opcodes in IBV_INIT_CMD() doesn't break. - */ - 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, - }; - - struct ibv_destroy_cq_v1 { -diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h -index d944680..7e32e64 100644 ---- a/include/infiniband/verbs.h -+++ b/include/infiniband/verbs.h -@@ -1,6 +1,6 @@ - /* - * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. -- * Copyright (c) 2004 Intel Corporation. All rights reserved. -+ * Copyright (c) 2004, 2011-2012 Intel Corporation. All rights reserved. - * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2005 PathScale, Inc. All rights reserved. - * -@@ -39,6 +39,7 @@ - #include - #include - #include -+#include - - #ifdef __cplusplus - # define BEGIN_C_DECLS extern "C" { -@@ -57,20 +58,20 @@ - BEGIN_C_DECLS - - union ibv_gid { -- uint8_t raw[16]; -+ uint8_t raw[16]; - struct { -- uint64_t subnet_prefix; -- uint64_t interface_id; -+ uint64_t subnet_prefix; -+ uint64_t interface_id; - } global; - }; - - #ifndef container_of - /** -- * container_of - cast a member of a structure out to the containing structure -- * @ptr: the pointer to the member. -- * @type: the type of the container struct this is embedded in. -- * @member: the name of the member within the struct. -- * -+ * container_of - cast a member of a structure out to the containing structure -+ * @ptr: the pointer to the member. -+ * @type: the type of the container struct this is embedded in. -+ * @member: the name of the member within the struct. -+ * - */ - #define container_of(ptr, type, member) ({\ - const typeof(((type *)0)->member) * __mptr = (ptr);\ -@@ -78,101 +79,97 @@ union ibv_gid { - #endif - - enum ibv_node_type { -- IBV_NODE_UNKNOWN = -1, -- IBV_NODE_CA = 1, -+ IBV_NODE_UNKNOWN = -1, -+ IBV_NODE_CA = 1, - IBV_NODE_SWITCH, - IBV_NODE_ROUTER, - IBV_NODE_RNIC - }; - - enum ibv_transport_type { -- IBV_TRANSPORT_UNKNOWN = -1, -- IBV_TRANSPORT_IB = 0, -- IBV_TRANSPORT_IWARP -+ IBV_TRANSPORT_UNKNOWN = -1, IBV_TRANSPORT_IB = 0, IBV_TRANSPORT_IWARP - }; - - enum ibv_device_cap_flags { -- IBV_DEVICE_RESIZE_MAX_WR = 1, -- IBV_DEVICE_BAD_PKEY_CNTR = 1 << 1, -- IBV_DEVICE_BAD_QKEY_CNTR = 1 << 2, -- IBV_DEVICE_RAW_MULTI = 1 << 3, -- IBV_DEVICE_AUTO_PATH_MIG = 1 << 4, -- IBV_DEVICE_CHANGE_PHY_PORT = 1 << 5, -- IBV_DEVICE_UD_AV_PORT_ENFORCE = 1 << 6, -- IBV_DEVICE_CURR_QP_STATE_MOD = 1 << 7, -- IBV_DEVICE_SHUTDOWN_PORT = 1 << 8, -- IBV_DEVICE_INIT_TYPE = 1 << 9, -- IBV_DEVICE_PORT_ACTIVE_EVENT = 1 << 10, -- 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_RESIZE_MAX_WR = 1, -+ IBV_DEVICE_BAD_PKEY_CNTR = 1 << 1, -+ IBV_DEVICE_BAD_QKEY_CNTR = 1 << 2, -+ IBV_DEVICE_RAW_MULTI = 1 << 3, -+ IBV_DEVICE_AUTO_PATH_MIG = 1 << 4, -+ IBV_DEVICE_CHANGE_PHY_PORT = 1 << 5, -+ IBV_DEVICE_UD_AV_PORT_ENFORCE = 1 << 6, -+ IBV_DEVICE_CURR_QP_STATE_MOD = 1 << 7, -+ IBV_DEVICE_SHUTDOWN_PORT = 1 << 8, -+ IBV_DEVICE_INIT_TYPE = 1 << 9, -+ IBV_DEVICE_PORT_ACTIVE_EVENT = 1 << 10, -+ 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 - }; - - enum ibv_atomic_cap { -- IBV_ATOMIC_NONE, -- IBV_ATOMIC_HCA, -- IBV_ATOMIC_GLOB -+ IBV_ATOMIC_NONE, IBV_ATOMIC_HCA, IBV_ATOMIC_GLOB - }; - - struct ibv_device_attr { -- char fw_ver[64]; -- uint64_t node_guid; -- uint64_t sys_image_guid; -- uint64_t max_mr_size; -- uint64_t page_size_cap; -- uint32_t vendor_id; -- uint32_t vendor_part_id; -- uint32_t hw_ver; -- int max_qp; -- int max_qp_wr; -- int device_cap_flags; -- int max_sge; -- int max_sge_rd; -- int max_cq; -- int max_cqe; -- int max_mr; -- int max_pd; -- int max_qp_rd_atom; -- int max_ee_rd_atom; -- int max_res_rd_atom; -- int max_qp_init_rd_atom; -- int max_ee_init_rd_atom; -- enum ibv_atomic_cap atomic_cap; -- int max_ee; -- int max_rdd; -- int max_mw; -- int max_raw_ipv6_qp; -- int max_raw_ethy_qp; -- int max_mcast_grp; -- int max_mcast_qp_attach; -- int max_total_mcast_qp_attach; -- int max_ah; -- int max_fmr; -- int max_map_per_fmr; -- int max_srq; -- int max_srq_wr; -- int max_srq_sge; -- uint16_t max_pkeys; -- uint8_t local_ca_ack_delay; -- uint8_t phys_port_cnt; -+ char fw_ver[64]; -+ uint64_t node_guid; -+ uint64_t sys_image_guid; -+ uint64_t max_mr_size; -+ uint64_t page_size_cap; -+ uint32_t vendor_id; -+ uint32_t vendor_part_id; -+ uint32_t hw_ver; -+ int max_qp; -+ int max_qp_wr; -+ int device_cap_flags; -+ int max_sge; -+ int max_sge_rd; -+ int max_cq; -+ int max_cqe; -+ int max_mr; -+ int max_pd; -+ int max_qp_rd_atom; -+ int max_ee_rd_atom; -+ int max_res_rd_atom; -+ int max_qp_init_rd_atom; -+ int max_ee_init_rd_atom; -+ enum ibv_atomic_cap atomic_cap; -+ int max_ee; -+ int max_rdd; -+ int max_mw; -+ int max_raw_ipv6_qp; -+ int max_raw_ethy_qp; -+ int max_mcast_grp; -+ int max_mcast_qp_attach; -+ int max_total_mcast_qp_attach; -+ int max_ah; -+ int max_fmr; -+ int max_map_per_fmr; -+ int max_srq; -+ int max_srq_wr; -+ int max_srq_sge; -+ uint16_t max_pkeys; -+ uint8_t local_ca_ack_delay; -+ uint8_t phys_port_cnt; - }; - - enum ibv_mtu { -- IBV_MTU_256 = 1, -- IBV_MTU_512 = 2, -+ IBV_MTU_256 = 1, -+ IBV_MTU_512 = 2, - IBV_MTU_1024 = 3, - IBV_MTU_2048 = 4, - IBV_MTU_4096 = 5 - }; - - enum ibv_port_state { -- IBV_PORT_NOP = 0, -- IBV_PORT_DOWN = 1, -- IBV_PORT_INIT = 2, -- IBV_PORT_ARMED = 3, -- IBV_PORT_ACTIVE = 4, -- IBV_PORT_ACTIVE_DEFER = 5 -+ IBV_PORT_NOP = 0, -+ IBV_PORT_DOWN = 1, -+ IBV_PORT_INIT = 2, -+ IBV_PORT_ARMED = 3, -+ IBV_PORT_ACTIVE = 4, -+ IBV_PORT_ACTIVE_DEFER = 5 - }; - - enum { -@@ -182,27 +179,27 @@ enum { - }; - - struct ibv_port_attr { -- enum ibv_port_state state; -- enum ibv_mtu max_mtu; -- enum ibv_mtu active_mtu; -- int gid_tbl_len; -- uint32_t port_cap_flags; -- uint32_t max_msg_sz; -- uint32_t bad_pkey_cntr; -- uint32_t qkey_viol_cntr; -- uint16_t pkey_tbl_len; -- uint16_t lid; -- uint16_t sm_lid; -- uint8_t lmc; -- uint8_t max_vl_num; -- uint8_t sm_sl; -- uint8_t subnet_timeout; -- uint8_t init_type_reply; -- uint8_t active_width; -- uint8_t active_speed; -- uint8_t phys_state; -- uint8_t link_layer; -- uint8_t reserved; -+ enum ibv_port_state state; -+ enum ibv_mtu max_mtu; -+ enum ibv_mtu active_mtu; -+ int gid_tbl_len; -+ uint32_t port_cap_flags; -+ uint32_t max_msg_sz; -+ uint32_t bad_pkey_cntr; -+ uint32_t qkey_viol_cntr; -+ uint16_t pkey_tbl_len; -+ uint16_t lid; -+ uint16_t sm_lid; -+ uint8_t lmc; -+ uint8_t max_vl_num; -+ uint8_t sm_sl; -+ uint8_t subnet_timeout; -+ uint8_t init_type_reply; -+ uint8_t active_width; -+ uint8_t active_speed; -+ uint8_t phys_state; -+ uint8_t link_layer; -+ uint8_t reserved; - }; - - enum ibv_event_type { -@@ -229,12 +226,12 @@ enum ibv_event_type { - - struct ibv_async_event { - union { -- struct ibv_cq *cq; -- struct ibv_qp *qp; -+ struct ibv_cq *cq; -+ struct ibv_qp *qp; - struct ibv_srq *srq; -- int port_num; -+ int port_num; - } element; -- enum ibv_event_type event_type; -+ enum ibv_event_type event_type; - }; - - enum ibv_wc_status { -@@ -270,103 +267,117 @@ enum ibv_wc_opcode { - IBV_WC_COMP_SWAP, - IBV_WC_FETCH_ADD, - IBV_WC_BIND_MW, --/* -- * Set value of IBV_WC_RECV so consumers can test if a completion is a -- * receive by testing (opcode & IBV_WC_RECV). -- */ -- IBV_WC_RECV = 1 << 7, -+ /* -+ * Set value of IBV_WC_RECV so consumers can test if a completion is a -+ * receive by testing (opcode & IBV_WC_RECV). -+ */ -+ IBV_WC_RECV = 1 << 7, - IBV_WC_RECV_RDMA_WITH_IMM - }; - - enum ibv_wc_flags { -- IBV_WC_GRH = 1 << 0, -- IBV_WC_WITH_IMM = 1 << 1 -+ IBV_WC_GRH = 1 << 0, IBV_WC_WITH_IMM = 1 << 1 - }; - - struct ibv_wc { -- uint64_t wr_id; -- enum ibv_wc_status status; -- enum ibv_wc_opcode opcode; -- uint32_t vendor_err; -- uint32_t byte_len; -- uint32_t imm_data; /* in network byte order */ -- uint32_t qp_num; -- uint32_t src_qp; -- int wc_flags; -- uint16_t pkey_index; -- uint16_t slid; -- uint8_t sl; -- uint8_t dlid_path_bits; -+ uint64_t wr_id; -+ enum ibv_wc_status status; -+ enum ibv_wc_opcode opcode; -+ uint32_t vendor_err; -+ uint32_t byte_len; -+ uint32_t imm_data; /* in network byte order */ -+ uint32_t qp_num; -+ uint32_t src_qp; -+ int wc_flags; -+ uint16_t pkey_index; -+ uint16_t slid; -+ uint8_t sl; -+ uint8_t dlid_path_bits; - }; - - enum ibv_access_flags { -- IBV_ACCESS_LOCAL_WRITE = 1, -- IBV_ACCESS_REMOTE_WRITE = (1<<1), -- IBV_ACCESS_REMOTE_READ = (1<<2), -- IBV_ACCESS_REMOTE_ATOMIC = (1<<3), -- IBV_ACCESS_MW_BIND = (1<<4) -+ IBV_ACCESS_LOCAL_WRITE = 1, -+ IBV_ACCESS_REMOTE_WRITE = (1 << 1), -+ IBV_ACCESS_REMOTE_READ = (1 << 2), -+ IBV_ACCESS_REMOTE_ATOMIC = (1 << 3), -+ IBV_ACCESS_MW_BIND = (1 << 4) - }; - - struct ibv_pd { -- struct ibv_context *context; -- uint32_t handle; -+ struct ibv_context *context; -+ uint32_t handle; -+}; -+ -+enum ibv_xrcd_init_attr_mask { -+ IBV_XRCD_INIT_ATTR_FD = 1 << 0, -+ IBV_XRCD_INIT_ATTR_OFLAGS = 1 << 1, -+ IBV_XRCD_INIT_ATTR_RESERVED = 1 << 2 -+}; -+ -+struct ibv_xrcd_init_attr { -+ uint32_t comp_mask; -+ int fd; -+ int oflags; -+}; -+ -+struct ibv_xrcd { -+ struct ibv_context *context; - }; - - enum ibv_rereg_mr_flags { -- IBV_REREG_MR_CHANGE_TRANSLATION = (1 << 0), -- IBV_REREG_MR_CHANGE_PD = (1 << 1), -- IBV_REREG_MR_CHANGE_ACCESS = (1 << 2), -- IBV_REREG_MR_KEEP_VALID = (1 << 3) -+ IBV_REREG_MR_CHANGE_TRANSLATION = (1 << 0), -+ IBV_REREG_MR_CHANGE_PD = (1 << 1), -+ IBV_REREG_MR_CHANGE_ACCESS = (1 << 2), -+ IBV_REREG_MR_KEEP_VALID = (1 << 3) - }; - - struct ibv_mr { -- struct ibv_context *context; -- struct ibv_pd *pd; -- void *addr; -- size_t length; -- uint32_t handle; -- uint32_t lkey; -- uint32_t rkey; -+ struct ibv_context *context; -+ struct ibv_pd *pd; -+ void *addr; -+ size_t length; -+ uint32_t handle; -+ uint32_t lkey; -+ uint32_t rkey; - }; - - enum ibv_mw_type { -- IBV_MW_TYPE_1 = 1, -- IBV_MW_TYPE_2 = 2 -+ IBV_MW_TYPE_1 = 1, IBV_MW_TYPE_2 = 2 - }; - - struct ibv_mw { -- struct ibv_context *context; -- struct ibv_pd *pd; -- uint32_t rkey; -+ struct ibv_context *context; -+ struct ibv_pd *pd; -+ uint32_t rkey; - }; - - struct ibv_global_route { -- union ibv_gid dgid; -- uint32_t flow_label; -- uint8_t sgid_index; -- uint8_t hop_limit; -- uint8_t traffic_class; -+ union ibv_gid dgid; -+ uint32_t flow_label; -+ uint8_t sgid_index; -+ uint8_t hop_limit; -+ uint8_t traffic_class; - }; - - struct ibv_grh { -- uint32_t version_tclass_flow; -- uint16_t paylen; -- uint8_t next_hdr; -- uint8_t hop_limit; -- union ibv_gid sgid; -- union ibv_gid dgid; -+ uint32_t version_tclass_flow; -+ uint16_t paylen; -+ uint8_t next_hdr; -+ uint8_t hop_limit; -+ union ibv_gid sgid; -+ union ibv_gid dgid; - }; - - enum ibv_rate { -- IBV_RATE_MAX = 0, -+ IBV_RATE_MAX = 0, - IBV_RATE_2_5_GBPS = 2, -- IBV_RATE_5_GBPS = 5, -- IBV_RATE_10_GBPS = 3, -- IBV_RATE_20_GBPS = 6, -- IBV_RATE_30_GBPS = 4, -- IBV_RATE_40_GBPS = 7, -- IBV_RATE_60_GBPS = 8, -- IBV_RATE_80_GBPS = 9, -+ IBV_RATE_5_GBPS = 5, -+ IBV_RATE_10_GBPS = 3, -+ IBV_RATE_20_GBPS = 6, -+ IBV_RATE_30_GBPS = 4, -+ IBV_RATE_40_GBPS = 7, -+ IBV_RATE_60_GBPS = 8, -+ IBV_RATE_80_GBPS = 9, - IBV_RATE_120_GBPS = 10 - }; - -@@ -385,77 +396,74 @@ int ibv_rate_to_mult(enum ibv_rate rate) __attribute_const; - enum ibv_rate mult_to_ibv_rate(int mult) __attribute_const; - - struct ibv_ah_attr { -- struct ibv_global_route grh; -- uint16_t dlid; -- uint8_t sl; -- uint8_t src_path_bits; -- uint8_t static_rate; -- uint8_t is_global; -- uint8_t port_num; -+ struct ibv_global_route grh; -+ uint16_t dlid; -+ uint8_t sl; -+ uint8_t src_path_bits; -+ uint8_t static_rate; -+ uint8_t is_global; -+ uint8_t port_num; - }; - - enum ibv_srq_attr_mask { -- IBV_SRQ_MAX_WR = 1 << 0, -- IBV_SRQ_LIMIT = 1 << 1 -+ IBV_SRQ_MAX_WR = 1 << 0, IBV_SRQ_LIMIT = 1 << 1 - }; - - struct ibv_srq_attr { -- uint32_t max_wr; -- uint32_t max_sge; -- uint32_t srq_limit; -+ uint32_t max_wr; -+ uint32_t max_sge; -+ uint32_t srq_limit; - }; - - struct ibv_srq_init_attr { -- void *srq_context; -- struct ibv_srq_attr attr; -+ void *srq_context; -+ struct ibv_srq_attr attr; - }; - - enum ibv_qp_type { -- IBV_QPT_RC = 2, -- IBV_QPT_UC, -- IBV_QPT_UD -+ IBV_QPT_RC = 2, IBV_QPT_UC, IBV_QPT_UD - }; - - struct ibv_qp_cap { -- uint32_t max_send_wr; -- uint32_t max_recv_wr; -- uint32_t max_send_sge; -- uint32_t max_recv_sge; -- uint32_t max_inline_data; -+ uint32_t max_send_wr; -+ uint32_t max_recv_wr; -+ uint32_t max_send_sge; -+ uint32_t max_recv_sge; -+ uint32_t max_inline_data; - }; - - struct ibv_qp_init_attr { -- void *qp_context; -- struct ibv_cq *send_cq; -- struct ibv_cq *recv_cq; -- struct ibv_srq *srq; -- struct ibv_qp_cap cap; -- enum ibv_qp_type qp_type; -- int sq_sig_all; -+ void *qp_context; -+ struct ibv_cq *send_cq; -+ struct ibv_cq *recv_cq; -+ struct ibv_srq *srq; -+ struct ibv_qp_cap cap; -+ enum ibv_qp_type qp_type; -+ int sq_sig_all; - }; - - enum ibv_qp_attr_mask { -- IBV_QP_STATE = 1 << 0, -- IBV_QP_CUR_STATE = 1 << 1, -- IBV_QP_EN_SQD_ASYNC_NOTIFY = 1 << 2, -- IBV_QP_ACCESS_FLAGS = 1 << 3, -- IBV_QP_PKEY_INDEX = 1 << 4, -- IBV_QP_PORT = 1 << 5, -- IBV_QP_QKEY = 1 << 6, -- IBV_QP_AV = 1 << 7, -- IBV_QP_PATH_MTU = 1 << 8, -- IBV_QP_TIMEOUT = 1 << 9, -- IBV_QP_RETRY_CNT = 1 << 10, -- IBV_QP_RNR_RETRY = 1 << 11, -- IBV_QP_RQ_PSN = 1 << 12, -- IBV_QP_MAX_QP_RD_ATOMIC = 1 << 13, -- IBV_QP_ALT_PATH = 1 << 14, -- IBV_QP_MIN_RNR_TIMER = 1 << 15, -- IBV_QP_SQ_PSN = 1 << 16, -- IBV_QP_MAX_DEST_RD_ATOMIC = 1 << 17, -- IBV_QP_PATH_MIG_STATE = 1 << 18, -- IBV_QP_CAP = 1 << 19, -- IBV_QP_DEST_QPN = 1 << 20 -+ IBV_QP_STATE = 1 << 0, -+ IBV_QP_CUR_STATE = 1 << 1, -+ IBV_QP_EN_SQD_ASYNC_NOTIFY = 1 << 2, -+ IBV_QP_ACCESS_FLAGS = 1 << 3, -+ IBV_QP_PKEY_INDEX = 1 << 4, -+ IBV_QP_PORT = 1 << 5, -+ IBV_QP_QKEY = 1 << 6, -+ IBV_QP_AV = 1 << 7, -+ IBV_QP_PATH_MTU = 1 << 8, -+ IBV_QP_TIMEOUT = 1 << 9, -+ IBV_QP_RETRY_CNT = 1 << 10, -+ IBV_QP_RNR_RETRY = 1 << 11, -+ IBV_QP_RQ_PSN = 1 << 12, -+ IBV_QP_MAX_QP_RD_ATOMIC = 1 << 13, -+ IBV_QP_ALT_PATH = 1 << 14, -+ IBV_QP_MIN_RNR_TIMER = 1 << 15, -+ IBV_QP_SQ_PSN = 1 << 16, -+ IBV_QP_MAX_DEST_RD_ATOMIC = 1 << 17, -+ IBV_QP_PATH_MIG_STATE = 1 << 18, -+ IBV_QP_CAP = 1 << 19, -+ IBV_QP_DEST_QPN = 1 << 20 - }; - - enum ibv_qp_state { -@@ -469,37 +477,35 @@ enum ibv_qp_state { - }; - - enum ibv_mig_state { -- IBV_MIG_MIGRATED, -- IBV_MIG_REARM, -- IBV_MIG_ARMED -+ IBV_MIG_MIGRATED, IBV_MIG_REARM, IBV_MIG_ARMED - }; - - struct ibv_qp_attr { -- enum ibv_qp_state qp_state; -- enum ibv_qp_state cur_qp_state; -- enum ibv_mtu path_mtu; -- enum ibv_mig_state path_mig_state; -- uint32_t qkey; -- uint32_t rq_psn; -- uint32_t sq_psn; -- uint32_t dest_qp_num; -- int qp_access_flags; -- struct ibv_qp_cap cap; -- struct ibv_ah_attr ah_attr; -- struct ibv_ah_attr alt_ah_attr; -- uint16_t pkey_index; -- uint16_t alt_pkey_index; -- uint8_t en_sqd_async_notify; -- uint8_t sq_draining; -- uint8_t max_rd_atomic; -- uint8_t max_dest_rd_atomic; -- uint8_t min_rnr_timer; -- uint8_t port_num; -- uint8_t timeout; -- uint8_t retry_cnt; -- uint8_t rnr_retry; -- uint8_t alt_port_num; -- uint8_t alt_timeout; -+ enum ibv_qp_state qp_state; -+ enum ibv_qp_state cur_qp_state; -+ enum ibv_mtu path_mtu; -+ enum ibv_mig_state path_mig_state; -+ uint32_t qkey; -+ uint32_t rq_psn; -+ uint32_t sq_psn; -+ uint32_t dest_qp_num; -+ int qp_access_flags; -+ struct ibv_qp_cap cap; -+ struct ibv_ah_attr ah_attr; -+ struct ibv_ah_attr alt_ah_attr; -+ uint16_t pkey_index; -+ uint16_t alt_pkey_index; -+ uint8_t en_sqd_async_notify; -+ uint8_t sq_draining; -+ uint8_t max_rd_atomic; -+ uint8_t max_dest_rd_atomic; -+ uint8_t min_rnr_timer; -+ uint8_t port_num; -+ uint8_t timeout; -+ uint8_t retry_cnt; -+ uint8_t rnr_retry; -+ uint8_t alt_port_num; -+ uint8_t alt_timeout; - }; - - enum ibv_wr_opcode { -@@ -513,249 +519,249 @@ enum ibv_wr_opcode { - }; - - enum ibv_send_flags { -- IBV_SEND_FENCE = 1 << 0, -- IBV_SEND_SIGNALED = 1 << 1, -- IBV_SEND_SOLICITED = 1 << 2, -- IBV_SEND_INLINE = 1 << 3 -+ IBV_SEND_FENCE = 1 << 0, -+ IBV_SEND_SIGNALED = 1 << 1, -+ IBV_SEND_SOLICITED = 1 << 2, -+ IBV_SEND_INLINE = 1 << 3 - }; - - struct ibv_sge { -- uint64_t addr; -- uint32_t length; -- uint32_t lkey; -+ uint64_t addr; -+ uint32_t length; -+ uint32_t lkey; - }; - - struct ibv_send_wr { -- uint64_t wr_id; -- struct ibv_send_wr *next; -- struct ibv_sge *sg_list; -- int num_sge; -- enum ibv_wr_opcode opcode; -- int send_flags; -- uint32_t imm_data; /* in network byte order */ -+ uint64_t wr_id; -+ struct ibv_send_wr *next; -+ struct ibv_sge *sg_list; -+ int num_sge; -+ enum ibv_wr_opcode opcode; -+ int send_flags; -+ uint32_t imm_data; /* in network byte order */ - union { - struct { -- uint64_t remote_addr; -- uint32_t rkey; -+ uint64_t remote_addr; -+ uint32_t rkey; - } rdma; - struct { -- uint64_t remote_addr; -- uint64_t compare_add; -- uint64_t swap; -- uint32_t rkey; -+ uint64_t remote_addr; -+ uint64_t compare_add; -+ uint64_t swap; -+ uint32_t rkey; - } atomic; - struct { -- struct ibv_ah *ah; -- uint32_t remote_qpn; -- uint32_t remote_qkey; -+ struct ibv_ah *ah; -+ uint32_t remote_qpn; -+ uint32_t remote_qkey; - } ud; - } wr; - }; - - struct ibv_recv_wr { -- uint64_t wr_id; -- struct ibv_recv_wr *next; -- struct ibv_sge *sg_list; -- int num_sge; -+ uint64_t wr_id; -+ struct ibv_recv_wr *next; -+ struct ibv_sge *sg_list; -+ int num_sge; - }; - - struct ibv_mw_bind { -- uint64_t wr_id; -- struct ibv_mr *mr; -- void *addr; -- size_t length; -- int send_flags; -- int mw_access_flags; -+ uint64_t wr_id; -+ struct ibv_mr *mr; -+ void *addr; -+ size_t length; -+ int send_flags; -+ int mw_access_flags; - }; - - struct ibv_srq { -- struct ibv_context *context; -- void *srq_context; -- struct ibv_pd *pd; -- uint32_t handle; -- -- pthread_mutex_t mutex; -- pthread_cond_t cond; -- uint32_t events_completed; -+ struct ibv_context *context; -+ void *srq_context; -+ struct ibv_pd *pd; -+ uint32_t handle; -+ -+ pthread_mutex_t mutex; -+ pthread_cond_t cond; -+ uint32_t events_completed; - }; - - struct ibv_qp { -- struct ibv_context *context; -- void *qp_context; -- struct ibv_pd *pd; -- struct ibv_cq *send_cq; -- struct ibv_cq *recv_cq; -- struct ibv_srq *srq; -- uint32_t handle; -- uint32_t qp_num; -- enum ibv_qp_state state; -- enum ibv_qp_type qp_type; -- -- pthread_mutex_t mutex; -- pthread_cond_t cond; -- uint32_t events_completed; -+ struct ibv_context *context; -+ void *qp_context; -+ struct ibv_pd *pd; -+ struct ibv_cq *send_cq; -+ struct ibv_cq *recv_cq; -+ struct ibv_srq *srq; -+ uint32_t handle; -+ uint32_t qp_num; -+ enum ibv_qp_state state; -+ enum ibv_qp_type qp_type; -+ -+ pthread_mutex_t mutex; -+ pthread_cond_t cond; -+ uint32_t events_completed; - }; - - struct ibv_comp_channel { -- struct ibv_context *context; -- int fd; -- int refcnt; -+ struct ibv_context *context; -+ int fd; -+ int refcnt; - }; - - struct ibv_cq { -- struct ibv_context *context; -+ struct ibv_context *context; - struct ibv_comp_channel *channel; -- void *cq_context; -- uint32_t handle; -- int cqe; -- -- pthread_mutex_t mutex; -- pthread_cond_t cond; -- uint32_t comp_events_completed; -- uint32_t async_events_completed; -+ void *cq_context; -+ uint32_t handle; -+ int cqe; -+ -+ pthread_mutex_t mutex; -+ pthread_cond_t cond; -+ uint32_t comp_events_completed; -+ uint32_t async_events_completed; - }; - - struct ibv_ah { -- struct ibv_context *context; -- struct ibv_pd *pd; -- uint32_t handle; -+ struct ibv_context *context; -+ struct ibv_pd *pd; -+ uint32_t handle; - }; - - struct ibv_device; - struct ibv_context; - - struct ibv_device_ops { -- struct ibv_context * (*alloc_context)(struct ibv_device *device, int cmd_fd); -- void (*free_context)(struct ibv_context *context); -+ struct ibv_context * (*alloc_context)(struct ibv_device *device, -+ int cmd_fd); -+ void (*free_context)(struct ibv_context *context); - }; - - enum { -- IBV_SYSFS_NAME_MAX = 64, -- IBV_SYSFS_PATH_MAX = 256 -+ IBV_SYSFS_NAME_MAX = 64, IBV_SYSFS_PATH_MAX = 256 - }; - - struct ibv_device { -- struct ibv_device_ops ops; -- enum ibv_node_type node_type; -- enum ibv_transport_type transport_type; -+ struct ibv_device_ops ops; -+ enum ibv_node_type node_type; -+ enum ibv_transport_type transport_type; - /* Name of underlying kernel IB device, eg "mthca0" */ -- char name[IBV_SYSFS_NAME_MAX]; -+ char name[IBV_SYSFS_NAME_MAX]; - /* Name of uverbs device, eg "uverbs0" */ -- char dev_name[IBV_SYSFS_NAME_MAX]; -+ char dev_name[IBV_SYSFS_NAME_MAX]; - /* Path to infiniband_verbs class device in sysfs */ -- char dev_path[IBV_SYSFS_PATH_MAX]; -+ char dev_path[IBV_SYSFS_PATH_MAX]; - /* Path to infiniband class device in sysfs */ -- char ibdev_path[IBV_SYSFS_PATH_MAX]; -+ char ibdev_path[IBV_SYSFS_PATH_MAX]; - }; - - struct verbs_device { - struct ibv_device device; /* Must be first */ -- size_t sz; -- size_t size_of_context; -- int (*init_context)(struct verbs_device *device, -- struct ibv_context *ctx, int cmd_fd); -- void (*uninit_context)(struct verbs_device *device, -- struct ibv_context *ctx); -- /* future fields added here */ -+ size_t sz; -+ size_t size_of_context; -+ int (*init_context)(struct verbs_device *device, -+ struct ibv_context *ctx, int cmd_fd); -+ void (*uninit_context)(struct verbs_device *device, -+ struct ibv_context *ctx); -+/* future fields added here */ - }; - - struct ibv_context_ops { -- int (*query_device)(struct ibv_context *context, -- struct ibv_device_attr *device_attr); -- int (*query_port)(struct ibv_context *context, uint8_t port_num, -- struct ibv_port_attr *port_attr); -- struct ibv_pd * (*alloc_pd)(struct ibv_context *context); -- int (*dealloc_pd)(struct ibv_pd *pd); -- struct ibv_mr * (*reg_mr)(struct ibv_pd *pd, void *addr, size_t length, -- int access); -- struct ibv_mr * (*rereg_mr)(struct ibv_mr *mr, -- int flags, -- struct ibv_pd *pd, void *addr, -- size_t length, -- int access); -- int (*dereg_mr)(struct ibv_mr *mr); -- struct ibv_mw * (*alloc_mw)(struct ibv_pd *pd, enum ibv_mw_type type); -- int (*bind_mw)(struct ibv_qp *qp, struct ibv_mw *mw, -- struct ibv_mw_bind *mw_bind); -- int (*dealloc_mw)(struct ibv_mw *mw); -- struct ibv_cq * (*create_cq)(struct ibv_context *context, int cqe, -- struct ibv_comp_channel *channel, -- int comp_vector); -- int (*poll_cq)(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc); -- int (*req_notify_cq)(struct ibv_cq *cq, int solicited_only); -- void (*cq_event)(struct ibv_cq *cq); -- int (*resize_cq)(struct ibv_cq *cq, int cqe); -- int (*destroy_cq)(struct ibv_cq *cq); -- struct ibv_srq * (*create_srq)(struct ibv_pd *pd, -- struct ibv_srq_init_attr *srq_init_attr); -- int (*modify_srq)(struct ibv_srq *srq, -- struct ibv_srq_attr *srq_attr, -- int srq_attr_mask); -- int (*query_srq)(struct ibv_srq *srq, -- struct ibv_srq_attr *srq_attr); -- int (*destroy_srq)(struct ibv_srq *srq); -- int (*post_srq_recv)(struct ibv_srq *srq, -- struct ibv_recv_wr *recv_wr, -- struct ibv_recv_wr **bad_recv_wr); -- struct ibv_qp * (*create_qp)(struct ibv_pd *pd, struct ibv_qp_init_attr *attr); -- int (*query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, -- int attr_mask, -- struct ibv_qp_init_attr *init_attr); -- int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, -- int attr_mask); -- int (*destroy_qp)(struct ibv_qp *qp); -- int (*post_send)(struct ibv_qp *qp, struct ibv_send_wr *wr, -- struct ibv_send_wr **bad_wr); -- int (*post_recv)(struct ibv_qp *qp, struct ibv_recv_wr *wr, -- struct ibv_recv_wr **bad_wr); -- struct ibv_ah * (*create_ah)(struct ibv_pd *pd, struct ibv_ah_attr *attr); -- int (*destroy_ah)(struct ibv_ah *ah); -- int (*attach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, -- uint16_t lid); -- int (*detach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, -- uint16_t lid); -- void (*async_event)(struct ibv_async_event *event); -+ int (*query_device)(struct ibv_context *context, -+ struct ibv_device_attr *device_attr); -+ int (*query_port)(struct ibv_context *context, uint8_t port_num, -+ struct ibv_port_attr *port_attr); -+ struct ibv_pd * (*alloc_pd)(struct ibv_context *context); -+ int (*dealloc_pd)(struct ibv_pd *pd); -+ struct ibv_mr * (*reg_mr)(struct ibv_pd *pd, void *addr, size_t length, -+ int access); -+ struct ibv_mr * (*rereg_mr)(struct ibv_mr *mr, int flags, -+ struct ibv_pd *pd, void *addr, size_t length, -+ int access); -+ int (*dereg_mr)(struct ibv_mr *mr); -+ struct ibv_mw * (*alloc_mw)(struct ibv_pd *pd, enum ibv_mw_type type); -+ int (*bind_mw)(struct ibv_qp *qp, struct ibv_mw *mw, -+ struct ibv_mw_bind *mw_bind); -+ int (*dealloc_mw)(struct ibv_mw *mw); -+ struct ibv_cq * (*create_cq)(struct ibv_context *context, int cqe, -+ struct ibv_comp_channel *channel, int comp_vector); -+ int (*poll_cq)(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc); -+ int (*req_notify_cq)(struct ibv_cq *cq, int solicited_only); -+ void (*cq_event)(struct ibv_cq *cq); -+ int (*resize_cq)(struct ibv_cq *cq, int cqe); -+ int (*destroy_cq)(struct ibv_cq *cq); -+ struct ibv_srq * (*create_srq)(struct ibv_pd *pd, -+ struct ibv_srq_init_attr *srq_init_attr); -+ int (*modify_srq)(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr, -+ int srq_attr_mask); -+ int (*query_srq)(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr); -+ int (*destroy_srq)(struct ibv_srq *srq); -+ int (*post_srq_recv)(struct ibv_srq *srq, struct ibv_recv_wr *recv_wr, -+ struct ibv_recv_wr **bad_recv_wr); -+ struct ibv_qp * (*create_qp)(struct ibv_pd *pd, -+ struct ibv_qp_init_attr *attr); -+ int (*query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, -+ int attr_mask, struct ibv_qp_init_attr *init_attr); -+ int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, -+ int attr_mask); -+ int (*destroy_qp)(struct ibv_qp *qp); -+ int (*post_send)(struct ibv_qp *qp, struct ibv_send_wr *wr, -+ struct ibv_send_wr **bad_wr); -+ int (*post_recv)(struct ibv_qp *qp, struct ibv_recv_wr *wr, -+ struct ibv_recv_wr **bad_wr); -+ struct ibv_ah * (*create_ah)(struct ibv_pd *pd, -+ struct ibv_ah_attr *attr); -+ int (*destroy_ah)(struct ibv_ah *ah); -+ int (*attach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, -+ uint16_t lid); -+ int (*detach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, -+ uint16_t lid); -+ void (*async_event)(struct ibv_async_event *event); - }; - - struct ibv_context { -- struct ibv_device *device; -- struct ibv_context_ops ops; -- int cmd_fd; -- int async_fd; -- int num_comp_vectors; -- pthread_mutex_t mutex; -- void *abi_compat; -+ struct ibv_device *device; -+ struct ibv_context_ops ops; -+ int cmd_fd; -+ int async_fd; -+ int num_comp_vectors; -+ pthread_mutex_t mutex; -+ void *abi_compat; - }; - - enum verbs_context_mask { -- VERBS_CONTEXT_RESERVED = 1 << 0 -+ VERBS_CONTEXT_XRCD = 1 << 0, -+ VERBS_CONTEXT_RESERVED = 1 << 1 - }; - - 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 -+ */ -+ 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 */ - }; - --static inline struct verbs_context *verbs_get_ctx( -- const struct ibv_context *ctx) --{ -+static inline struct verbs_context *verbs_get_ctx(const struct ibv_context *ctx) { - return (ctx->abi_compat != ((uint8_t *) NULL) - 1) ? -- NULL : container_of(ctx, struct verbs_context, context); -+ NULL : container_of(ctx, struct verbs_context, context); - } - -+#define verbs_get_ctx_op(ctx, op) ({ \ -+ struct verbs_context *vctx = verbs_get_ctx(ctx); \ -+ (!vctx || (vctx->sz < sizeof(*vctx) - offsetof(struct verbs_context, op)) || \ -+ !vctx->op) ? NULL : vctx; }) -+ - static inline struct verbs_device *verbs_get_device( -- const struct ibv_device *dev) --{ -+ const struct ibv_device *dev) { - return (dev->ops.alloc_context) ? -- NULL : container_of(dev, struct verbs_device, device); -+ NULL : container_of(dev, struct verbs_device, device); - } - - /** -@@ -806,7 +812,7 @@ int ibv_close_device(struct ibv_context *context); - * be acknowledged with ibv_ack_async_event(). - */ - int ibv_get_async_event(struct ibv_context *context, -- struct ibv_async_event *event); -+ struct ibv_async_event *event); - - /** - * ibv_ack_async_event - Acknowledge an async event -@@ -824,21 +830,19 @@ void ibv_ack_async_event(struct ibv_async_event *event); - * ibv_query_device - Get device properties - */ - int ibv_query_device(struct ibv_context *context, -- struct ibv_device_attr *device_attr); -+ struct ibv_device_attr *device_attr); - - /** - * ibv_query_port - Get port properties - */ - int ibv_query_port(struct ibv_context *context, uint8_t port_num, -- struct ibv_port_attr *port_attr); -+ struct ibv_port_attr *port_attr); - - static inline int ___ibv_query_port(struct ibv_context *context, -- uint8_t port_num, -- struct ibv_port_attr *port_attr) --{ -- /* For compatability when running with old libibverbs */ -+ uint8_t port_num, struct ibv_port_attr *port_attr) { -+ /* For compatibility when running with old libibverbs */ - port_attr->link_layer = IBV_LINK_LAYER_UNSPECIFIED; -- port_attr->reserved = 0; -+ port_attr->reserved = 0; - - return ibv_query_port(context, port_num, port_attr); - } -@@ -849,14 +853,14 @@ static inline int ___ibv_query_port(struct ibv_context *context, - /** - * ibv_query_gid - Get a GID table entry - */ --int ibv_query_gid(struct ibv_context *context, uint8_t port_num, -- int index, union ibv_gid *gid); -+int ibv_query_gid(struct ibv_context *context, uint8_t port_num, int index, -+ union ibv_gid *gid); - - /** - * ibv_query_pkey - Get a P_Key table entry - */ --int ibv_query_pkey(struct ibv_context *context, uint8_t port_num, -- int index, uint16_t *pkey); -+int ibv_query_pkey(struct ibv_context *context, uint8_t port_num, int index, -+ uint16_t *pkey); - - /** - * ibv_alloc_pd - Allocate a protection domain -@@ -869,10 +873,31 @@ struct ibv_pd *ibv_alloc_pd(struct ibv_context *context); - int ibv_dealloc_pd(struct ibv_pd *pd); - - /** -+ * ibv_open_xrcd - Open an extended connection domain -+ */ -+static inline struct ibv_xrcd * -+ibv_open_xrcd(struct ibv_context *context, struct ibv_xrcd_init_attr *xrcd_init_attr) { -+ struct verbs_context *vctx = verbs_get_ctx_op(context, open_xrcd); -+ if (!vctx) { -+ errno = ENOSYS; -+ return NULL; -+ } -+ return vctx->open_xrcd(context, xrcd_init_attr); -+} -+ -+/** -+ * ibv_close_xrcd - Close an extended connection domain -+ */ -+static inline int ibv_close_xrcd(struct ibv_xrcd *xrcd) { -+ struct verbs_context *vctx = verbs_get_ctx(xrcd->context); -+ return vctx->close_xrcd(xrcd); -+} -+ -+/** - * ibv_reg_mr - Register a memory region - */ --struct ibv_mr *ibv_reg_mr(struct ibv_pd *pd, void *addr, -- size_t length, int access); -+struct ibv_mr *ibv_reg_mr(struct ibv_pd *pd, void *addr, size_t length, -+ int access); - - /** - * ibv_dereg_mr - Deregister a memory region -@@ -900,9 +925,8 @@ int ibv_destroy_comp_channel(struct ibv_comp_channel *channel); - * Must be >= 0 and < context->num_comp_vectors. - */ - struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe, -- void *cq_context, -- struct ibv_comp_channel *channel, -- int comp_vector); -+ void *cq_context, struct ibv_comp_channel *channel, -+ int comp_vector); - - /** - * ibv_resize_cq - Modifies the capacity of the CQ. -@@ -927,8 +951,8 @@ int ibv_destroy_cq(struct ibv_cq *cq); - * All completion events returned by ibv_get_cq_event() must - * eventually be acknowledged with ibv_ack_cq_events(). - */ --int ibv_get_cq_event(struct ibv_comp_channel *channel, -- struct ibv_cq **cq, void **cq_context); -+int ibv_get_cq_event(struct ibv_comp_channel *channel, struct ibv_cq **cq, -+ void **cq_context); - - /** - * ibv_ack_cq_events - Acknowledge CQ completion events -@@ -958,8 +982,8 @@ void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents); - * non-negative and strictly less than num_entries, then the CQ was - * emptied. - */ --static inline int ibv_poll_cq(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc) --{ -+static inline int ibv_poll_cq(struct ibv_cq *cq, int num_entries, -+ struct ibv_wc *wc) { - return cq->context->ops.poll_cq(cq, num_entries, wc); - } - -@@ -972,8 +996,7 @@ static inline int ibv_poll_cq(struct ibv_cq *cq, int num_entries, struct ibv_wc - * the next solicited CQ entry. If zero, any CQ entry, solicited or - * not, will generate an event. - */ --static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only) --{ -+static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only) { - return cq->context->ops.req_notify_cq(cq, solicited_only); - } - -@@ -989,7 +1012,7 @@ static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only) - * will always be at least as large as the requested values. - */ - struct ibv_srq *ibv_create_srq(struct ibv_pd *pd, -- struct ibv_srq_init_attr *srq_init_attr); -+ struct ibv_srq_init_attr *srq_init_attr); - - /** - * ibv_modify_srq - Modifies the attributes for the specified SRQ. -@@ -1003,9 +1026,8 @@ struct ibv_srq *ibv_create_srq(struct ibv_pd *pd, - * IBV_SRQ_LIMIT to set the SRQ's limit and request notification when - * the number of receives queued drops below the limit. - */ --int ibv_modify_srq(struct ibv_srq *srq, -- struct ibv_srq_attr *srq_attr, -- int srq_attr_mask); -+int ibv_modify_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr, -+ int srq_attr_mask); - - /** - * ibv_query_srq - Returns the attribute list and current values for the -@@ -1029,9 +1051,7 @@ int ibv_destroy_srq(struct ibv_srq *srq); - * the work request that failed to be posted on the QP. - */ - static inline int ibv_post_srq_recv(struct ibv_srq *srq, -- struct ibv_recv_wr *recv_wr, -- struct ibv_recv_wr **bad_recv_wr) --{ -+ struct ibv_recv_wr *recv_wr, struct ibv_recv_wr **bad_recv_wr) { - return srq->context->ops.post_srq_recv(srq, recv_wr, bad_recv_wr); - } - -@@ -1039,13 +1059,12 @@ static inline int ibv_post_srq_recv(struct ibv_srq *srq, - * ibv_create_qp - Create a queue pair. - */ - struct ibv_qp *ibv_create_qp(struct ibv_pd *pd, -- struct ibv_qp_init_attr *qp_init_attr); -+ struct ibv_qp_init_attr *qp_init_attr); - - /** - * ibv_modify_qp - Modify a queue pair. - */ --int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, -- int attr_mask); -+int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask); - - /** - * ibv_query_qp - Returns the attribute list and current values for the -@@ -1058,9 +1077,8 @@ int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, - * The qp_attr_mask may be used to limit the query to gathering only the - * selected attributes. - */ --int ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, -- int attr_mask, -- struct ibv_qp_init_attr *init_attr); -+int ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask, -+ struct ibv_qp_init_attr *init_attr); - - /** - * ibv_destroy_qp - Destroy a queue pair. -@@ -1074,8 +1092,7 @@ int ibv_destroy_qp(struct ibv_qp *qp); - * immediately after the call returns. - */ - static inline int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr, -- struct ibv_send_wr **bad_wr) --{ -+ struct ibv_send_wr **bad_wr) { - return qp->context->ops.post_send(qp, wr, bad_wr); - } - -@@ -1083,8 +1100,7 @@ static inline int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr, - * ibv_post_recv - Post a list of work requests to a receive queue. - */ - static inline int ibv_post_recv(struct ibv_qp *qp, struct ibv_recv_wr *wr, -- struct ibv_recv_wr **bad_wr) --{ -+ struct ibv_recv_wr **bad_wr) { - return qp->context->ops.post_recv(qp, wr, bad_wr); - } - -@@ -1105,8 +1121,8 @@ struct ibv_ah *ibv_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr); - * handle for replying to the message. - */ - int ibv_init_ah_from_wc(struct ibv_context *context, uint8_t port_num, -- struct ibv_wc *wc, struct ibv_grh *grh, -- struct ibv_ah_attr *ah_attr); -+ struct ibv_wc *wc, struct ibv_grh *grh, -+ struct ibv_ah_attr *ah_attr); - - /** - * ibv_create_ah_from_wc - Creates an address handle associated with the -@@ -1121,7 +1137,7 @@ int ibv_init_ah_from_wc(struct ibv_context *context, uint8_t port_num, - * in all UD QP post sends. - */ - struct ibv_ah *ibv_create_ah_from_wc(struct ibv_pd *pd, struct ibv_wc *wc, -- struct ibv_grh *grh, uint8_t port_num); -+ struct ibv_grh *grh, uint8_t port_num); - - /** - * ibv_destroy_ah - Destroy an address handle. -@@ -1176,5 +1192,4 @@ END_C_DECLS - - # undef __attribute_const - -- - #endif /* INFINIBAND_VERBS_H */ -diff --git a/src/cmd.c b/src/cmd.c -index dab8930..f0fb1dc 100644 ---- a/src/cmd.c -+++ b/src/cmd.c -@@ -194,6 +194,47 @@ int ibv_cmd_dealloc_pd(struct ibv_pd *pd) - return 0; - } - -+int ibv_cmd_open_xrcd(struct ibv_context *context, struct verbs_xrcd *xrcd, -+ struct ibv_xrcd_init_attr *attr, -+ struct ibv_open_xrcd *cmd, size_t cmd_size, -+ struct ibv_open_xrcd_resp *resp, size_t resp_size) -+{ -+ IBV_INIT_CMD_RESP(cmd, cmd_size, OPEN_XRCD, resp, resp_size); -+ -+ if (attr->comp_mask >= IBV_XRCD_INIT_ATTR_RESERVED) -+ return ENOSYS; -+ -+ if (!(attr->comp_mask & IBV_XRCD_INIT_ATTR_FD) || -+ !(attr->comp_mask & IBV_XRCD_INIT_ATTR_OFLAGS)) -+ return EINVAL; -+ -+ cmd->fd = attr->fd; -+ cmd->oflags = attr->oflags; -+ if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) -+ return errno; -+ -+ VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); -+ -+ xrcd->xrcd.context = context; -+ xrcd->comp_mask = VERBS_XRCD_HANDLE; -+ xrcd->handle = resp->xrcd_handle; -+ -+ return 0; -+} -+ -+int ibv_cmd_close_xrcd(struct verbs_xrcd *xrcd) -+{ -+ struct ibv_close_xrcd cmd; -+ -+ IBV_INIT_CMD(&cmd, sizeof cmd, CLOSE_XRCD); -+ cmd.xrcd_handle = xrcd->handle; -+ -+ if (write(xrcd->xrcd.context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) -+ return errno; -+ -+ return 0; -+} -+ - int ibv_cmd_reg_mr(struct ibv_pd *pd, void *addr, size_t length, - uint64_t hca_va, int access, - struct ibv_mr *mr, struct ibv_reg_mr *cmd, -diff --git a/src/libibverbs.map b/src/libibverbs.map -index ee9adea..9a15f3f 100644 ---- a/src/libibverbs.map -+++ b/src/libibverbs.map -@@ -97,4 +97,8 @@ IBVERBS_1.1 { - ibv_port_state_str; - ibv_event_type_str; - ibv_wc_status_str; -+ -+ ibv_cmd_open_xrcd; -+ ibv_cmd_close_xrcd; -+ - } IBVERBS_1.0; diff --git a/patches/xrcd b/patches/xrcd index aa732d5..bcdd27e 100644 --- a/patches/xrcd +++ b/patches/xrcd @@ -1,5 +1,5 @@ Bottom: ff25a98f5caa5889dfa52d7e2a6a9aa3e69b3ee5 -Top: ff25a98f5caa5889dfa52d7e2a6a9aa3e69b3ee5 +Top: 261f148eb3217529a654c1d876ec3902e40bcc3d Author: Sean Hefty Date: 2012-09-07 14:38:07 -0700 @@ -21,4 +21,1461 @@ Signed-off-by: Sean Hefty --- - +diff --git a/include/infiniband/driver.h b/include/infiniband/driver.h +index f22f287..ce88442 100644 +--- a/include/infiniband/driver.h ++++ b/include/infiniband/driver.h +@@ -53,6 +53,17 @@ + */ + #define IBV_DEVICE_LIBRARY_EXTENSION rdmav2 + ++enum verbs_xrcd_mask { ++ VERBS_XRCD_HANDLE = 1 << 0, ++ VERBS_XRCD_RESERVED = 1 << 1 ++}; ++ ++struct verbs_xrcd { ++ struct ibv_xrcd xrcd; ++ uint64_t comp_mask; ++ uint32_t handle; ++}; ++ + 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, +@@ -78,6 +89,11 @@ int ibv_cmd_alloc_pd(struct ibv_context *context, struct ibv_pd *pd, + struct ibv_alloc_pd *cmd, size_t cmd_size, + struct ibv_alloc_pd_resp *resp, size_t resp_size); + int ibv_cmd_dealloc_pd(struct ibv_pd *pd); ++int ibv_cmd_open_xrcd(struct ibv_context *context, struct verbs_xrcd *xrcd, ++ struct ibv_xrcd_init_attr *attr, ++ struct ibv_open_xrcd *cmd, size_t cmd_size, ++ struct ibv_open_xrcd_resp *resp, size_t resp_size); ++int ibv_cmd_close_xrcd(struct verbs_xrcd *xrcd); + #define IBV_CMD_REG_MR_HAS_RESP_PARAMS + int ibv_cmd_reg_mr(struct ibv_pd *pd, void *addr, size_t length, + uint64_t hca_va, int access, +diff --git a/include/infiniband/kern-abi.h b/include/infiniband/kern-abi.h +index 619ea7e..d7c673f 100644 +--- a/include/infiniband/kern-abi.h ++++ b/include/infiniband/kern-abi.h +@@ -85,7 +85,9 @@ enum { + IB_USER_VERBS_CMD_MODIFY_SRQ, + IB_USER_VERBS_CMD_QUERY_SRQ, + IB_USER_VERBS_CMD_DESTROY_SRQ, +- IB_USER_VERBS_CMD_POST_SRQ_RECV ++ IB_USER_VERBS_CMD_POST_SRQ_RECV, ++ IB_USER_VERBS_CMD_OPEN_XRCD, ++ IB_USER_VERBS_CMD_CLOSE_XRCD, + }; + + /* +@@ -246,6 +248,27 @@ struct ibv_dealloc_pd { + __u32 pd_handle; + }; + ++struct ibv_open_xrcd { ++ __u32 command; ++ __u16 in_words; ++ __u16 out_words; ++ __u64 response; ++ __u32 fd; ++ __u32 oflags; ++ __u64 driver_data[0]; ++}; ++ ++struct ibv_open_xrcd_resp { ++ __u32 xrcd_handle; ++}; ++ ++struct ibv_close_xrcd { ++ __u32 command; ++ __u16 in_words; ++ __u16 out_words; ++ __u32 xrcd_handle; ++}; ++ + struct ibv_reg_mr { + __u32 command; + __u16 in_words; +@@ -804,6 +827,8 @@ enum { + * trick opcodes in IBV_INIT_CMD() doesn't break. + */ + 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, + }; + + struct ibv_destroy_cq_v1 { +diff --git a/include/infiniband/verbs.h b/include/infiniband/verbs.h +index d944680..7e32e64 100644 +--- a/include/infiniband/verbs.h ++++ b/include/infiniband/verbs.h +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. +- * Copyright (c) 2004 Intel Corporation. All rights reserved. ++ * Copyright (c) 2004, 2011-2012 Intel Corporation. All rights reserved. + * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2005 PathScale, Inc. All rights reserved. + * +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + #ifdef __cplusplus + # define BEGIN_C_DECLS extern "C" { +@@ -57,20 +58,20 @@ + BEGIN_C_DECLS + + union ibv_gid { +- uint8_t raw[16]; ++ uint8_t raw[16]; + struct { +- uint64_t subnet_prefix; +- uint64_t interface_id; ++ uint64_t subnet_prefix; ++ uint64_t interface_id; + } global; + }; + + #ifndef container_of + /** +- * container_of - cast a member of a structure out to the containing structure +- * @ptr: the pointer to the member. +- * @type: the type of the container struct this is embedded in. +- * @member: the name of the member within the struct. +- * ++ * container_of - cast a member of a structure out to the containing structure ++ * @ptr: the pointer to the member. ++ * @type: the type of the container struct this is embedded in. ++ * @member: the name of the member within the struct. ++ * + */ + #define container_of(ptr, type, member) ({\ + const typeof(((type *)0)->member) * __mptr = (ptr);\ +@@ -78,101 +79,97 @@ union ibv_gid { + #endif + + enum ibv_node_type { +- IBV_NODE_UNKNOWN = -1, +- IBV_NODE_CA = 1, ++ IBV_NODE_UNKNOWN = -1, ++ IBV_NODE_CA = 1, + IBV_NODE_SWITCH, + IBV_NODE_ROUTER, + IBV_NODE_RNIC + }; + + enum ibv_transport_type { +- IBV_TRANSPORT_UNKNOWN = -1, +- IBV_TRANSPORT_IB = 0, +- IBV_TRANSPORT_IWARP ++ IBV_TRANSPORT_UNKNOWN = -1, IBV_TRANSPORT_IB = 0, IBV_TRANSPORT_IWARP + }; + + enum ibv_device_cap_flags { +- IBV_DEVICE_RESIZE_MAX_WR = 1, +- IBV_DEVICE_BAD_PKEY_CNTR = 1 << 1, +- IBV_DEVICE_BAD_QKEY_CNTR = 1 << 2, +- IBV_DEVICE_RAW_MULTI = 1 << 3, +- IBV_DEVICE_AUTO_PATH_MIG = 1 << 4, +- IBV_DEVICE_CHANGE_PHY_PORT = 1 << 5, +- IBV_DEVICE_UD_AV_PORT_ENFORCE = 1 << 6, +- IBV_DEVICE_CURR_QP_STATE_MOD = 1 << 7, +- IBV_DEVICE_SHUTDOWN_PORT = 1 << 8, +- IBV_DEVICE_INIT_TYPE = 1 << 9, +- IBV_DEVICE_PORT_ACTIVE_EVENT = 1 << 10, +- 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_RESIZE_MAX_WR = 1, ++ IBV_DEVICE_BAD_PKEY_CNTR = 1 << 1, ++ IBV_DEVICE_BAD_QKEY_CNTR = 1 << 2, ++ IBV_DEVICE_RAW_MULTI = 1 << 3, ++ IBV_DEVICE_AUTO_PATH_MIG = 1 << 4, ++ IBV_DEVICE_CHANGE_PHY_PORT = 1 << 5, ++ IBV_DEVICE_UD_AV_PORT_ENFORCE = 1 << 6, ++ IBV_DEVICE_CURR_QP_STATE_MOD = 1 << 7, ++ IBV_DEVICE_SHUTDOWN_PORT = 1 << 8, ++ IBV_DEVICE_INIT_TYPE = 1 << 9, ++ IBV_DEVICE_PORT_ACTIVE_EVENT = 1 << 10, ++ 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 + }; + + enum ibv_atomic_cap { +- IBV_ATOMIC_NONE, +- IBV_ATOMIC_HCA, +- IBV_ATOMIC_GLOB ++ IBV_ATOMIC_NONE, IBV_ATOMIC_HCA, IBV_ATOMIC_GLOB + }; + + struct ibv_device_attr { +- char fw_ver[64]; +- uint64_t node_guid; +- uint64_t sys_image_guid; +- uint64_t max_mr_size; +- uint64_t page_size_cap; +- uint32_t vendor_id; +- uint32_t vendor_part_id; +- uint32_t hw_ver; +- int max_qp; +- int max_qp_wr; +- int device_cap_flags; +- int max_sge; +- int max_sge_rd; +- int max_cq; +- int max_cqe; +- int max_mr; +- int max_pd; +- int max_qp_rd_atom; +- int max_ee_rd_atom; +- int max_res_rd_atom; +- int max_qp_init_rd_atom; +- int max_ee_init_rd_atom; +- enum ibv_atomic_cap atomic_cap; +- int max_ee; +- int max_rdd; +- int max_mw; +- int max_raw_ipv6_qp; +- int max_raw_ethy_qp; +- int max_mcast_grp; +- int max_mcast_qp_attach; +- int max_total_mcast_qp_attach; +- int max_ah; +- int max_fmr; +- int max_map_per_fmr; +- int max_srq; +- int max_srq_wr; +- int max_srq_sge; +- uint16_t max_pkeys; +- uint8_t local_ca_ack_delay; +- uint8_t phys_port_cnt; ++ char fw_ver[64]; ++ uint64_t node_guid; ++ uint64_t sys_image_guid; ++ uint64_t max_mr_size; ++ uint64_t page_size_cap; ++ uint32_t vendor_id; ++ uint32_t vendor_part_id; ++ uint32_t hw_ver; ++ int max_qp; ++ int max_qp_wr; ++ int device_cap_flags; ++ int max_sge; ++ int max_sge_rd; ++ int max_cq; ++ int max_cqe; ++ int max_mr; ++ int max_pd; ++ int max_qp_rd_atom; ++ int max_ee_rd_atom; ++ int max_res_rd_atom; ++ int max_qp_init_rd_atom; ++ int max_ee_init_rd_atom; ++ enum ibv_atomic_cap atomic_cap; ++ int max_ee; ++ int max_rdd; ++ int max_mw; ++ int max_raw_ipv6_qp; ++ int max_raw_ethy_qp; ++ int max_mcast_grp; ++ int max_mcast_qp_attach; ++ int max_total_mcast_qp_attach; ++ int max_ah; ++ int max_fmr; ++ int max_map_per_fmr; ++ int max_srq; ++ int max_srq_wr; ++ int max_srq_sge; ++ uint16_t max_pkeys; ++ uint8_t local_ca_ack_delay; ++ uint8_t phys_port_cnt; + }; + + enum ibv_mtu { +- IBV_MTU_256 = 1, +- IBV_MTU_512 = 2, ++ IBV_MTU_256 = 1, ++ IBV_MTU_512 = 2, + IBV_MTU_1024 = 3, + IBV_MTU_2048 = 4, + IBV_MTU_4096 = 5 + }; + + enum ibv_port_state { +- IBV_PORT_NOP = 0, +- IBV_PORT_DOWN = 1, +- IBV_PORT_INIT = 2, +- IBV_PORT_ARMED = 3, +- IBV_PORT_ACTIVE = 4, +- IBV_PORT_ACTIVE_DEFER = 5 ++ IBV_PORT_NOP = 0, ++ IBV_PORT_DOWN = 1, ++ IBV_PORT_INIT = 2, ++ IBV_PORT_ARMED = 3, ++ IBV_PORT_ACTIVE = 4, ++ IBV_PORT_ACTIVE_DEFER = 5 + }; + + enum { +@@ -182,27 +179,27 @@ enum { + }; + + struct ibv_port_attr { +- enum ibv_port_state state; +- enum ibv_mtu max_mtu; +- enum ibv_mtu active_mtu; +- int gid_tbl_len; +- uint32_t port_cap_flags; +- uint32_t max_msg_sz; +- uint32_t bad_pkey_cntr; +- uint32_t qkey_viol_cntr; +- uint16_t pkey_tbl_len; +- uint16_t lid; +- uint16_t sm_lid; +- uint8_t lmc; +- uint8_t max_vl_num; +- uint8_t sm_sl; +- uint8_t subnet_timeout; +- uint8_t init_type_reply; +- uint8_t active_width; +- uint8_t active_speed; +- uint8_t phys_state; +- uint8_t link_layer; +- uint8_t reserved; ++ enum ibv_port_state state; ++ enum ibv_mtu max_mtu; ++ enum ibv_mtu active_mtu; ++ int gid_tbl_len; ++ uint32_t port_cap_flags; ++ uint32_t max_msg_sz; ++ uint32_t bad_pkey_cntr; ++ uint32_t qkey_viol_cntr; ++ uint16_t pkey_tbl_len; ++ uint16_t lid; ++ uint16_t sm_lid; ++ uint8_t lmc; ++ uint8_t max_vl_num; ++ uint8_t sm_sl; ++ uint8_t subnet_timeout; ++ uint8_t init_type_reply; ++ uint8_t active_width; ++ uint8_t active_speed; ++ uint8_t phys_state; ++ uint8_t link_layer; ++ uint8_t reserved; + }; + + enum ibv_event_type { +@@ -229,12 +226,12 @@ enum ibv_event_type { + + struct ibv_async_event { + union { +- struct ibv_cq *cq; +- struct ibv_qp *qp; ++ struct ibv_cq *cq; ++ struct ibv_qp *qp; + struct ibv_srq *srq; +- int port_num; ++ int port_num; + } element; +- enum ibv_event_type event_type; ++ enum ibv_event_type event_type; + }; + + enum ibv_wc_status { +@@ -270,103 +267,117 @@ enum ibv_wc_opcode { + IBV_WC_COMP_SWAP, + IBV_WC_FETCH_ADD, + IBV_WC_BIND_MW, +-/* +- * Set value of IBV_WC_RECV so consumers can test if a completion is a +- * receive by testing (opcode & IBV_WC_RECV). +- */ +- IBV_WC_RECV = 1 << 7, ++ /* ++ * Set value of IBV_WC_RECV so consumers can test if a completion is a ++ * receive by testing (opcode & IBV_WC_RECV). ++ */ ++ IBV_WC_RECV = 1 << 7, + IBV_WC_RECV_RDMA_WITH_IMM + }; + + enum ibv_wc_flags { +- IBV_WC_GRH = 1 << 0, +- IBV_WC_WITH_IMM = 1 << 1 ++ IBV_WC_GRH = 1 << 0, IBV_WC_WITH_IMM = 1 << 1 + }; + + struct ibv_wc { +- uint64_t wr_id; +- enum ibv_wc_status status; +- enum ibv_wc_opcode opcode; +- uint32_t vendor_err; +- uint32_t byte_len; +- uint32_t imm_data; /* in network byte order */ +- uint32_t qp_num; +- uint32_t src_qp; +- int wc_flags; +- uint16_t pkey_index; +- uint16_t slid; +- uint8_t sl; +- uint8_t dlid_path_bits; ++ uint64_t wr_id; ++ enum ibv_wc_status status; ++ enum ibv_wc_opcode opcode; ++ uint32_t vendor_err; ++ uint32_t byte_len; ++ uint32_t imm_data; /* in network byte order */ ++ uint32_t qp_num; ++ uint32_t src_qp; ++ int wc_flags; ++ uint16_t pkey_index; ++ uint16_t slid; ++ uint8_t sl; ++ uint8_t dlid_path_bits; + }; + + enum ibv_access_flags { +- IBV_ACCESS_LOCAL_WRITE = 1, +- IBV_ACCESS_REMOTE_WRITE = (1<<1), +- IBV_ACCESS_REMOTE_READ = (1<<2), +- IBV_ACCESS_REMOTE_ATOMIC = (1<<3), +- IBV_ACCESS_MW_BIND = (1<<4) ++ IBV_ACCESS_LOCAL_WRITE = 1, ++ IBV_ACCESS_REMOTE_WRITE = (1 << 1), ++ IBV_ACCESS_REMOTE_READ = (1 << 2), ++ IBV_ACCESS_REMOTE_ATOMIC = (1 << 3), ++ IBV_ACCESS_MW_BIND = (1 << 4) + }; + + struct ibv_pd { +- struct ibv_context *context; +- uint32_t handle; ++ struct ibv_context *context; ++ uint32_t handle; ++}; ++ ++enum ibv_xrcd_init_attr_mask { ++ IBV_XRCD_INIT_ATTR_FD = 1 << 0, ++ IBV_XRCD_INIT_ATTR_OFLAGS = 1 << 1, ++ IBV_XRCD_INIT_ATTR_RESERVED = 1 << 2 ++}; ++ ++struct ibv_xrcd_init_attr { ++ uint32_t comp_mask; ++ int fd; ++ int oflags; ++}; ++ ++struct ibv_xrcd { ++ struct ibv_context *context; + }; + + enum ibv_rereg_mr_flags { +- IBV_REREG_MR_CHANGE_TRANSLATION = (1 << 0), +- IBV_REREG_MR_CHANGE_PD = (1 << 1), +- IBV_REREG_MR_CHANGE_ACCESS = (1 << 2), +- IBV_REREG_MR_KEEP_VALID = (1 << 3) ++ IBV_REREG_MR_CHANGE_TRANSLATION = (1 << 0), ++ IBV_REREG_MR_CHANGE_PD = (1 << 1), ++ IBV_REREG_MR_CHANGE_ACCESS = (1 << 2), ++ IBV_REREG_MR_KEEP_VALID = (1 << 3) + }; + + struct ibv_mr { +- struct ibv_context *context; +- struct ibv_pd *pd; +- void *addr; +- size_t length; +- uint32_t handle; +- uint32_t lkey; +- uint32_t rkey; ++ struct ibv_context *context; ++ struct ibv_pd *pd; ++ void *addr; ++ size_t length; ++ uint32_t handle; ++ uint32_t lkey; ++ uint32_t rkey; + }; + + enum ibv_mw_type { +- IBV_MW_TYPE_1 = 1, +- IBV_MW_TYPE_2 = 2 ++ IBV_MW_TYPE_1 = 1, IBV_MW_TYPE_2 = 2 + }; + + struct ibv_mw { +- struct ibv_context *context; +- struct ibv_pd *pd; +- uint32_t rkey; ++ struct ibv_context *context; ++ struct ibv_pd *pd; ++ uint32_t rkey; + }; + + struct ibv_global_route { +- union ibv_gid dgid; +- uint32_t flow_label; +- uint8_t sgid_index; +- uint8_t hop_limit; +- uint8_t traffic_class; ++ union ibv_gid dgid; ++ uint32_t flow_label; ++ uint8_t sgid_index; ++ uint8_t hop_limit; ++ uint8_t traffic_class; + }; + + struct ibv_grh { +- uint32_t version_tclass_flow; +- uint16_t paylen; +- uint8_t next_hdr; +- uint8_t hop_limit; +- union ibv_gid sgid; +- union ibv_gid dgid; ++ uint32_t version_tclass_flow; ++ uint16_t paylen; ++ uint8_t next_hdr; ++ uint8_t hop_limit; ++ union ibv_gid sgid; ++ union ibv_gid dgid; + }; + + enum ibv_rate { +- IBV_RATE_MAX = 0, ++ IBV_RATE_MAX = 0, + IBV_RATE_2_5_GBPS = 2, +- IBV_RATE_5_GBPS = 5, +- IBV_RATE_10_GBPS = 3, +- IBV_RATE_20_GBPS = 6, +- IBV_RATE_30_GBPS = 4, +- IBV_RATE_40_GBPS = 7, +- IBV_RATE_60_GBPS = 8, +- IBV_RATE_80_GBPS = 9, ++ IBV_RATE_5_GBPS = 5, ++ IBV_RATE_10_GBPS = 3, ++ IBV_RATE_20_GBPS = 6, ++ IBV_RATE_30_GBPS = 4, ++ IBV_RATE_40_GBPS = 7, ++ IBV_RATE_60_GBPS = 8, ++ IBV_RATE_80_GBPS = 9, + IBV_RATE_120_GBPS = 10 + }; + +@@ -385,77 +396,74 @@ int ibv_rate_to_mult(enum ibv_rate rate) __attribute_const; + enum ibv_rate mult_to_ibv_rate(int mult) __attribute_const; + + struct ibv_ah_attr { +- struct ibv_global_route grh; +- uint16_t dlid; +- uint8_t sl; +- uint8_t src_path_bits; +- uint8_t static_rate; +- uint8_t is_global; +- uint8_t port_num; ++ struct ibv_global_route grh; ++ uint16_t dlid; ++ uint8_t sl; ++ uint8_t src_path_bits; ++ uint8_t static_rate; ++ uint8_t is_global; ++ uint8_t port_num; + }; + + enum ibv_srq_attr_mask { +- IBV_SRQ_MAX_WR = 1 << 0, +- IBV_SRQ_LIMIT = 1 << 1 ++ IBV_SRQ_MAX_WR = 1 << 0, IBV_SRQ_LIMIT = 1 << 1 + }; + + struct ibv_srq_attr { +- uint32_t max_wr; +- uint32_t max_sge; +- uint32_t srq_limit; ++ uint32_t max_wr; ++ uint32_t max_sge; ++ uint32_t srq_limit; + }; + + struct ibv_srq_init_attr { +- void *srq_context; +- struct ibv_srq_attr attr; ++ void *srq_context; ++ struct ibv_srq_attr attr; + }; + + enum ibv_qp_type { +- IBV_QPT_RC = 2, +- IBV_QPT_UC, +- IBV_QPT_UD ++ IBV_QPT_RC = 2, IBV_QPT_UC, IBV_QPT_UD + }; + + struct ibv_qp_cap { +- uint32_t max_send_wr; +- uint32_t max_recv_wr; +- uint32_t max_send_sge; +- uint32_t max_recv_sge; +- uint32_t max_inline_data; ++ uint32_t max_send_wr; ++ uint32_t max_recv_wr; ++ uint32_t max_send_sge; ++ uint32_t max_recv_sge; ++ uint32_t max_inline_data; + }; + + struct ibv_qp_init_attr { +- void *qp_context; +- struct ibv_cq *send_cq; +- struct ibv_cq *recv_cq; +- struct ibv_srq *srq; +- struct ibv_qp_cap cap; +- enum ibv_qp_type qp_type; +- int sq_sig_all; ++ void *qp_context; ++ struct ibv_cq *send_cq; ++ struct ibv_cq *recv_cq; ++ struct ibv_srq *srq; ++ struct ibv_qp_cap cap; ++ enum ibv_qp_type qp_type; ++ int sq_sig_all; + }; + + enum ibv_qp_attr_mask { +- IBV_QP_STATE = 1 << 0, +- IBV_QP_CUR_STATE = 1 << 1, +- IBV_QP_EN_SQD_ASYNC_NOTIFY = 1 << 2, +- IBV_QP_ACCESS_FLAGS = 1 << 3, +- IBV_QP_PKEY_INDEX = 1 << 4, +- IBV_QP_PORT = 1 << 5, +- IBV_QP_QKEY = 1 << 6, +- IBV_QP_AV = 1 << 7, +- IBV_QP_PATH_MTU = 1 << 8, +- IBV_QP_TIMEOUT = 1 << 9, +- IBV_QP_RETRY_CNT = 1 << 10, +- IBV_QP_RNR_RETRY = 1 << 11, +- IBV_QP_RQ_PSN = 1 << 12, +- IBV_QP_MAX_QP_RD_ATOMIC = 1 << 13, +- IBV_QP_ALT_PATH = 1 << 14, +- IBV_QP_MIN_RNR_TIMER = 1 << 15, +- IBV_QP_SQ_PSN = 1 << 16, +- IBV_QP_MAX_DEST_RD_ATOMIC = 1 << 17, +- IBV_QP_PATH_MIG_STATE = 1 << 18, +- IBV_QP_CAP = 1 << 19, +- IBV_QP_DEST_QPN = 1 << 20 ++ IBV_QP_STATE = 1 << 0, ++ IBV_QP_CUR_STATE = 1 << 1, ++ IBV_QP_EN_SQD_ASYNC_NOTIFY = 1 << 2, ++ IBV_QP_ACCESS_FLAGS = 1 << 3, ++ IBV_QP_PKEY_INDEX = 1 << 4, ++ IBV_QP_PORT = 1 << 5, ++ IBV_QP_QKEY = 1 << 6, ++ IBV_QP_AV = 1 << 7, ++ IBV_QP_PATH_MTU = 1 << 8, ++ IBV_QP_TIMEOUT = 1 << 9, ++ IBV_QP_RETRY_CNT = 1 << 10, ++ IBV_QP_RNR_RETRY = 1 << 11, ++ IBV_QP_RQ_PSN = 1 << 12, ++ IBV_QP_MAX_QP_RD_ATOMIC = 1 << 13, ++ IBV_QP_ALT_PATH = 1 << 14, ++ IBV_QP_MIN_RNR_TIMER = 1 << 15, ++ IBV_QP_SQ_PSN = 1 << 16, ++ IBV_QP_MAX_DEST_RD_ATOMIC = 1 << 17, ++ IBV_QP_PATH_MIG_STATE = 1 << 18, ++ IBV_QP_CAP = 1 << 19, ++ IBV_QP_DEST_QPN = 1 << 20 + }; + + enum ibv_qp_state { +@@ -469,37 +477,35 @@ enum ibv_qp_state { + }; + + enum ibv_mig_state { +- IBV_MIG_MIGRATED, +- IBV_MIG_REARM, +- IBV_MIG_ARMED ++ IBV_MIG_MIGRATED, IBV_MIG_REARM, IBV_MIG_ARMED + }; + + struct ibv_qp_attr { +- enum ibv_qp_state qp_state; +- enum ibv_qp_state cur_qp_state; +- enum ibv_mtu path_mtu; +- enum ibv_mig_state path_mig_state; +- uint32_t qkey; +- uint32_t rq_psn; +- uint32_t sq_psn; +- uint32_t dest_qp_num; +- int qp_access_flags; +- struct ibv_qp_cap cap; +- struct ibv_ah_attr ah_attr; +- struct ibv_ah_attr alt_ah_attr; +- uint16_t pkey_index; +- uint16_t alt_pkey_index; +- uint8_t en_sqd_async_notify; +- uint8_t sq_draining; +- uint8_t max_rd_atomic; +- uint8_t max_dest_rd_atomic; +- uint8_t min_rnr_timer; +- uint8_t port_num; +- uint8_t timeout; +- uint8_t retry_cnt; +- uint8_t rnr_retry; +- uint8_t alt_port_num; +- uint8_t alt_timeout; ++ enum ibv_qp_state qp_state; ++ enum ibv_qp_state cur_qp_state; ++ enum ibv_mtu path_mtu; ++ enum ibv_mig_state path_mig_state; ++ uint32_t qkey; ++ uint32_t rq_psn; ++ uint32_t sq_psn; ++ uint32_t dest_qp_num; ++ int qp_access_flags; ++ struct ibv_qp_cap cap; ++ struct ibv_ah_attr ah_attr; ++ struct ibv_ah_attr alt_ah_attr; ++ uint16_t pkey_index; ++ uint16_t alt_pkey_index; ++ uint8_t en_sqd_async_notify; ++ uint8_t sq_draining; ++ uint8_t max_rd_atomic; ++ uint8_t max_dest_rd_atomic; ++ uint8_t min_rnr_timer; ++ uint8_t port_num; ++ uint8_t timeout; ++ uint8_t retry_cnt; ++ uint8_t rnr_retry; ++ uint8_t alt_port_num; ++ uint8_t alt_timeout; + }; + + enum ibv_wr_opcode { +@@ -513,249 +519,249 @@ enum ibv_wr_opcode { + }; + + enum ibv_send_flags { +- IBV_SEND_FENCE = 1 << 0, +- IBV_SEND_SIGNALED = 1 << 1, +- IBV_SEND_SOLICITED = 1 << 2, +- IBV_SEND_INLINE = 1 << 3 ++ IBV_SEND_FENCE = 1 << 0, ++ IBV_SEND_SIGNALED = 1 << 1, ++ IBV_SEND_SOLICITED = 1 << 2, ++ IBV_SEND_INLINE = 1 << 3 + }; + + struct ibv_sge { +- uint64_t addr; +- uint32_t length; +- uint32_t lkey; ++ uint64_t addr; ++ uint32_t length; ++ uint32_t lkey; + }; + + struct ibv_send_wr { +- uint64_t wr_id; +- struct ibv_send_wr *next; +- struct ibv_sge *sg_list; +- int num_sge; +- enum ibv_wr_opcode opcode; +- int send_flags; +- uint32_t imm_data; /* in network byte order */ ++ uint64_t wr_id; ++ struct ibv_send_wr *next; ++ struct ibv_sge *sg_list; ++ int num_sge; ++ enum ibv_wr_opcode opcode; ++ int send_flags; ++ uint32_t imm_data; /* in network byte order */ + union { + struct { +- uint64_t remote_addr; +- uint32_t rkey; ++ uint64_t remote_addr; ++ uint32_t rkey; + } rdma; + struct { +- uint64_t remote_addr; +- uint64_t compare_add; +- uint64_t swap; +- uint32_t rkey; ++ uint64_t remote_addr; ++ uint64_t compare_add; ++ uint64_t swap; ++ uint32_t rkey; + } atomic; + struct { +- struct ibv_ah *ah; +- uint32_t remote_qpn; +- uint32_t remote_qkey; ++ struct ibv_ah *ah; ++ uint32_t remote_qpn; ++ uint32_t remote_qkey; + } ud; + } wr; + }; + + struct ibv_recv_wr { +- uint64_t wr_id; +- struct ibv_recv_wr *next; +- struct ibv_sge *sg_list; +- int num_sge; ++ uint64_t wr_id; ++ struct ibv_recv_wr *next; ++ struct ibv_sge *sg_list; ++ int num_sge; + }; + + struct ibv_mw_bind { +- uint64_t wr_id; +- struct ibv_mr *mr; +- void *addr; +- size_t length; +- int send_flags; +- int mw_access_flags; ++ uint64_t wr_id; ++ struct ibv_mr *mr; ++ void *addr; ++ size_t length; ++ int send_flags; ++ int mw_access_flags; + }; + + struct ibv_srq { +- struct ibv_context *context; +- void *srq_context; +- struct ibv_pd *pd; +- uint32_t handle; +- +- pthread_mutex_t mutex; +- pthread_cond_t cond; +- uint32_t events_completed; ++ struct ibv_context *context; ++ void *srq_context; ++ struct ibv_pd *pd; ++ uint32_t handle; ++ ++ pthread_mutex_t mutex; ++ pthread_cond_t cond; ++ uint32_t events_completed; + }; + + struct ibv_qp { +- struct ibv_context *context; +- void *qp_context; +- struct ibv_pd *pd; +- struct ibv_cq *send_cq; +- struct ibv_cq *recv_cq; +- struct ibv_srq *srq; +- uint32_t handle; +- uint32_t qp_num; +- enum ibv_qp_state state; +- enum ibv_qp_type qp_type; +- +- pthread_mutex_t mutex; +- pthread_cond_t cond; +- uint32_t events_completed; ++ struct ibv_context *context; ++ void *qp_context; ++ struct ibv_pd *pd; ++ struct ibv_cq *send_cq; ++ struct ibv_cq *recv_cq; ++ struct ibv_srq *srq; ++ uint32_t handle; ++ uint32_t qp_num; ++ enum ibv_qp_state state; ++ enum ibv_qp_type qp_type; ++ ++ pthread_mutex_t mutex; ++ pthread_cond_t cond; ++ uint32_t events_completed; + }; + + struct ibv_comp_channel { +- struct ibv_context *context; +- int fd; +- int refcnt; ++ struct ibv_context *context; ++ int fd; ++ int refcnt; + }; + + struct ibv_cq { +- struct ibv_context *context; ++ struct ibv_context *context; + struct ibv_comp_channel *channel; +- void *cq_context; +- uint32_t handle; +- int cqe; +- +- pthread_mutex_t mutex; +- pthread_cond_t cond; +- uint32_t comp_events_completed; +- uint32_t async_events_completed; ++ void *cq_context; ++ uint32_t handle; ++ int cqe; ++ ++ pthread_mutex_t mutex; ++ pthread_cond_t cond; ++ uint32_t comp_events_completed; ++ uint32_t async_events_completed; + }; + + struct ibv_ah { +- struct ibv_context *context; +- struct ibv_pd *pd; +- uint32_t handle; ++ struct ibv_context *context; ++ struct ibv_pd *pd; ++ uint32_t handle; + }; + + struct ibv_device; + struct ibv_context; + + struct ibv_device_ops { +- struct ibv_context * (*alloc_context)(struct ibv_device *device, int cmd_fd); +- void (*free_context)(struct ibv_context *context); ++ struct ibv_context * (*alloc_context)(struct ibv_device *device, ++ int cmd_fd); ++ void (*free_context)(struct ibv_context *context); + }; + + enum { +- IBV_SYSFS_NAME_MAX = 64, +- IBV_SYSFS_PATH_MAX = 256 ++ IBV_SYSFS_NAME_MAX = 64, IBV_SYSFS_PATH_MAX = 256 + }; + + struct ibv_device { +- struct ibv_device_ops ops; +- enum ibv_node_type node_type; +- enum ibv_transport_type transport_type; ++ struct ibv_device_ops ops; ++ enum ibv_node_type node_type; ++ enum ibv_transport_type transport_type; + /* Name of underlying kernel IB device, eg "mthca0" */ +- char name[IBV_SYSFS_NAME_MAX]; ++ char name[IBV_SYSFS_NAME_MAX]; + /* Name of uverbs device, eg "uverbs0" */ +- char dev_name[IBV_SYSFS_NAME_MAX]; ++ char dev_name[IBV_SYSFS_NAME_MAX]; + /* Path to infiniband_verbs class device in sysfs */ +- char dev_path[IBV_SYSFS_PATH_MAX]; ++ char dev_path[IBV_SYSFS_PATH_MAX]; + /* Path to infiniband class device in sysfs */ +- char ibdev_path[IBV_SYSFS_PATH_MAX]; ++ char ibdev_path[IBV_SYSFS_PATH_MAX]; + }; + + struct verbs_device { + struct ibv_device device; /* Must be first */ +- size_t sz; +- size_t size_of_context; +- int (*init_context)(struct verbs_device *device, +- struct ibv_context *ctx, int cmd_fd); +- void (*uninit_context)(struct verbs_device *device, +- struct ibv_context *ctx); +- /* future fields added here */ ++ size_t sz; ++ size_t size_of_context; ++ int (*init_context)(struct verbs_device *device, ++ struct ibv_context *ctx, int cmd_fd); ++ void (*uninit_context)(struct verbs_device *device, ++ struct ibv_context *ctx); ++/* future fields added here */ + }; + + struct ibv_context_ops { +- int (*query_device)(struct ibv_context *context, +- struct ibv_device_attr *device_attr); +- int (*query_port)(struct ibv_context *context, uint8_t port_num, +- struct ibv_port_attr *port_attr); +- struct ibv_pd * (*alloc_pd)(struct ibv_context *context); +- int (*dealloc_pd)(struct ibv_pd *pd); +- struct ibv_mr * (*reg_mr)(struct ibv_pd *pd, void *addr, size_t length, +- int access); +- struct ibv_mr * (*rereg_mr)(struct ibv_mr *mr, +- int flags, +- struct ibv_pd *pd, void *addr, +- size_t length, +- int access); +- int (*dereg_mr)(struct ibv_mr *mr); +- struct ibv_mw * (*alloc_mw)(struct ibv_pd *pd, enum ibv_mw_type type); +- int (*bind_mw)(struct ibv_qp *qp, struct ibv_mw *mw, +- struct ibv_mw_bind *mw_bind); +- int (*dealloc_mw)(struct ibv_mw *mw); +- struct ibv_cq * (*create_cq)(struct ibv_context *context, int cqe, +- struct ibv_comp_channel *channel, +- int comp_vector); +- int (*poll_cq)(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc); +- int (*req_notify_cq)(struct ibv_cq *cq, int solicited_only); +- void (*cq_event)(struct ibv_cq *cq); +- int (*resize_cq)(struct ibv_cq *cq, int cqe); +- int (*destroy_cq)(struct ibv_cq *cq); +- struct ibv_srq * (*create_srq)(struct ibv_pd *pd, +- struct ibv_srq_init_attr *srq_init_attr); +- int (*modify_srq)(struct ibv_srq *srq, +- struct ibv_srq_attr *srq_attr, +- int srq_attr_mask); +- int (*query_srq)(struct ibv_srq *srq, +- struct ibv_srq_attr *srq_attr); +- int (*destroy_srq)(struct ibv_srq *srq); +- int (*post_srq_recv)(struct ibv_srq *srq, +- struct ibv_recv_wr *recv_wr, +- struct ibv_recv_wr **bad_recv_wr); +- struct ibv_qp * (*create_qp)(struct ibv_pd *pd, struct ibv_qp_init_attr *attr); +- int (*query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, +- int attr_mask, +- struct ibv_qp_init_attr *init_attr); +- int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, +- int attr_mask); +- int (*destroy_qp)(struct ibv_qp *qp); +- int (*post_send)(struct ibv_qp *qp, struct ibv_send_wr *wr, +- struct ibv_send_wr **bad_wr); +- int (*post_recv)(struct ibv_qp *qp, struct ibv_recv_wr *wr, +- struct ibv_recv_wr **bad_wr); +- struct ibv_ah * (*create_ah)(struct ibv_pd *pd, struct ibv_ah_attr *attr); +- int (*destroy_ah)(struct ibv_ah *ah); +- int (*attach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, +- uint16_t lid); +- int (*detach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, +- uint16_t lid); +- void (*async_event)(struct ibv_async_event *event); ++ int (*query_device)(struct ibv_context *context, ++ struct ibv_device_attr *device_attr); ++ int (*query_port)(struct ibv_context *context, uint8_t port_num, ++ struct ibv_port_attr *port_attr); ++ struct ibv_pd * (*alloc_pd)(struct ibv_context *context); ++ int (*dealloc_pd)(struct ibv_pd *pd); ++ struct ibv_mr * (*reg_mr)(struct ibv_pd *pd, void *addr, size_t length, ++ int access); ++ struct ibv_mr * (*rereg_mr)(struct ibv_mr *mr, int flags, ++ struct ibv_pd *pd, void *addr, size_t length, ++ int access); ++ int (*dereg_mr)(struct ibv_mr *mr); ++ struct ibv_mw * (*alloc_mw)(struct ibv_pd *pd, enum ibv_mw_type type); ++ int (*bind_mw)(struct ibv_qp *qp, struct ibv_mw *mw, ++ struct ibv_mw_bind *mw_bind); ++ int (*dealloc_mw)(struct ibv_mw *mw); ++ struct ibv_cq * (*create_cq)(struct ibv_context *context, int cqe, ++ struct ibv_comp_channel *channel, int comp_vector); ++ int (*poll_cq)(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc); ++ int (*req_notify_cq)(struct ibv_cq *cq, int solicited_only); ++ void (*cq_event)(struct ibv_cq *cq); ++ int (*resize_cq)(struct ibv_cq *cq, int cqe); ++ int (*destroy_cq)(struct ibv_cq *cq); ++ struct ibv_srq * (*create_srq)(struct ibv_pd *pd, ++ struct ibv_srq_init_attr *srq_init_attr); ++ int (*modify_srq)(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr, ++ int srq_attr_mask); ++ int (*query_srq)(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr); ++ int (*destroy_srq)(struct ibv_srq *srq); ++ int (*post_srq_recv)(struct ibv_srq *srq, struct ibv_recv_wr *recv_wr, ++ struct ibv_recv_wr **bad_recv_wr); ++ struct ibv_qp * (*create_qp)(struct ibv_pd *pd, ++ struct ibv_qp_init_attr *attr); ++ int (*query_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, ++ int attr_mask, struct ibv_qp_init_attr *init_attr); ++ int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, ++ int attr_mask); ++ int (*destroy_qp)(struct ibv_qp *qp); ++ int (*post_send)(struct ibv_qp *qp, struct ibv_send_wr *wr, ++ struct ibv_send_wr **bad_wr); ++ int (*post_recv)(struct ibv_qp *qp, struct ibv_recv_wr *wr, ++ struct ibv_recv_wr **bad_wr); ++ struct ibv_ah * (*create_ah)(struct ibv_pd *pd, ++ struct ibv_ah_attr *attr); ++ int (*destroy_ah)(struct ibv_ah *ah); ++ int (*attach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, ++ uint16_t lid); ++ int (*detach_mcast)(struct ibv_qp *qp, const union ibv_gid *gid, ++ uint16_t lid); ++ void (*async_event)(struct ibv_async_event *event); + }; + + struct ibv_context { +- struct ibv_device *device; +- struct ibv_context_ops ops; +- int cmd_fd; +- int async_fd; +- int num_comp_vectors; +- pthread_mutex_t mutex; +- void *abi_compat; ++ struct ibv_device *device; ++ struct ibv_context_ops ops; ++ int cmd_fd; ++ int async_fd; ++ int num_comp_vectors; ++ pthread_mutex_t mutex; ++ void *abi_compat; + }; + + enum verbs_context_mask { +- VERBS_CONTEXT_RESERVED = 1 << 0 ++ VERBS_CONTEXT_XRCD = 1 << 0, ++ VERBS_CONTEXT_RESERVED = 1 << 1 + }; + + 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 ++ */ ++ 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 */ + }; + +-static inline struct verbs_context *verbs_get_ctx( +- const struct ibv_context *ctx) +-{ ++static inline struct verbs_context *verbs_get_ctx(const struct ibv_context *ctx) { + return (ctx->abi_compat != ((uint8_t *) NULL) - 1) ? +- NULL : container_of(ctx, struct verbs_context, context); ++ NULL : container_of(ctx, struct verbs_context, context); + } + ++#define verbs_get_ctx_op(ctx, op) ({ \ ++ struct verbs_context *vctx = verbs_get_ctx(ctx); \ ++ (!vctx || (vctx->sz < sizeof(*vctx) - offsetof(struct verbs_context, op)) || \ ++ !vctx->op) ? NULL : vctx; }) ++ + static inline struct verbs_device *verbs_get_device( +- const struct ibv_device *dev) +-{ ++ const struct ibv_device *dev) { + return (dev->ops.alloc_context) ? +- NULL : container_of(dev, struct verbs_device, device); ++ NULL : container_of(dev, struct verbs_device, device); + } + + /** +@@ -806,7 +812,7 @@ int ibv_close_device(struct ibv_context *context); + * be acknowledged with ibv_ack_async_event(). + */ + int ibv_get_async_event(struct ibv_context *context, +- struct ibv_async_event *event); ++ struct ibv_async_event *event); + + /** + * ibv_ack_async_event - Acknowledge an async event +@@ -824,21 +830,19 @@ void ibv_ack_async_event(struct ibv_async_event *event); + * ibv_query_device - Get device properties + */ + int ibv_query_device(struct ibv_context *context, +- struct ibv_device_attr *device_attr); ++ struct ibv_device_attr *device_attr); + + /** + * ibv_query_port - Get port properties + */ + int ibv_query_port(struct ibv_context *context, uint8_t port_num, +- struct ibv_port_attr *port_attr); ++ struct ibv_port_attr *port_attr); + + static inline int ___ibv_query_port(struct ibv_context *context, +- uint8_t port_num, +- struct ibv_port_attr *port_attr) +-{ +- /* For compatability when running with old libibverbs */ ++ uint8_t port_num, struct ibv_port_attr *port_attr) { ++ /* For compatibility when running with old libibverbs */ + port_attr->link_layer = IBV_LINK_LAYER_UNSPECIFIED; +- port_attr->reserved = 0; ++ port_attr->reserved = 0; + + return ibv_query_port(context, port_num, port_attr); + } +@@ -849,14 +853,14 @@ static inline int ___ibv_query_port(struct ibv_context *context, + /** + * ibv_query_gid - Get a GID table entry + */ +-int ibv_query_gid(struct ibv_context *context, uint8_t port_num, +- int index, union ibv_gid *gid); ++int ibv_query_gid(struct ibv_context *context, uint8_t port_num, int index, ++ union ibv_gid *gid); + + /** + * ibv_query_pkey - Get a P_Key table entry + */ +-int ibv_query_pkey(struct ibv_context *context, uint8_t port_num, +- int index, uint16_t *pkey); ++int ibv_query_pkey(struct ibv_context *context, uint8_t port_num, int index, ++ uint16_t *pkey); + + /** + * ibv_alloc_pd - Allocate a protection domain +@@ -869,10 +873,31 @@ struct ibv_pd *ibv_alloc_pd(struct ibv_context *context); + int ibv_dealloc_pd(struct ibv_pd *pd); + + /** ++ * ibv_open_xrcd - Open an extended connection domain ++ */ ++static inline struct ibv_xrcd * ++ibv_open_xrcd(struct ibv_context *context, struct ibv_xrcd_init_attr *xrcd_init_attr) { ++ struct verbs_context *vctx = verbs_get_ctx_op(context, open_xrcd); ++ if (!vctx) { ++ errno = ENOSYS; ++ return NULL; ++ } ++ return vctx->open_xrcd(context, xrcd_init_attr); ++} ++ ++/** ++ * ibv_close_xrcd - Close an extended connection domain ++ */ ++static inline int ibv_close_xrcd(struct ibv_xrcd *xrcd) { ++ struct verbs_context *vctx = verbs_get_ctx(xrcd->context); ++ return vctx->close_xrcd(xrcd); ++} ++ ++/** + * ibv_reg_mr - Register a memory region + */ +-struct ibv_mr *ibv_reg_mr(struct ibv_pd *pd, void *addr, +- size_t length, int access); ++struct ibv_mr *ibv_reg_mr(struct ibv_pd *pd, void *addr, size_t length, ++ int access); + + /** + * ibv_dereg_mr - Deregister a memory region +@@ -900,9 +925,8 @@ int ibv_destroy_comp_channel(struct ibv_comp_channel *channel); + * Must be >= 0 and < context->num_comp_vectors. + */ + struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe, +- void *cq_context, +- struct ibv_comp_channel *channel, +- int comp_vector); ++ void *cq_context, struct ibv_comp_channel *channel, ++ int comp_vector); + + /** + * ibv_resize_cq - Modifies the capacity of the CQ. +@@ -927,8 +951,8 @@ int ibv_destroy_cq(struct ibv_cq *cq); + * All completion events returned by ibv_get_cq_event() must + * eventually be acknowledged with ibv_ack_cq_events(). + */ +-int ibv_get_cq_event(struct ibv_comp_channel *channel, +- struct ibv_cq **cq, void **cq_context); ++int ibv_get_cq_event(struct ibv_comp_channel *channel, struct ibv_cq **cq, ++ void **cq_context); + + /** + * ibv_ack_cq_events - Acknowledge CQ completion events +@@ -958,8 +982,8 @@ void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents); + * non-negative and strictly less than num_entries, then the CQ was + * emptied. + */ +-static inline int ibv_poll_cq(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc) +-{ ++static inline int ibv_poll_cq(struct ibv_cq *cq, int num_entries, ++ struct ibv_wc *wc) { + return cq->context->ops.poll_cq(cq, num_entries, wc); + } + +@@ -972,8 +996,7 @@ static inline int ibv_poll_cq(struct ibv_cq *cq, int num_entries, struct ibv_wc + * the next solicited CQ entry. If zero, any CQ entry, solicited or + * not, will generate an event. + */ +-static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only) +-{ ++static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only) { + return cq->context->ops.req_notify_cq(cq, solicited_only); + } + +@@ -989,7 +1012,7 @@ static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only) + * will always be at least as large as the requested values. + */ + struct ibv_srq *ibv_create_srq(struct ibv_pd *pd, +- struct ibv_srq_init_attr *srq_init_attr); ++ struct ibv_srq_init_attr *srq_init_attr); + + /** + * ibv_modify_srq - Modifies the attributes for the specified SRQ. +@@ -1003,9 +1026,8 @@ struct ibv_srq *ibv_create_srq(struct ibv_pd *pd, + * IBV_SRQ_LIMIT to set the SRQ's limit and request notification when + * the number of receives queued drops below the limit. + */ +-int ibv_modify_srq(struct ibv_srq *srq, +- struct ibv_srq_attr *srq_attr, +- int srq_attr_mask); ++int ibv_modify_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr, ++ int srq_attr_mask); + + /** + * ibv_query_srq - Returns the attribute list and current values for the +@@ -1029,9 +1051,7 @@ int ibv_destroy_srq(struct ibv_srq *srq); + * the work request that failed to be posted on the QP. + */ + static inline int ibv_post_srq_recv(struct ibv_srq *srq, +- struct ibv_recv_wr *recv_wr, +- struct ibv_recv_wr **bad_recv_wr) +-{ ++ struct ibv_recv_wr *recv_wr, struct ibv_recv_wr **bad_recv_wr) { + return srq->context->ops.post_srq_recv(srq, recv_wr, bad_recv_wr); + } + +@@ -1039,13 +1059,12 @@ static inline int ibv_post_srq_recv(struct ibv_srq *srq, + * ibv_create_qp - Create a queue pair. + */ + struct ibv_qp *ibv_create_qp(struct ibv_pd *pd, +- struct ibv_qp_init_attr *qp_init_attr); ++ struct ibv_qp_init_attr *qp_init_attr); + + /** + * ibv_modify_qp - Modify a queue pair. + */ +-int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, +- int attr_mask); ++int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask); + + /** + * ibv_query_qp - Returns the attribute list and current values for the +@@ -1058,9 +1077,8 @@ int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, + * The qp_attr_mask may be used to limit the query to gathering only the + * selected attributes. + */ +-int ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, +- int attr_mask, +- struct ibv_qp_init_attr *init_attr); ++int ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask, ++ struct ibv_qp_init_attr *init_attr); + + /** + * ibv_destroy_qp - Destroy a queue pair. +@@ -1074,8 +1092,7 @@ int ibv_destroy_qp(struct ibv_qp *qp); + * immediately after the call returns. + */ + static inline int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr, +- struct ibv_send_wr **bad_wr) +-{ ++ struct ibv_send_wr **bad_wr) { + return qp->context->ops.post_send(qp, wr, bad_wr); + } + +@@ -1083,8 +1100,7 @@ static inline int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr, + * ibv_post_recv - Post a list of work requests to a receive queue. + */ + static inline int ibv_post_recv(struct ibv_qp *qp, struct ibv_recv_wr *wr, +- struct ibv_recv_wr **bad_wr) +-{ ++ struct ibv_recv_wr **bad_wr) { + return qp->context->ops.post_recv(qp, wr, bad_wr); + } + +@@ -1105,8 +1121,8 @@ struct ibv_ah *ibv_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr); + * handle for replying to the message. + */ + int ibv_init_ah_from_wc(struct ibv_context *context, uint8_t port_num, +- struct ibv_wc *wc, struct ibv_grh *grh, +- struct ibv_ah_attr *ah_attr); ++ struct ibv_wc *wc, struct ibv_grh *grh, ++ struct ibv_ah_attr *ah_attr); + + /** + * ibv_create_ah_from_wc - Creates an address handle associated with the +@@ -1121,7 +1137,7 @@ int ibv_init_ah_from_wc(struct ibv_context *context, uint8_t port_num, + * in all UD QP post sends. + */ + struct ibv_ah *ibv_create_ah_from_wc(struct ibv_pd *pd, struct ibv_wc *wc, +- struct ibv_grh *grh, uint8_t port_num); ++ struct ibv_grh *grh, uint8_t port_num); + + /** + * ibv_destroy_ah - Destroy an address handle. +@@ -1176,5 +1192,4 @@ END_C_DECLS + + # undef __attribute_const + +- + #endif /* INFINIBAND_VERBS_H */ +diff --git a/src/cmd.c b/src/cmd.c +index dab8930..f0fb1dc 100644 +--- a/src/cmd.c ++++ b/src/cmd.c +@@ -194,6 +194,47 @@ int ibv_cmd_dealloc_pd(struct ibv_pd *pd) + return 0; + } + ++int ibv_cmd_open_xrcd(struct ibv_context *context, struct verbs_xrcd *xrcd, ++ struct ibv_xrcd_init_attr *attr, ++ struct ibv_open_xrcd *cmd, size_t cmd_size, ++ struct ibv_open_xrcd_resp *resp, size_t resp_size) ++{ ++ IBV_INIT_CMD_RESP(cmd, cmd_size, OPEN_XRCD, resp, resp_size); ++ ++ if (attr->comp_mask >= IBV_XRCD_INIT_ATTR_RESERVED) ++ return ENOSYS; ++ ++ if (!(attr->comp_mask & IBV_XRCD_INIT_ATTR_FD) || ++ !(attr->comp_mask & IBV_XRCD_INIT_ATTR_OFLAGS)) ++ return EINVAL; ++ ++ cmd->fd = attr->fd; ++ cmd->oflags = attr->oflags; ++ if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) ++ return errno; ++ ++ VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); ++ ++ xrcd->xrcd.context = context; ++ xrcd->comp_mask = VERBS_XRCD_HANDLE; ++ xrcd->handle = resp->xrcd_handle; ++ ++ return 0; ++} ++ ++int ibv_cmd_close_xrcd(struct verbs_xrcd *xrcd) ++{ ++ struct ibv_close_xrcd cmd; ++ ++ IBV_INIT_CMD(&cmd, sizeof cmd, CLOSE_XRCD); ++ cmd.xrcd_handle = xrcd->handle; ++ ++ if (write(xrcd->xrcd.context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) ++ return errno; ++ ++ return 0; ++} ++ + int ibv_cmd_reg_mr(struct ibv_pd *pd, void *addr, size_t length, + uint64_t hca_va, int access, + struct ibv_mr *mr, struct ibv_reg_mr *cmd, +diff --git a/src/libibverbs.map b/src/libibverbs.map +index ee9adea..9a15f3f 100644 +--- a/src/libibverbs.map ++++ b/src/libibverbs.map +@@ -97,4 +97,8 @@ IBVERBS_1.1 { + ibv_port_state_str; + ibv_event_type_str; + ibv_wc_status_str; ++ ++ ibv_cmd_open_xrcd; ++ ibv_cmd_close_xrcd; ++ + } IBVERBS_1.0;