Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 358851
b: refs/heads/master
c: 6b52a12
h: refs/heads/master
i:
  358849: a6a2c39
  358847: de3ad5d
v: v3
  • Loading branch information
Shani Michaeli authored and Roland Dreier committed Feb 21, 2013
1 parent bbc2b37 commit 9cc372e
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7083e42ee2ff43a11481e0e7211ec4f9ac68cb79
refs/heads/master: 6b52a12bc3fc39053b5bac4d4927ec8d974f8f60
2 changes: 2 additions & 0 deletions trunk/drivers/infiniband/core/uverbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ IB_UVERBS_DECLARE_CMD(alloc_pd);
IB_UVERBS_DECLARE_CMD(dealloc_pd);
IB_UVERBS_DECLARE_CMD(reg_mr);
IB_UVERBS_DECLARE_CMD(dereg_mr);
IB_UVERBS_DECLARE_CMD(alloc_mw);
IB_UVERBS_DECLARE_CMD(dealloc_mw);
IB_UVERBS_DECLARE_CMD(create_comp_channel);
IB_UVERBS_DECLARE_CMD(create_cq);
IB_UVERBS_DECLARE_CMD(resize_cq);
Expand Down
121 changes: 121 additions & 0 deletions trunk/drivers/infiniband/core/uverbs_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct uverbs_lock_class {

static struct uverbs_lock_class pd_lock_class = { .name = "PD-uobj" };
static struct uverbs_lock_class mr_lock_class = { .name = "MR-uobj" };
static struct uverbs_lock_class mw_lock_class = { .name = "MW-uobj" };
static struct uverbs_lock_class cq_lock_class = { .name = "CQ-uobj" };
static struct uverbs_lock_class qp_lock_class = { .name = "QP-uobj" };
static struct uverbs_lock_class ah_lock_class = { .name = "AH-uobj" };
Expand Down Expand Up @@ -1049,6 +1050,126 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
return in_len;
}

ssize_t ib_uverbs_alloc_mw(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
struct ib_uverbs_alloc_mw cmd;
struct ib_uverbs_alloc_mw_resp resp;
struct ib_uobject *uobj;
struct ib_pd *pd;
struct ib_mw *mw;
int ret;

if (out_len < sizeof(resp))
return -ENOSPC;

if (copy_from_user(&cmd, buf, sizeof(cmd)))
return -EFAULT;

uobj = kmalloc(sizeof(*uobj), GFP_KERNEL);
if (!uobj)
return -ENOMEM;

init_uobj(uobj, 0, file->ucontext, &mw_lock_class);
down_write(&uobj->mutex);

pd = idr_read_pd(cmd.pd_handle, file->ucontext);
if (!pd) {
ret = -EINVAL;
goto err_free;
}

mw = pd->device->alloc_mw(pd, cmd.mw_type);
if (IS_ERR(mw)) {
ret = PTR_ERR(mw);
goto err_put;
}

mw->device = pd->device;
mw->pd = pd;
mw->uobject = uobj;
atomic_inc(&pd->usecnt);

uobj->object = mw;
ret = idr_add_uobj(&ib_uverbs_mw_idr, uobj);
if (ret)
goto err_unalloc;

memset(&resp, 0, sizeof(resp));
resp.rkey = mw->rkey;
resp.mw_handle = uobj->id;

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(&uobj->list, &file->ucontext->mw_list);
mutex_unlock(&file->mutex);

uobj->live = 1;

up_write(&uobj->mutex);

return in_len;

err_copy:
idr_remove_uobj(&ib_uverbs_mw_idr, uobj);

err_unalloc:
ib_dealloc_mw(mw);

err_put:
put_pd_read(pd);

err_free:
put_uobj_write(uobj);
return ret;
}

ssize_t ib_uverbs_dealloc_mw(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
struct ib_uverbs_dealloc_mw cmd;
struct ib_mw *mw;
struct ib_uobject *uobj;
int ret = -EINVAL;

if (copy_from_user(&cmd, buf, sizeof(cmd)))
return -EFAULT;

uobj = idr_write_uobj(&ib_uverbs_mw_idr, cmd.mw_handle, file->ucontext);
if (!uobj)
return -EINVAL;

mw = uobj->object;

ret = ib_dealloc_mw(mw);
if (!ret)
uobj->live = 0;

put_uobj_write(uobj);

if (ret)
return ret;

idr_remove_uobj(&ib_uverbs_mw_idr, uobj);

mutex_lock(&file->mutex);
list_del(&uobj->list);
mutex_unlock(&file->mutex);

put_uobj(uobj);

return in_len;
}

ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
Expand Down
13 changes: 11 additions & 2 deletions trunk/drivers/infiniband/core/uverbs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
[IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd,
[IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr,
[IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr,
[IB_USER_VERBS_CMD_ALLOC_MW] = ib_uverbs_alloc_mw,
[IB_USER_VERBS_CMD_DEALLOC_MW] = ib_uverbs_dealloc_mw,
[IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL] = ib_uverbs_create_comp_channel,
[IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq,
[IB_USER_VERBS_CMD_RESIZE_CQ] = ib_uverbs_resize_cq,
Expand Down Expand Up @@ -201,6 +203,15 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
kfree(uobj);
}

/* Remove MWs before QPs, in order to support type 2A MWs. */
list_for_each_entry_safe(uobj, tmp, &context->mw_list, list) {
struct ib_mw *mw = uobj->object;

idr_remove_uobj(&ib_uverbs_mw_idr, uobj);
ib_dealloc_mw(mw);
kfree(uobj);
}

list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) {
struct ib_qp *qp = uobj->object;
struct ib_uqp_object *uqp =
Expand Down Expand Up @@ -240,8 +251,6 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
kfree(uevent);
}

/* XXX Free MWs */

list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) {
struct ib_mr *mr = uobj->object;

Expand Down
16 changes: 16 additions & 0 deletions trunk/include/uapi/rdma/ib_user_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,22 @@ struct ib_uverbs_dereg_mr {
__u32 mr_handle;
};

struct ib_uverbs_alloc_mw {
__u64 response;
__u32 pd_handle;
__u8 mw_type;
__u8 reserved[3];
};

struct ib_uverbs_alloc_mw_resp {
__u32 mw_handle;
__u32 rkey;
};

struct ib_uverbs_dealloc_mw {
__u32 mw_handle;
};

struct ib_uverbs_create_comp_channel {
__u64 response;
};
Expand Down

0 comments on commit 9cc372e

Please sign in to comment.