Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RDMA/core: Create clean QP creations interface for uverbs

Unify create QP creation interface to make clean approach to create
XRC_TGT and regular QPs.

Link: https://lore.kernel.org/r/5cd50e7d8ad9112545a1a61dea62799a5cb3224a.1628014762.git.leonro@nvidia.com
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Leon Romanovsky and committed by
Jason Gunthorpe
d2b10794 5507f67d

+52 -52
+5 -4
drivers/infiniband/core/core_priv.h
··· 316 316 void nldev_init(void); 317 317 void nldev_exit(void); 318 318 319 - struct ib_qp *_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, 320 - struct ib_qp_init_attr *attr, 321 - struct ib_udata *udata, struct ib_uqp_object *uobj, 322 - const char *caller); 319 + struct ib_qp *ib_create_qp_user(struct ib_device *dev, struct ib_pd *pd, 320 + struct ib_qp_init_attr *attr, 321 + struct ib_udata *udata, 322 + struct ib_uqp_object *uobj, const char *caller); 323 + 323 324 void ib_qp_usecnt_inc(struct ib_qp *qp); 324 325 void ib_qp_usecnt_dec(struct ib_qp *qp); 325 326
+2 -11
drivers/infiniband/core/uverbs_cmd.c
··· 1435 1435 attr.source_qpn = cmd->source_qpn; 1436 1436 } 1437 1437 1438 - if (cmd->qp_type == IB_QPT_XRC_TGT) 1439 - qp = ib_create_qp(pd, &attr); 1440 - else 1441 - qp = _ib_create_qp(device, pd, &attr, &attrs->driver_udata, obj, 1442 - NULL); 1443 - 1438 + qp = ib_create_qp_user(device, pd, &attr, &attrs->driver_udata, obj, 1439 + KBUILD_MODNAME); 1444 1440 if (IS_ERR(qp)) { 1445 1441 ret = PTR_ERR(qp); 1446 1442 goto err_put; 1447 1443 } 1448 1444 ib_qp_usecnt_inc(qp); 1449 - 1450 - if (cmd->qp_type == IB_QPT_XRC_TGT) { 1451 - /* It is done in _ib_create_qp for other QP types */ 1452 - qp->uobject = obj; 1453 - } 1454 1445 1455 1446 obj->uevent.uobject.object = qp; 1456 1447 obj->uevent.event_file = READ_ONCE(attrs->ufile->default_async_file);
+2 -8
drivers/infiniband/core/uverbs_std_types_qp.c
··· 248 248 set_caps(&attr, &cap, true); 249 249 mutex_init(&obj->mcast_lock); 250 250 251 - if (attr.qp_type == IB_QPT_XRC_TGT) 252 - qp = ib_create_qp(pd, &attr); 253 - else 254 - qp = _ib_create_qp(device, pd, &attr, &attrs->driver_udata, obj, 255 - NULL); 256 - 251 + qp = ib_create_qp_user(device, pd, &attr, &attrs->driver_udata, obj, 252 + KBUILD_MODNAME); 257 253 if (IS_ERR(qp)) { 258 254 ret = PTR_ERR(qp); 259 255 goto err_put; ··· 260 264 obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, 261 265 uobject); 262 266 atomic_inc(&obj->uxrcd->refcnt); 263 - /* It is done in _ib_create_qp for other QP types */ 264 - qp->uobject = obj; 265 267 } 266 268 267 269 obj->uevent.uobject.object = qp;
+43 -29
drivers/infiniband/core/verbs.c
··· 1200 1200 return qp; 1201 1201 } 1202 1202 1203 - /** 1204 - * _ib_create_qp - Creates a QP associated with the specified protection domain 1205 - * @dev: IB device 1206 - * @pd: The protection domain associated with the QP. 1207 - * @attr: A list of initial attributes required to create the 1208 - * QP. If QP creation succeeds, then the attributes are updated to 1209 - * the actual capabilities of the created QP. 1210 - * @udata: User data 1211 - * @uobj: uverbs obect 1212 - * @caller: caller's build-time module name 1213 - */ 1214 - struct ib_qp *_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, 1215 - struct ib_qp_init_attr *attr, 1216 - struct ib_udata *udata, struct ib_uqp_object *uobj, 1217 - const char *caller) 1203 + static struct ib_qp *create_qp(struct ib_device *dev, struct ib_pd *pd, 1204 + struct ib_qp_init_attr *attr, 1205 + struct ib_udata *udata, 1206 + struct ib_uqp_object *uobj, const char *caller) 1218 1207 { 1219 1208 struct ib_udata dummy = {}; 1220 1209 struct ib_qp *qp; ··· 1261 1272 return ERR_PTR(ret); 1262 1273 1263 1274 } 1264 - EXPORT_SYMBOL(_ib_create_qp); 1275 + 1276 + /** 1277 + * ib_create_qp_user - Creates a QP associated with the specified protection 1278 + * domain. 1279 + * @dev: IB device 1280 + * @pd: The protection domain associated with the QP. 1281 + * @attr: A list of initial attributes required to create the 1282 + * QP. If QP creation succeeds, then the attributes are updated to 1283 + * the actual capabilities of the created QP. 1284 + * @udata: User data 1285 + * @uobj: uverbs obect 1286 + * @caller: caller's build-time module name 1287 + */ 1288 + struct ib_qp *ib_create_qp_user(struct ib_device *dev, struct ib_pd *pd, 1289 + struct ib_qp_init_attr *attr, 1290 + struct ib_udata *udata, 1291 + struct ib_uqp_object *uobj, const char *caller) 1292 + { 1293 + struct ib_qp *qp, *xrc_qp; 1294 + 1295 + if (attr->qp_type == IB_QPT_XRC_TGT) 1296 + qp = create_qp(dev, pd, attr, NULL, NULL, caller); 1297 + else 1298 + qp = create_qp(dev, pd, attr, udata, uobj, NULL); 1299 + if (attr->qp_type != IB_QPT_XRC_TGT || IS_ERR(qp)) 1300 + return qp; 1301 + 1302 + xrc_qp = create_xrc_qp_user(qp, attr); 1303 + if (IS_ERR(xrc_qp)) { 1304 + ib_destroy_qp(qp); 1305 + return xrc_qp; 1306 + } 1307 + 1308 + xrc_qp->uobject = uobj; 1309 + return xrc_qp; 1310 + } 1311 + EXPORT_SYMBOL(ib_create_qp_user); 1265 1312 1266 1313 void ib_qp_usecnt_inc(struct ib_qp *qp) 1267 1314 { ··· 1333 1308 struct ib_qp_init_attr *qp_init_attr, 1334 1309 const char *caller) 1335 1310 { 1336 - struct ib_device *device = pd ? pd->device : qp_init_attr->xrcd->device; 1311 + struct ib_device *device = pd->device; 1337 1312 struct ib_qp *qp; 1338 1313 int ret; 1339 1314 ··· 1346 1321 if (qp_init_attr->cap.max_rdma_ctxs) 1347 1322 rdma_rw_init_qp(device, qp_init_attr); 1348 1323 1349 - qp = _ib_create_qp(device, pd, qp_init_attr, NULL, NULL, caller); 1324 + qp = create_qp(device, pd, qp_init_attr, NULL, NULL, caller); 1350 1325 if (IS_ERR(qp)) 1351 1326 return qp; 1352 - 1353 - if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { 1354 - struct ib_qp *xrc_qp = 1355 - create_xrc_qp_user(qp, qp_init_attr); 1356 - 1357 - if (IS_ERR(xrc_qp)) { 1358 - ret = PTR_ERR(xrc_qp); 1359 - goto err; 1360 - } 1361 - return xrc_qp; 1362 - } 1363 1327 1364 1328 ib_qp_usecnt_inc(qp); 1365 1329