diff options
author | Dotan Barak <dotanb@mellanox.co.il> | 2006-02-13 19:31:25 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-03-20 13:08:14 -0500 |
commit | 7ccc9a24e01258a31ee2b964215e4ddddd2a02c4 (patch) | |
tree | 486ab72c62f42952309ea764bc6bd30f56e87522 /drivers/infiniband | |
parent | a74cd4af0bfa9578594acbb711a958104c93b772 (diff) |
IB/uverbs: Support for query QP from userspace
Add support to uverbs to handle querying userspace QPs (queue pairs),
including adding an ABI for marshalling requests and responses. The
kernel midlayer already has the underlying ib_query_qp() function.
Signed-off-by: Dotan Barak <dotanb@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 100 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 1 |
3 files changed, 102 insertions, 0 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 3207239819ce..89c798eb5749 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -183,6 +183,7 @@ IB_UVERBS_DECLARE_CMD(poll_cq); | |||
183 | IB_UVERBS_DECLARE_CMD(req_notify_cq); | 183 | IB_UVERBS_DECLARE_CMD(req_notify_cq); |
184 | IB_UVERBS_DECLARE_CMD(destroy_cq); | 184 | IB_UVERBS_DECLARE_CMD(destroy_cq); |
185 | IB_UVERBS_DECLARE_CMD(create_qp); | 185 | IB_UVERBS_DECLARE_CMD(create_qp); |
186 | IB_UVERBS_DECLARE_CMD(query_qp); | ||
186 | IB_UVERBS_DECLARE_CMD(modify_qp); | 187 | IB_UVERBS_DECLARE_CMD(modify_qp); |
187 | IB_UVERBS_DECLARE_CMD(destroy_qp); | 188 | IB_UVERBS_DECLARE_CMD(destroy_qp); |
188 | IB_UVERBS_DECLARE_CMD(post_send); | 189 | IB_UVERBS_DECLARE_CMD(post_send); |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 398c125d908c..4cbef8c06634 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -996,6 +996,106 @@ err_up: | |||
996 | return ret; | 996 | return ret; |
997 | } | 997 | } |
998 | 998 | ||
999 | ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file, | ||
1000 | const char __user *buf, int in_len, | ||
1001 | int out_len) | ||
1002 | { | ||
1003 | struct ib_uverbs_query_qp cmd; | ||
1004 | struct ib_uverbs_query_qp_resp resp; | ||
1005 | struct ib_qp *qp; | ||
1006 | struct ib_qp_attr *attr; | ||
1007 | struct ib_qp_init_attr *init_attr; | ||
1008 | int ret; | ||
1009 | |||
1010 | if (copy_from_user(&cmd, buf, sizeof cmd)) | ||
1011 | return -EFAULT; | ||
1012 | |||
1013 | attr = kmalloc(sizeof *attr, GFP_KERNEL); | ||
1014 | init_attr = kmalloc(sizeof *init_attr, GFP_KERNEL); | ||
1015 | if (!attr || !init_attr) { | ||
1016 | ret = -ENOMEM; | ||
1017 | goto out; | ||
1018 | } | ||
1019 | |||
1020 | mutex_lock(&ib_uverbs_idr_mutex); | ||
1021 | |||
1022 | qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); | ||
1023 | if (qp && qp->uobject->context == file->ucontext) | ||
1024 | ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr); | ||
1025 | else | ||
1026 | ret = -EINVAL; | ||
1027 | |||
1028 | mutex_unlock(&ib_uverbs_idr_mutex); | ||
1029 | |||
1030 | if (ret) | ||
1031 | goto out; | ||
1032 | |||
1033 | memset(&resp, 0, sizeof resp); | ||
1034 | |||
1035 | resp.qp_state = attr->qp_state; | ||
1036 | resp.cur_qp_state = attr->cur_qp_state; | ||
1037 | resp.path_mtu = attr->path_mtu; | ||
1038 | resp.path_mig_state = attr->path_mig_state; | ||
1039 | resp.qkey = attr->qkey; | ||
1040 | resp.rq_psn = attr->rq_psn; | ||
1041 | resp.sq_psn = attr->sq_psn; | ||
1042 | resp.dest_qp_num = attr->dest_qp_num; | ||
1043 | resp.qp_access_flags = attr->qp_access_flags; | ||
1044 | resp.pkey_index = attr->pkey_index; | ||
1045 | resp.alt_pkey_index = attr->alt_pkey_index; | ||
1046 | resp.en_sqd_async_notify = attr->en_sqd_async_notify; | ||
1047 | resp.max_rd_atomic = attr->max_rd_atomic; | ||
1048 | resp.max_dest_rd_atomic = attr->max_dest_rd_atomic; | ||
1049 | resp.min_rnr_timer = attr->min_rnr_timer; | ||
1050 | resp.port_num = attr->port_num; | ||
1051 | resp.timeout = attr->timeout; | ||
1052 | resp.retry_cnt = attr->retry_cnt; | ||
1053 | resp.rnr_retry = attr->rnr_retry; | ||
1054 | resp.alt_port_num = attr->alt_port_num; | ||
1055 | resp.alt_timeout = attr->alt_timeout; | ||
1056 | |||
1057 | memcpy(resp.dest.dgid, attr->ah_attr.grh.dgid.raw, 16); | ||
1058 | resp.dest.flow_label = attr->ah_attr.grh.flow_label; | ||
1059 | resp.dest.sgid_index = attr->ah_attr.grh.sgid_index; | ||
1060 | resp.dest.hop_limit = attr->ah_attr.grh.hop_limit; | ||
1061 | resp.dest.traffic_class = attr->ah_attr.grh.traffic_class; | ||
1062 | resp.dest.dlid = attr->ah_attr.dlid; | ||
1063 | resp.dest.sl = attr->ah_attr.sl; | ||
1064 | resp.dest.src_path_bits = attr->ah_attr.src_path_bits; | ||
1065 | resp.dest.static_rate = attr->ah_attr.static_rate; | ||
1066 | resp.dest.is_global = !!(attr->ah_attr.ah_flags & IB_AH_GRH); | ||
1067 | resp.dest.port_num = attr->ah_attr.port_num; | ||
1068 | |||
1069 | memcpy(resp.alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16); | ||
1070 | resp.alt_dest.flow_label = attr->alt_ah_attr.grh.flow_label; | ||
1071 | resp.alt_dest.sgid_index = attr->alt_ah_attr.grh.sgid_index; | ||
1072 | resp.alt_dest.hop_limit = attr->alt_ah_attr.grh.hop_limit; | ||
1073 | resp.alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class; | ||
1074 | resp.alt_dest.dlid = attr->alt_ah_attr.dlid; | ||
1075 | resp.alt_dest.sl = attr->alt_ah_attr.sl; | ||
1076 | resp.alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits; | ||
1077 | resp.alt_dest.static_rate = attr->alt_ah_attr.static_rate; | ||
1078 | resp.alt_dest.is_global = !!(attr->alt_ah_attr.ah_flags & IB_AH_GRH); | ||
1079 | resp.alt_dest.port_num = attr->alt_ah_attr.port_num; | ||
1080 | |||
1081 | resp.max_send_wr = init_attr->cap.max_send_wr; | ||
1082 | resp.max_recv_wr = init_attr->cap.max_recv_wr; | ||
1083 | resp.max_send_sge = init_attr->cap.max_send_sge; | ||
1084 | resp.max_recv_sge = init_attr->cap.max_recv_sge; | ||
1085 | resp.max_inline_data = init_attr->cap.max_inline_data; | ||
1086 | resp.sq_sig_all = !!init_attr->sq_sig_type; | ||
1087 | |||
1088 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | ||
1089 | &resp, sizeof resp)) | ||
1090 | ret = -EFAULT; | ||
1091 | |||
1092 | out: | ||
1093 | kfree(attr); | ||
1094 | kfree(init_attr); | ||
1095 | |||
1096 | return ret ? ret : in_len; | ||
1097 | } | ||
1098 | |||
999 | ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, | 1099 | ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, |
1000 | const char __user *buf, int in_len, | 1100 | const char __user *buf, int in_len, |
1001 | int out_len) | 1101 | int out_len) |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 335b6938a656..91e4750fa319 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -96,6 +96,7 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, | |||
96 | [IB_USER_VERBS_CMD_REQ_NOTIFY_CQ] = ib_uverbs_req_notify_cq, | 96 | [IB_USER_VERBS_CMD_REQ_NOTIFY_CQ] = ib_uverbs_req_notify_cq, |
97 | [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq, | 97 | [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq, |
98 | [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp, | 98 | [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp, |
99 | [IB_USER_VERBS_CMD_QUERY_QP] = ib_uverbs_query_qp, | ||
99 | [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp, | 100 | [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp, |
100 | [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, | 101 | [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, |
101 | [IB_USER_VERBS_CMD_POST_SEND] = ib_uverbs_post_send, | 102 | [IB_USER_VERBS_CMD_POST_SEND] = ib_uverbs_post_send, |