History

IB/uverbs: Extend modify_qp and support packet pacing

An new uverbs command ib_uverbs_ex_modify_qp is added to support more QP attributes. User driver should choose to call the legacy/extended API based on input mask. IB_USER_LAST_QP_ATTR_MASK is added to indicated the maximum bit position which supports legacy ib_uverbs_modify_qp. IB_USER_LEGACY_LAST_QP_ATTR_MASK indicates the maximum bit position which supports ib_uverbs_ex_modify_qp, the value of this mask should be updated if new mask is added later. Along with this change, rate_limit is supported by the extended command, user driver could use it to control packet packing.

Bodong Wang committed 9 years ago

Commit 189aba91 parent 528e5a14 files · +146 −69Browse files

Unified · Split

4 files
  1. drivers/infiniband/core/uverbs.h +1 −0
  2. drivers/infiniband/core/uverbs_cmd.c +123 −69
  3. drivers/infiniband/core/uverbs_main.c +1 −0
  4. include/uapi/rdma/ib_user_verbs.h +21 −0
drivers/infiniband/core/uverbs.h+1−0
@@ -289,5 +289,6 @@ IB_UVERBS_DECLARE_EX_CMD(modify_wq); · 288 unmodified lines
289289 IB_UVERBS_DECLARE_EX_CMD(destroy_wq);
290290 IB_UVERBS_DECLARE_EX_CMD(create_rwq_ind_table);
291291 IB_UVERBS_DECLARE_EX_CMD(destroy_rwq_ind_table);
292+IB_UVERBS_DECLARE_EX_CMD(modify_qp);
292293
293294 #endif /* UVERBS_H */
drivers/infiniband/core/uverbs_cmd.c+123−69
@@ -2328,96 +2328,88 @@ static int modify_qp_mask(enum ib_qp_type qp_type, int mask) · 2327 unmodified lines
23282328 }
23292329 }
23302330
2331−ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
2332− struct ib_device *ib_dev,
2333− const char __user *buf, int in_len,
2334− int out_len)
2331+static int modify_qp(struct ib_uverbs_file *file,
2332+ struct ib_uverbs_ex_modify_qp *cmd, struct ib_udata *udata)
23352333 {
2336− struct ib_uverbs_modify_qp cmd;
2337− struct ib_udata udata;
2338− struct ib_qp *qp;
2339− struct ib_qp_attr *attr;
2340− int ret;
2341−
2342− if (copy_from_user(&cmd, buf, sizeof cmd))
2343− return -EFAULT;
2344−
2345− INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd,
2346− out_len);
2334+ struct ib_qp_attr *attr;
2335+ struct ib_qp *qp;
2336+ int ret;
23472337
23482338 attr = kmalloc(sizeof *attr, GFP_KERNEL);
23492339 if (!attr)
23502340 return -ENOMEM;
23512341
2352− qp = idr_read_qp(cmd.qp_handle, file->ucontext);
2342+ qp = idr_read_qp(cmd->base.qp_handle, file->ucontext);
23532343 if (!qp) {
23542344 ret = -EINVAL;
23552345 goto out;
23562346 }
23572347
2358− attr->qp_state = cmd.qp_state;
2359− attr->cur_qp_state = cmd.cur_qp_state;
2360− attr->path_mtu = cmd.path_mtu;
2361− attr->path_mig_state = cmd.path_mig_state;
2362− attr->qkey = cmd.qkey;
2363− attr->rq_psn = cmd.rq_psn;
2364− attr->sq_psn = cmd.sq_psn;
2365− attr->dest_qp_num = cmd.dest_qp_num;
2366− attr->qp_access_flags = cmd.qp_access_flags;
2367− attr->pkey_index = cmd.pkey_index;
2368− attr->alt_pkey_index = cmd.alt_pkey_index;
2369− attr->en_sqd_async_notify = cmd.en_sqd_async_notify;
2370− attr->max_rd_atomic = cmd.max_rd_atomic;
2371− attr->max_dest_rd_atomic = cmd.max_dest_rd_atomic;
2372− attr->min_rnr_timer = cmd.min_rnr_timer;
2373− attr->port_num = cmd.port_num;
2374− attr->timeout = cmd.timeout;
2375− attr->retry_cnt = cmd.retry_cnt;
2376− attr->rnr_retry = cmd.rnr_retry;
2377− attr->alt_port_num = cmd.alt_port_num;
2378− attr->alt_timeout = cmd.alt_timeout;
2379−
2380− memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16);
2381− attr->ah_attr.grh.flow_label = cmd.dest.flow_label;
2382− attr->ah_attr.grh.sgid_index = cmd.dest.sgid_index;
2383− attr->ah_attr.grh.hop_limit = cmd.dest.hop_limit;
2384− attr->ah_attr.grh.traffic_class = cmd.dest.traffic_class;
2385− attr->ah_attr.dlid = cmd.dest.dlid;
2386− attr->ah_attr.sl = cmd.dest.sl;
2387− attr->ah_attr.src_path_bits = cmd.dest.src_path_bits;
2388− attr->ah_attr.static_rate = cmd.dest.static_rate;
2389− attr->ah_attr.ah_flags = cmd.dest.is_global ? IB_AH_GRH : 0;
2390− attr->ah_attr.port_num = cmd.dest.port_num;
2391−
2392− memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16);
2393− attr->alt_ah_attr.grh.flow_label = cmd.alt_dest.flow_label;
2394− attr->alt_ah_attr.grh.sgid_index = cmd.alt_dest.sgid_index;
2395− attr->alt_ah_attr.grh.hop_limit = cmd.alt_dest.hop_limit;
2396− attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class;
2397− attr->alt_ah_attr.dlid = cmd.alt_dest.dlid;
2398− attr->alt_ah_attr.sl = cmd.alt_dest.sl;
2399− attr->alt_ah_attr.src_path_bits = cmd.alt_dest.src_path_bits;
2400− attr->alt_ah_attr.static_rate = cmd.alt_dest.static_rate;
2401− attr->alt_ah_attr.ah_flags = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
2402− attr->alt_ah_attr.port_num = cmd.alt_dest.port_num;
2348+ attr->qp_state = cmd->base.qp_state;
2349+ attr->cur_qp_state = cmd->base.cur_qp_state;
2350+ attr->path_mtu = cmd->base.path_mtu;
2351+ attr->path_mig_state = cmd->base.path_mig_state;
2352+ attr->qkey = cmd->base.qkey;
2353+ attr->rq_psn = cmd->base.rq_psn;
2354+ attr->sq_psn = cmd->base.sq_psn;
2355+ attr->dest_qp_num = cmd->base.dest_qp_num;
2356+ attr->qp_access_flags = cmd->base.qp_access_flags;
2357+ attr->pkey_index = cmd->base.pkey_index;
2358+ attr->alt_pkey_index = cmd->base.alt_pkey_index;
2359+ attr->en_sqd_async_notify = cmd->base.en_sqd_async_notify;
2360+ attr->max_rd_atomic = cmd->base.max_rd_atomic;
2361+ attr->max_dest_rd_atomic = cmd->base.max_dest_rd_atomic;
2362+ attr->min_rnr_timer = cmd->base.min_rnr_timer;
2363+ attr->port_num = cmd->base.port_num;
2364+ attr->timeout = cmd->base.timeout;
2365+ attr->retry_cnt = cmd->base.retry_cnt;
2366+ attr->rnr_retry = cmd->base.rnr_retry;
2367+ attr->alt_port_num = cmd->base.alt_port_num;
2368+ attr->alt_timeout = cmd->base.alt_timeout;
2369+ attr->rate_limit = cmd->rate_limit;
2370+
2371+ memcpy(attr->ah_attr.grh.dgid.raw, cmd->base.dest.dgid, 16);
2372+ attr->ah_attr.grh.flow_label = cmd->base.dest.flow_label;
2373+ attr->ah_attr.grh.sgid_index = cmd->base.dest.sgid_index;
2374+ attr->ah_attr.grh.hop_limit = cmd->base.dest.hop_limit;
2375+ attr->ah_attr.grh.traffic_class = cmd->base.dest.traffic_class;
2376+ attr->ah_attr.dlid = cmd->base.dest.dlid;
2377+ attr->ah_attr.sl = cmd->base.dest.sl;
2378+ attr->ah_attr.src_path_bits = cmd->base.dest.src_path_bits;
2379+ attr->ah_attr.static_rate = cmd->base.dest.static_rate;
2380+ attr->ah_attr.ah_flags = cmd->base.dest.is_global ?
2381+ IB_AH_GRH : 0;
2382+ attr->ah_attr.port_num = cmd->base.dest.port_num;
2383+
2384+ memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd->base.alt_dest.dgid, 16);
2385+ attr->alt_ah_attr.grh.flow_label = cmd->base.alt_dest.flow_label;
2386+ attr->alt_ah_attr.grh.sgid_index = cmd->base.alt_dest.sgid_index;
2387+ attr->alt_ah_attr.grh.hop_limit = cmd->base.alt_dest.hop_limit;
2388+ attr->alt_ah_attr.grh.traffic_class = cmd->base.alt_dest.traffic_class;
2389+ attr->alt_ah_attr.dlid = cmd->base.alt_dest.dlid;
2390+ attr->alt_ah_attr.sl = cmd->base.alt_dest.sl;
2391+ attr->alt_ah_attr.src_path_bits = cmd->base.alt_dest.src_path_bits;
2392+ attr->alt_ah_attr.static_rate = cmd->base.alt_dest.static_rate;
2393+ attr->alt_ah_attr.ah_flags = cmd->base.alt_dest.is_global ?
2394+ IB_AH_GRH : 0;
2395+ attr->alt_ah_attr.port_num = cmd->base.alt_dest.port_num;
24032396
24042397 if (qp->real_qp == qp) {
2405− if (cmd.attr_mask & IB_QP_AV) {
2398+ if (cmd->base.attr_mask & IB_QP_AV) {
24062399 ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr);
24072400 if (ret)
24082401 goto release_qp;
24092402 }
24102403 ret = qp->device->modify_qp(qp, attr,
2411− modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata);
2404+ modify_qp_mask(qp->qp_type,
2405+ cmd->base.attr_mask),
2406+ udata);
24122407 } else {
2413− ret = ib_modify_qp(qp, attr, modify_qp_mask(qp->qp_type, cmd.attr_mask));
2408+ ret = ib_modify_qp(qp, attr,
2409+ modify_qp_mask(qp->qp_type,
2410+ cmd->base.attr_mask));
24142411 }
24152412
2416− if (ret)
2417− goto release_qp;
2418−
2419− ret = in_len;
2420−
24212413 release_qp:
24222414 put_qp_read(qp);
24232415
@@ -2427,6 +2419,68 @@ out: · 3 unmodified lines
24272419 return ret;
24282420 }
24292421
2422+ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
2423+ struct ib_device *ib_dev,
2424+ const char __user *buf, int in_len,
2425+ int out_len)
2426+{
2427+ struct ib_uverbs_ex_modify_qp cmd = {};
2428+ struct ib_udata udata;
2429+ int ret;
2430+
2431+ if (copy_from_user(&cmd.base, buf, sizeof(cmd.base)))
2432+ return -EFAULT;
2433+
2434+ if (cmd.base.attr_mask &
2435+ ~((IB_USER_LEGACY_LAST_QP_ATTR_MASK << 1) - 1))
2436+ return -EOPNOTSUPP;
2437+
2438+ INIT_UDATA(&udata, buf + sizeof(cmd.base), NULL,
2439+ in_len - sizeof(cmd.base), out_len);
2440+
2441+ ret = modify_qp(file, &cmd, &udata);
2442+ if (ret)
2443+ return ret;
2444+
2445+ return in_len;
2446+}
2447+
2448+int ib_uverbs_ex_modify_qp(struct ib_uverbs_file *file,
2449+ struct ib_device *ib_dev,
2450+ struct ib_udata *ucore,
2451+ struct ib_udata *uhw)
2452+{
2453+ struct ib_uverbs_ex_modify_qp cmd = {};
2454+ int ret;
2455+
2456+ /*
2457+ * Last bit is reserved for extending the attr_mask by
2458+ * using another field.
2459+ */
2460+ BUILD_BUG_ON(IB_USER_LAST_QP_ATTR_MASK == (1 << 31));
2461+
2462+ if (ucore->inlen < sizeof(cmd.base))
2463+ return -EINVAL;
2464+
2465+ ret = ib_copy_from_udata(&cmd, ucore, min(sizeof(cmd), ucore->inlen));
2466+ if (ret)
2467+ return ret;
2468+
2469+ if (cmd.base.attr_mask &
2470+ ~((IB_USER_LAST_QP_ATTR_MASK << 1) - 1))
2471+ return -EOPNOTSUPP;
2472+
2473+ if (ucore->inlen > sizeof(cmd)) {
2474+ if (ib_is_udata_cleared(ucore, sizeof(cmd),
2475+ ucore->inlen - sizeof(cmd)))
2476+ return -EOPNOTSUPP;
2477+ }
2478+
2479+ ret = modify_qp(file, &cmd, uhw);
2480+
2481+ return ret;
2482+}
2483+
24302484 ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
24312485 struct ib_device *ib_dev,
24322486 const char __user *buf, int in_len,
drivers/infiniband/core/uverbs_main.c+1−0
@@ -137,6 +137,7 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file, · 136 unmodified lines
137137 [IB_USER_VERBS_EX_CMD_DESTROY_WQ] = ib_uverbs_ex_destroy_wq,
138138 [IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL] = ib_uverbs_ex_create_rwq_ind_table,
139139 [IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL] = ib_uverbs_ex_destroy_rwq_ind_table,
140+ [IB_USER_VERBS_EX_CMD_MODIFY_QP] = ib_uverbs_ex_modify_qp,
140141 };
141142
142143 static void ib_uverbs_add_one(struct ib_device *device);
include/uapi/rdma/ib_user_verbs.h+21−0
@@ -37,6 +37,7 @@ · 36 unmodified lines
3737 #define IB_USER_VERBS_H
3838
3939 #include <linux/types.h>
40+#include <rdma/ib_verbs.h>
4041
4142 /*
4243 * Increment this value if any changes that break userspace ABI
@@ -93,6 +94,7 @@ enum { · 50 unmodified lines
9394 IB_USER_VERBS_EX_CMD_QUERY_DEVICE = IB_USER_VERBS_CMD_QUERY_DEVICE,
9495 IB_USER_VERBS_EX_CMD_CREATE_CQ = IB_USER_VERBS_CMD_CREATE_CQ,
9596 IB_USER_VERBS_EX_CMD_CREATE_QP = IB_USER_VERBS_CMD_CREATE_QP,
97+ IB_USER_VERBS_EX_CMD_MODIFY_QP = IB_USER_VERBS_CMD_MODIFY_QP,
9698 IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD,
9799 IB_USER_VERBS_EX_CMD_DESTROY_FLOW,
98100 IB_USER_VERBS_EX_CMD_CREATE_WQ,
@@ -545,6 +547,14 @@ enum { · 446 unmodified lines
545547 IB_UVERBS_CREATE_QP_SUP_COMP_MASK = IB_UVERBS_CREATE_QP_MASK_IND_TABLE,
546548 };
547549
550+enum {
551+ IB_USER_LEGACY_LAST_QP_ATTR_MASK = IB_QP_DEST_QPN
552+};
553+
554+enum {
555+ IB_USER_LAST_QP_ATTR_MASK = IB_QP_RATE_LIMIT
556+};
557+
548558 struct ib_uverbs_ex_create_qp {
549559 __u64 user_handle;
550560 __u32 pd_handle;
@@ -684,9 +694,20 @@ struct ib_uverbs_modify_qp { · 133 unmodified lines
684694 __u64 driver_data[0];
685695 };
686696
697+struct ib_uverbs_ex_modify_qp {
698+ struct ib_uverbs_modify_qp base;
699+ __u32 rate_limit;
700+ __u32 reserved;
701+};
702+
687703 struct ib_uverbs_modify_qp_resp {
688704 };
689705
706+struct ib_uverbs_ex_modify_qp_resp {
707+ __u32 comp_mask;
708+ __u32 response_length;
709+};
710+
690711 struct ib_uverbs_destroy_qp {
691712 __u64 response;
692713 __u32 qp_handle;