mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-23 05:56:14 -04:00
RDMA/uverbs: Export XRC SRQs to user space
We require additional information to create XRC SRQs than we can exchange using the existing create SRQ ABI. Provide an enhanced create ABI for extended SRQ types. Based on patches by Jack Morgenstein <jackm@dev.mellanox.co.il> and Roland Dreier <roland@purestorage.com> Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
committed by
Roland Dreier
parent
53d0bd1e7f
commit
8541f8de05
@@ -1400,7 +1400,8 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
|
||||
rcq = cmd.recv_cq_handle == cmd.send_cq_handle ?
|
||||
scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1);
|
||||
|
||||
if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) {
|
||||
if (!pd || !scq || !rcq ||
|
||||
(cmd.is_srq && (!srq || srq->srq_type != IB_SRQT_BASIC))) {
|
||||
ret = -EINVAL;
|
||||
goto err_put;
|
||||
}
|
||||
@@ -2293,17 +2294,180 @@ out_put:
|
||||
return ret ? ret : in_len;
|
||||
}
|
||||
|
||||
int __uverbs_create_xsrq(struct ib_uverbs_file *file,
|
||||
struct ib_uverbs_create_xsrq *cmd,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
struct ib_uverbs_create_srq_resp resp;
|
||||
struct ib_usrq_object *obj;
|
||||
struct ib_pd *pd;
|
||||
struct ib_srq *srq;
|
||||
struct ib_uobject *uninitialized_var(xrcd_uobj);
|
||||
struct ib_srq_init_attr attr;
|
||||
int ret;
|
||||
|
||||
obj = kmalloc(sizeof *obj, GFP_KERNEL);
|
||||
if (!obj)
|
||||
return -ENOMEM;
|
||||
|
||||
init_uobj(&obj->uevent.uobject, cmd->user_handle, file->ucontext, &srq_lock_key);
|
||||
down_write(&obj->uevent.uobject.mutex);
|
||||
|
||||
pd = idr_read_pd(cmd->pd_handle, file->ucontext);
|
||||
if (!pd) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (cmd->srq_type == IB_SRQT_XRC) {
|
||||
attr.ext.xrc.cq = idr_read_cq(cmd->cq_handle, file->ucontext, 0);
|
||||
if (!attr.ext.xrc.cq) {
|
||||
ret = -EINVAL;
|
||||
goto err_put_pd;
|
||||
}
|
||||
|
||||
attr.ext.xrc.xrcd = idr_read_xrcd(cmd->xrcd_handle, file->ucontext, &xrcd_uobj);
|
||||
if (!attr.ext.xrc.xrcd) {
|
||||
ret = -EINVAL;
|
||||
goto err_put_cq;
|
||||
}
|
||||
|
||||
obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject);
|
||||
atomic_inc(&obj->uxrcd->refcnt);
|
||||
}
|
||||
|
||||
attr.event_handler = ib_uverbs_srq_event_handler;
|
||||
attr.srq_context = file;
|
||||
attr.srq_type = cmd->srq_type;
|
||||
attr.attr.max_wr = cmd->max_wr;
|
||||
attr.attr.max_sge = cmd->max_sge;
|
||||
attr.attr.srq_limit = cmd->srq_limit;
|
||||
|
||||
obj->uevent.events_reported = 0;
|
||||
INIT_LIST_HEAD(&obj->uevent.event_list);
|
||||
|
||||
srq = pd->device->create_srq(pd, &attr, udata);
|
||||
if (IS_ERR(srq)) {
|
||||
ret = PTR_ERR(srq);
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
srq->device = pd->device;
|
||||
srq->pd = pd;
|
||||
srq->srq_type = cmd->srq_type;
|
||||
srq->uobject = &obj->uevent.uobject;
|
||||
srq->event_handler = attr.event_handler;
|
||||
srq->srq_context = attr.srq_context;
|
||||
|
||||
if (cmd->srq_type == IB_SRQT_XRC) {
|
||||
srq->ext.xrc.cq = attr.ext.xrc.cq;
|
||||
srq->ext.xrc.xrcd = attr.ext.xrc.xrcd;
|
||||
atomic_inc(&attr.ext.xrc.cq->usecnt);
|
||||
atomic_inc(&attr.ext.xrc.xrcd->usecnt);
|
||||
}
|
||||
|
||||
atomic_inc(&pd->usecnt);
|
||||
atomic_set(&srq->usecnt, 0);
|
||||
|
||||
obj->uevent.uobject.object = srq;
|
||||
ret = idr_add_uobj(&ib_uverbs_srq_idr, &obj->uevent.uobject);
|
||||
if (ret)
|
||||
goto err_destroy;
|
||||
|
||||
memset(&resp, 0, sizeof resp);
|
||||
resp.srq_handle = obj->uevent.uobject.id;
|
||||
resp.max_wr = attr.attr.max_wr;
|
||||
resp.max_sge = attr.attr.max_sge;
|
||||
if (cmd->srq_type == IB_SRQT_XRC)
|
||||
resp.srqn = srq->ext.xrc.srq_num;
|
||||
|
||||
if (copy_to_user((void __user *) (unsigned long) cmd->response,
|
||||
&resp, sizeof resp)) {
|
||||
ret = -EFAULT;
|
||||
goto err_copy;
|
||||
}
|
||||
|
||||
if (cmd->srq_type == IB_SRQT_XRC) {
|
||||
put_uobj_read(xrcd_uobj);
|
||||
put_cq_read(attr.ext.xrc.cq);
|
||||
}
|
||||
put_pd_read(pd);
|
||||
|
||||
mutex_lock(&file->mutex);
|
||||
list_add_tail(&obj->uevent.uobject.list, &file->ucontext->srq_list);
|
||||
mutex_unlock(&file->mutex);
|
||||
|
||||
obj->uevent.uobject.live = 1;
|
||||
|
||||
up_write(&obj->uevent.uobject.mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
err_copy:
|
||||
idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uevent.uobject);
|
||||
|
||||
err_destroy:
|
||||
ib_destroy_srq(srq);
|
||||
|
||||
err_put:
|
||||
if (cmd->srq_type == IB_SRQT_XRC) {
|
||||
atomic_dec(&obj->uxrcd->refcnt);
|
||||
put_uobj_read(xrcd_uobj);
|
||||
}
|
||||
|
||||
err_put_cq:
|
||||
if (cmd->srq_type == IB_SRQT_XRC)
|
||||
put_cq_read(attr.ext.xrc.cq);
|
||||
|
||||
err_put_pd:
|
||||
put_pd_read(pd);
|
||||
|
||||
err:
|
||||
put_uobj_write(&obj->uevent.uobject);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
|
||||
const char __user *buf, int in_len,
|
||||
int out_len)
|
||||
{
|
||||
struct ib_uverbs_create_srq cmd;
|
||||
struct ib_uverbs_create_xsrq xcmd;
|
||||
struct ib_uverbs_create_srq_resp resp;
|
||||
struct ib_udata udata;
|
||||
int ret;
|
||||
|
||||
if (out_len < sizeof resp)
|
||||
return -ENOSPC;
|
||||
|
||||
if (copy_from_user(&cmd, buf, sizeof cmd))
|
||||
return -EFAULT;
|
||||
|
||||
xcmd.response = cmd.response;
|
||||
xcmd.user_handle = cmd.user_handle;
|
||||
xcmd.srq_type = IB_SRQT_BASIC;
|
||||
xcmd.pd_handle = cmd.pd_handle;
|
||||
xcmd.max_wr = cmd.max_wr;
|
||||
xcmd.max_sge = cmd.max_sge;
|
||||
xcmd.srq_limit = cmd.srq_limit;
|
||||
|
||||
INIT_UDATA(&udata, buf + sizeof cmd,
|
||||
(unsigned long) cmd.response + sizeof resp,
|
||||
in_len - sizeof cmd, out_len - sizeof resp);
|
||||
|
||||
ret = __uverbs_create_xsrq(file, &xcmd, &udata);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return in_len;
|
||||
}
|
||||
|
||||
ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file,
|
||||
const char __user *buf, int in_len, int out_len)
|
||||
{
|
||||
struct ib_uverbs_create_xsrq cmd;
|
||||
struct ib_uverbs_create_srq_resp resp;
|
||||
struct ib_udata udata;
|
||||
struct ib_uevent_object *obj;
|
||||
struct ib_pd *pd;
|
||||
struct ib_srq *srq;
|
||||
struct ib_srq_init_attr attr;
|
||||
int ret;
|
||||
|
||||
if (out_len < sizeof resp)
|
||||
@@ -2316,83 +2480,11 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
|
||||
(unsigned long) cmd.response + sizeof resp,
|
||||
in_len - sizeof cmd, out_len - sizeof resp);
|
||||
|
||||
obj = kmalloc(sizeof *obj, GFP_KERNEL);
|
||||
if (!obj)
|
||||
return -ENOMEM;
|
||||
|
||||
init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &srq_lock_key);
|
||||
down_write(&obj->uobject.mutex);
|
||||
|
||||
pd = idr_read_pd(cmd.pd_handle, file->ucontext);
|
||||
if (!pd) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
attr.event_handler = ib_uverbs_srq_event_handler;
|
||||
attr.srq_context = file;
|
||||
attr.srq_type = IB_SRQT_BASIC;
|
||||
attr.attr.max_wr = cmd.max_wr;
|
||||
attr.attr.max_sge = cmd.max_sge;
|
||||
attr.attr.srq_limit = cmd.srq_limit;
|
||||
|
||||
obj->events_reported = 0;
|
||||
INIT_LIST_HEAD(&obj->event_list);
|
||||
|
||||
srq = pd->device->create_srq(pd, &attr, &udata);
|
||||
if (IS_ERR(srq)) {
|
||||
ret = PTR_ERR(srq);
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
srq->device = pd->device;
|
||||
srq->pd = pd;
|
||||
srq->uobject = &obj->uobject;
|
||||
srq->event_handler = attr.event_handler;
|
||||
srq->srq_context = attr.srq_context;
|
||||
atomic_inc(&pd->usecnt);
|
||||
atomic_set(&srq->usecnt, 0);
|
||||
|
||||
obj->uobject.object = srq;
|
||||
ret = idr_add_uobj(&ib_uverbs_srq_idr, &obj->uobject);
|
||||
ret = __uverbs_create_xsrq(file, &cmd, &udata);
|
||||
if (ret)
|
||||
goto err_destroy;
|
||||
|
||||
memset(&resp, 0, sizeof resp);
|
||||
resp.srq_handle = obj->uobject.id;
|
||||
resp.max_wr = attr.attr.max_wr;
|
||||
resp.max_sge = attr.attr.max_sge;
|
||||
|
||||
if (copy_to_user((void __user *) (unsigned long) cmd.response,
|
||||
&resp, sizeof resp)) {
|
||||
ret = -EFAULT;
|
||||
goto err_copy;
|
||||
}
|
||||
|
||||
put_pd_read(pd);
|
||||
|
||||
mutex_lock(&file->mutex);
|
||||
list_add_tail(&obj->uobject.list, &file->ucontext->srq_list);
|
||||
mutex_unlock(&file->mutex);
|
||||
|
||||
obj->uobject.live = 1;
|
||||
|
||||
up_write(&obj->uobject.mutex);
|
||||
return ret;
|
||||
|
||||
return in_len;
|
||||
|
||||
err_copy:
|
||||
idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uobject);
|
||||
|
||||
err_destroy:
|
||||
ib_destroy_srq(srq);
|
||||
|
||||
err_put:
|
||||
put_pd_read(pd);
|
||||
|
||||
err:
|
||||
put_uobj_write(&obj->uobject);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
|
||||
|
||||
Reference in New Issue
Block a user