mirror of
https://github.com/torvalds/linux.git
synced 2024-10-31 17:21:49 +00:00
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>
This commit is contained in:
parent
a74cd4af0b
commit
7ccc9a24e0
@ -183,6 +183,7 @@ IB_UVERBS_DECLARE_CMD(poll_cq);
|
||||
IB_UVERBS_DECLARE_CMD(req_notify_cq);
|
||||
IB_UVERBS_DECLARE_CMD(destroy_cq);
|
||||
IB_UVERBS_DECLARE_CMD(create_qp);
|
||||
IB_UVERBS_DECLARE_CMD(query_qp);
|
||||
IB_UVERBS_DECLARE_CMD(modify_qp);
|
||||
IB_UVERBS_DECLARE_CMD(destroy_qp);
|
||||
IB_UVERBS_DECLARE_CMD(post_send);
|
||||
|
@ -996,6 +996,106 @@ err_up:
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
|
||||
const char __user *buf, int in_len,
|
||||
int out_len)
|
||||
{
|
||||
struct ib_uverbs_query_qp cmd;
|
||||
struct ib_uverbs_query_qp_resp resp;
|
||||
struct ib_qp *qp;
|
||||
struct ib_qp_attr *attr;
|
||||
struct ib_qp_init_attr *init_attr;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(&cmd, buf, sizeof cmd))
|
||||
return -EFAULT;
|
||||
|
||||
attr = kmalloc(sizeof *attr, GFP_KERNEL);
|
||||
init_attr = kmalloc(sizeof *init_attr, GFP_KERNEL);
|
||||
if (!attr || !init_attr) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&ib_uverbs_idr_mutex);
|
||||
|
||||
qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
|
||||
if (qp && qp->uobject->context == file->ucontext)
|
||||
ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
||||
mutex_unlock(&ib_uverbs_idr_mutex);
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
memset(&resp, 0, sizeof resp);
|
||||
|
||||
resp.qp_state = attr->qp_state;
|
||||
resp.cur_qp_state = attr->cur_qp_state;
|
||||
resp.path_mtu = attr->path_mtu;
|
||||
resp.path_mig_state = attr->path_mig_state;
|
||||
resp.qkey = attr->qkey;
|
||||
resp.rq_psn = attr->rq_psn;
|
||||
resp.sq_psn = attr->sq_psn;
|
||||
resp.dest_qp_num = attr->dest_qp_num;
|
||||
resp.qp_access_flags = attr->qp_access_flags;
|
||||
resp.pkey_index = attr->pkey_index;
|
||||
resp.alt_pkey_index = attr->alt_pkey_index;
|
||||
resp.en_sqd_async_notify = attr->en_sqd_async_notify;
|
||||
resp.max_rd_atomic = attr->max_rd_atomic;
|
||||
resp.max_dest_rd_atomic = attr->max_dest_rd_atomic;
|
||||
resp.min_rnr_timer = attr->min_rnr_timer;
|
||||
resp.port_num = attr->port_num;
|
||||
resp.timeout = attr->timeout;
|
||||
resp.retry_cnt = attr->retry_cnt;
|
||||
resp.rnr_retry = attr->rnr_retry;
|
||||
resp.alt_port_num = attr->alt_port_num;
|
||||
resp.alt_timeout = attr->alt_timeout;
|
||||
|
||||
memcpy(resp.dest.dgid, attr->ah_attr.grh.dgid.raw, 16);
|
||||
resp.dest.flow_label = attr->ah_attr.grh.flow_label;
|
||||
resp.dest.sgid_index = attr->ah_attr.grh.sgid_index;
|
||||
resp.dest.hop_limit = attr->ah_attr.grh.hop_limit;
|
||||
resp.dest.traffic_class = attr->ah_attr.grh.traffic_class;
|
||||
resp.dest.dlid = attr->ah_attr.dlid;
|
||||
resp.dest.sl = attr->ah_attr.sl;
|
||||
resp.dest.src_path_bits = attr->ah_attr.src_path_bits;
|
||||
resp.dest.static_rate = attr->ah_attr.static_rate;
|
||||
resp.dest.is_global = !!(attr->ah_attr.ah_flags & IB_AH_GRH);
|
||||
resp.dest.port_num = attr->ah_attr.port_num;
|
||||
|
||||
memcpy(resp.alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16);
|
||||
resp.alt_dest.flow_label = attr->alt_ah_attr.grh.flow_label;
|
||||
resp.alt_dest.sgid_index = attr->alt_ah_attr.grh.sgid_index;
|
||||
resp.alt_dest.hop_limit = attr->alt_ah_attr.grh.hop_limit;
|
||||
resp.alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class;
|
||||
resp.alt_dest.dlid = attr->alt_ah_attr.dlid;
|
||||
resp.alt_dest.sl = attr->alt_ah_attr.sl;
|
||||
resp.alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits;
|
||||
resp.alt_dest.static_rate = attr->alt_ah_attr.static_rate;
|
||||
resp.alt_dest.is_global = !!(attr->alt_ah_attr.ah_flags & IB_AH_GRH);
|
||||
resp.alt_dest.port_num = attr->alt_ah_attr.port_num;
|
||||
|
||||
resp.max_send_wr = init_attr->cap.max_send_wr;
|
||||
resp.max_recv_wr = init_attr->cap.max_recv_wr;
|
||||
resp.max_send_sge = init_attr->cap.max_send_sge;
|
||||
resp.max_recv_sge = init_attr->cap.max_recv_sge;
|
||||
resp.max_inline_data = init_attr->cap.max_inline_data;
|
||||
resp.sq_sig_all = !!init_attr->sq_sig_type;
|
||||
|
||||
if (copy_to_user((void __user *) (unsigned long) cmd.response,
|
||||
&resp, sizeof resp))
|
||||
ret = -EFAULT;
|
||||
|
||||
out:
|
||||
kfree(attr);
|
||||
kfree(init_attr);
|
||||
|
||||
return ret ? ret : in_len;
|
||||
}
|
||||
|
||||
ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
|
||||
const char __user *buf, int in_len,
|
||||
int out_len)
|
||||
|
@ -96,6 +96,7 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
|
||||
[IB_USER_VERBS_CMD_REQ_NOTIFY_CQ] = ib_uverbs_req_notify_cq,
|
||||
[IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq,
|
||||
[IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp,
|
||||
[IB_USER_VERBS_CMD_QUERY_QP] = ib_uverbs_query_qp,
|
||||
[IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp,
|
||||
[IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp,
|
||||
[IB_USER_VERBS_CMD_POST_SEND] = ib_uverbs_post_send,
|
||||
|
@ -370,6 +370,47 @@ struct ib_uverbs_qp_dest {
|
||||
__u8 port_num;
|
||||
};
|
||||
|
||||
struct ib_uverbs_query_qp {
|
||||
__u64 response;
|
||||
__u32 qp_handle;
|
||||
__u32 attr_mask;
|
||||
__u64 driver_data[0];
|
||||
};
|
||||
|
||||
struct ib_uverbs_query_qp_resp {
|
||||
struct ib_uverbs_qp_dest dest;
|
||||
struct ib_uverbs_qp_dest alt_dest;
|
||||
__u32 max_send_wr;
|
||||
__u32 max_recv_wr;
|
||||
__u32 max_send_sge;
|
||||
__u32 max_recv_sge;
|
||||
__u32 max_inline_data;
|
||||
__u32 qkey;
|
||||
__u32 rq_psn;
|
||||
__u32 sq_psn;
|
||||
__u32 dest_qp_num;
|
||||
__u32 qp_access_flags;
|
||||
__u16 pkey_index;
|
||||
__u16 alt_pkey_index;
|
||||
__u8 qp_state;
|
||||
__u8 cur_qp_state;
|
||||
__u8 path_mtu;
|
||||
__u8 path_mig_state;
|
||||
__u8 en_sqd_async_notify;
|
||||
__u8 max_rd_atomic;
|
||||
__u8 max_dest_rd_atomic;
|
||||
__u8 min_rnr_timer;
|
||||
__u8 port_num;
|
||||
__u8 timeout;
|
||||
__u8 retry_cnt;
|
||||
__u8 rnr_retry;
|
||||
__u8 alt_port_num;
|
||||
__u8 alt_timeout;
|
||||
__u8 sq_sig_all;
|
||||
__u8 reserved[5];
|
||||
__u64 driver_data[0];
|
||||
};
|
||||
|
||||
struct ib_uverbs_modify_qp {
|
||||
struct ib_uverbs_qp_dest dest;
|
||||
struct ib_uverbs_qp_dest alt_dest;
|
||||
|
Loading…
Reference in New Issue
Block a user