aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Cohen <eli@dev.mellanox.co.il>2014-12-11 10:04:15 -0500
committerRoland Dreier <roland@purestorage.com>2014-12-15 21:13:35 -0500
commit5a77abf9a97a7ecc8fb0f6bf4ad411fb12b02f31 (patch)
tree2fbcf2c088cde299781ef0104c165f595aebd415
parentc1395a2a8c01e8a919e47d64eb3d23d00e824b8b (diff)
IB/core: Add support for extended query device caps
Add extensible query device capabilities verb to allow adding new features. ib_uverbs_ex_query_device is added and copy_query_dev_fields is used to copy capability fields to be used by both ib_uverbs_query_device and ib_uverbs_ex_query_device. Signed-off-by: Eli Cohen <eli@mellanox.com> Signed-off-by: Haggai Eran <haggaie@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/core/uverbs.h1
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c124
-rw-r--r--drivers/infiniband/core/uverbs_main.c3
-rw-r--r--include/rdma/ib_verbs.h5
-rw-r--r--include/uapi/rdma/ib_user_verbs.h14
5 files changed, 103 insertions, 44 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index 643c08a025a5..b716b0815644 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -258,5 +258,6 @@ IB_UVERBS_DECLARE_CMD(close_xrcd);
258 258
259IB_UVERBS_DECLARE_EX_CMD(create_flow); 259IB_UVERBS_DECLARE_EX_CMD(create_flow);
260IB_UVERBS_DECLARE_EX_CMD(destroy_flow); 260IB_UVERBS_DECLARE_EX_CMD(destroy_flow);
261IB_UVERBS_DECLARE_EX_CMD(query_device);
261 262
262#endif /* UVERBS_H */ 263#endif /* UVERBS_H */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 5ba2a86aab6a..c7a43624c96b 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -378,6 +378,52 @@ err:
378 return ret; 378 return ret;
379} 379}
380 380
381static void copy_query_dev_fields(struct ib_uverbs_file *file,
382 struct ib_uverbs_query_device_resp *resp,
383 struct ib_device_attr *attr)
384{
385 resp->fw_ver = attr->fw_ver;
386 resp->node_guid = file->device->ib_dev->node_guid;
387 resp->sys_image_guid = attr->sys_image_guid;
388 resp->max_mr_size = attr->max_mr_size;
389 resp->page_size_cap = attr->page_size_cap;
390 resp->vendor_id = attr->vendor_id;
391 resp->vendor_part_id = attr->vendor_part_id;
392 resp->hw_ver = attr->hw_ver;
393 resp->max_qp = attr->max_qp;
394 resp->max_qp_wr = attr->max_qp_wr;
395 resp->device_cap_flags = attr->device_cap_flags;
396 resp->max_sge = attr->max_sge;
397 resp->max_sge_rd = attr->max_sge_rd;
398 resp->max_cq = attr->max_cq;
399 resp->max_cqe = attr->max_cqe;
400 resp->max_mr = attr->max_mr;
401 resp->max_pd = attr->max_pd;
402 resp->max_qp_rd_atom = attr->max_qp_rd_atom;
403 resp->max_ee_rd_atom = attr->max_ee_rd_atom;
404 resp->max_res_rd_atom = attr->max_res_rd_atom;
405 resp->max_qp_init_rd_atom = attr->max_qp_init_rd_atom;
406 resp->max_ee_init_rd_atom = attr->max_ee_init_rd_atom;
407 resp->atomic_cap = attr->atomic_cap;
408 resp->max_ee = attr->max_ee;
409 resp->max_rdd = attr->max_rdd;
410 resp->max_mw = attr->max_mw;
411 resp->max_raw_ipv6_qp = attr->max_raw_ipv6_qp;
412 resp->max_raw_ethy_qp = attr->max_raw_ethy_qp;
413 resp->max_mcast_grp = attr->max_mcast_grp;
414 resp->max_mcast_qp_attach = attr->max_mcast_qp_attach;
415 resp->max_total_mcast_qp_attach = attr->max_total_mcast_qp_attach;
416 resp->max_ah = attr->max_ah;
417 resp->max_fmr = attr->max_fmr;
418 resp->max_map_per_fmr = attr->max_map_per_fmr;
419 resp->max_srq = attr->max_srq;
420 resp->max_srq_wr = attr->max_srq_wr;
421 resp->max_srq_sge = attr->max_srq_sge;
422 resp->max_pkeys = attr->max_pkeys;
423 resp->local_ca_ack_delay = attr->local_ca_ack_delay;
424 resp->phys_port_cnt = file->device->ib_dev->phys_port_cnt;
425}
426
381ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, 427ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
382 const char __user *buf, 428 const char __user *buf,
383 int in_len, int out_len) 429 int in_len, int out_len)
@@ -398,47 +444,7 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
398 return ret; 444 return ret;
399 445
400 memset(&resp, 0, sizeof resp); 446 memset(&resp, 0, sizeof resp);
401 447 copy_query_dev_fields(file, &resp, &attr);
402 resp.fw_ver = attr.fw_ver;
403 resp.node_guid = file->device->ib_dev->node_guid;
404 resp.sys_image_guid = attr.sys_image_guid;
405 resp.max_mr_size = attr.max_mr_size;
406 resp.page_size_cap = attr.page_size_cap;
407 resp.vendor_id = attr.vendor_id;
408 resp.vendor_part_id = attr.vendor_part_id;
409 resp.hw_ver = attr.hw_ver;
410 resp.max_qp = attr.max_qp;
411 resp.max_qp_wr = attr.max_qp_wr;
412 resp.device_cap_flags = attr.device_cap_flags;
413 resp.max_sge = attr.max_sge;
414 resp.max_sge_rd = attr.max_sge_rd;
415 resp.max_cq = attr.max_cq;
416 resp.max_cqe = attr.max_cqe;
417 resp.max_mr = attr.max_mr;
418 resp.max_pd = attr.max_pd;
419 resp.max_qp_rd_atom = attr.max_qp_rd_atom;
420 resp.max_ee_rd_atom = attr.max_ee_rd_atom;
421 resp.max_res_rd_atom = attr.max_res_rd_atom;
422 resp.max_qp_init_rd_atom = attr.max_qp_init_rd_atom;
423 resp.max_ee_init_rd_atom = attr.max_ee_init_rd_atom;
424 resp.atomic_cap = attr.atomic_cap;
425 resp.max_ee = attr.max_ee;
426 resp.max_rdd = attr.max_rdd;
427 resp.max_mw = attr.max_mw;
428 resp.max_raw_ipv6_qp = attr.max_raw_ipv6_qp;
429 resp.max_raw_ethy_qp = attr.max_raw_ethy_qp;
430 resp.max_mcast_grp = attr.max_mcast_grp;
431 resp.max_mcast_qp_attach = attr.max_mcast_qp_attach;
432 resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach;
433 resp.max_ah = attr.max_ah;
434 resp.max_fmr = attr.max_fmr;
435 resp.max_map_per_fmr = attr.max_map_per_fmr;
436 resp.max_srq = attr.max_srq;
437 resp.max_srq_wr = attr.max_srq_wr;
438 resp.max_srq_sge = attr.max_srq_sge;
439 resp.max_pkeys = attr.max_pkeys;
440 resp.local_ca_ack_delay = attr.local_ca_ack_delay;
441 resp.phys_port_cnt = file->device->ib_dev->phys_port_cnt;
442 448
443 if (copy_to_user((void __user *) (unsigned long) cmd.response, 449 if (copy_to_user((void __user *) (unsigned long) cmd.response,
444 &resp, sizeof resp)) 450 &resp, sizeof resp))
@@ -3253,3 +3259,39 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
3253 3259
3254 return ret ? ret : in_len; 3260 return ret ? ret : in_len;
3255} 3261}
3262
3263int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
3264 struct ib_udata *ucore,
3265 struct ib_udata *uhw)
3266{
3267 struct ib_uverbs_ex_query_device_resp resp;
3268 struct ib_uverbs_ex_query_device cmd;
3269 struct ib_device_attr attr;
3270 struct ib_device *device;
3271 int err;
3272
3273 device = file->device->ib_dev;
3274 if (ucore->inlen < sizeof(cmd))
3275 return -EINVAL;
3276
3277 err = ib_copy_from_udata(&cmd, ucore, sizeof(cmd));
3278 if (err)
3279 return err;
3280
3281 if (cmd.reserved)
3282 return -EINVAL;
3283
3284 err = device->query_device(device, &attr);
3285 if (err)
3286 return err;
3287
3288 memset(&resp, 0, sizeof(resp));
3289 copy_query_dev_fields(file, &resp.base, &attr);
3290 resp.comp_mask = 0;
3291
3292 err = ib_copy_to_udata(ucore, &resp, sizeof(resp));
3293 if (err)
3294 return err;
3295
3296 return 0;
3297}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 71ab83fde472..974025028790 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -122,7 +122,8 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file,
122 struct ib_udata *ucore, 122 struct ib_udata *ucore,
123 struct ib_udata *uhw) = { 123 struct ib_udata *uhw) = {
124 [IB_USER_VERBS_EX_CMD_CREATE_FLOW] = ib_uverbs_ex_create_flow, 124 [IB_USER_VERBS_EX_CMD_CREATE_FLOW] = ib_uverbs_ex_create_flow,
125 [IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow 125 [IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow,
126 [IB_USER_VERBS_EX_CMD_QUERY_DEVICE] = ib_uverbs_ex_query_device
126}; 127};
127 128
128static void ib_uverbs_add_one(struct ib_device *device); 129static void ib_uverbs_add_one(struct ib_device *device);
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 470a011d6fa4..97a999f9e4d8 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1662,7 +1662,10 @@ static inline int ib_copy_from_udata(void *dest, struct ib_udata *udata, size_t
1662 1662
1663static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len) 1663static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len)
1664{ 1664{
1665 return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0; 1665 size_t copy_sz;
1666
1667 copy_sz = min_t(size_t, len, udata->outlen);
1668 return copy_to_user(udata->outbuf, src, copy_sz) ? -EFAULT : 0;
1666} 1669}
1667 1670
1668/** 1671/**
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h
index 26daf55ff76e..e8a96071e352 100644
--- a/include/uapi/rdma/ib_user_verbs.h
+++ b/include/uapi/rdma/ib_user_verbs.h
@@ -90,8 +90,9 @@ enum {
90}; 90};
91 91
92enum { 92enum {
93 IB_USER_VERBS_EX_CMD_QUERY_DEVICE = IB_USER_VERBS_CMD_QUERY_DEVICE,
93 IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD, 94 IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD,
94 IB_USER_VERBS_EX_CMD_DESTROY_FLOW 95 IB_USER_VERBS_EX_CMD_DESTROY_FLOW,
95}; 96};
96 97
97/* 98/*
@@ -201,6 +202,17 @@ struct ib_uverbs_query_device_resp {
201 __u8 reserved[4]; 202 __u8 reserved[4];
202}; 203};
203 204
205struct ib_uverbs_ex_query_device {
206 __u32 comp_mask;
207 __u32 reserved;
208};
209
210struct ib_uverbs_ex_query_device_resp {
211 struct ib_uverbs_query_device_resp base;
212 __u32 comp_mask;
213 __u32 reserved;
214};
215
204struct ib_uverbs_query_port { 216struct ib_uverbs_query_port {
205 __u64 response; 217 __u64 response;
206 __u8 port_num; 218 __u8 port_num;