Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 6157
b: refs/heads/master
c: f520ba5
h: refs/heads/master
i:
  6155: 9090db2
v: v3
  • Loading branch information
Roland Dreier authored and Roland Dreier committed Aug 27, 2005
1 parent bb1a397 commit 407b366
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 5 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: d41fcc6705eddd04f7218c985b6da35435ed73cc
refs/heads/master: f520ba5aa48e2891c3fb3e364eeaaab4212c7c45
5 changes: 5 additions & 0 deletions trunk/drivers/infiniband/core/uverbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,12 @@ extern struct idr ib_uverbs_mw_idr;
extern struct idr ib_uverbs_ah_idr;
extern struct idr ib_uverbs_cq_idr;
extern struct idr ib_uverbs_qp_idr;
extern struct idr ib_uverbs_srq_idr;

void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr);

int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
void *addr, size_t size, int write);
Expand Down Expand Up @@ -131,5 +133,8 @@ IB_UVERBS_DECLARE_CMD(modify_qp);
IB_UVERBS_DECLARE_CMD(destroy_qp);
IB_UVERBS_DECLARE_CMD(attach_mcast);
IB_UVERBS_DECLARE_CMD(detach_mcast);
IB_UVERBS_DECLARE_CMD(create_srq);
IB_UVERBS_DECLARE_CMD(modify_srq);
IB_UVERBS_DECLARE_CMD(destroy_srq);

#endif /* UVERBS_H */
182 changes: 180 additions & 2 deletions trunk/drivers/infiniband/core/uverbs_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
struct ib_uobject *uobj;
struct ib_pd *pd;
struct ib_cq *scq, *rcq;
struct ib_srq *srq;
struct ib_qp *qp;
struct ib_qp_init_attr attr;
int ret;
Expand All @@ -747,10 +748,12 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle);
rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle);
srq = cmd.is_srq ? idr_find(&ib_uverbs_srq_idr, cmd.srq_handle) : NULL;

if (!pd || pd->uobject->context != file->ucontext ||
!scq || scq->uobject->context != file->ucontext ||
!rcq || rcq->uobject->context != file->ucontext) {
!rcq || rcq->uobject->context != file->ucontext ||
(cmd.is_srq && (!srq || srq->uobject->context != file->ucontext))) {
ret = -EINVAL;
goto err_up;
}
Expand All @@ -759,7 +762,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
attr.qp_context = file;
attr.send_cq = scq;
attr.recv_cq = rcq;
attr.srq = NULL;
attr.srq = srq;
attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
attr.qp_type = cmd.qp_type;

Expand Down Expand Up @@ -1004,3 +1007,178 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,

return ret ? ret : in_len;
}

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_srq_resp resp;
struct ib_udata udata;
struct ib_uobject *uobj;
struct ib_pd *pd;
struct ib_srq *srq;
struct ib_srq_init_attr attr;
int ret;

if (out_len < sizeof resp)
return -ENOSPC;

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

INIT_UDATA(&udata, buf + sizeof cmd,
(unsigned long) cmd.response + sizeof resp,
in_len - sizeof cmd, out_len - sizeof resp);

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

down(&ib_uverbs_idr_mutex);

pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);

if (!pd || pd->uobject->context != file->ucontext) {
ret = -EINVAL;
goto err_up;
}

attr.event_handler = ib_uverbs_srq_event_handler;
attr.srq_context = file;
attr.attr.max_wr = cmd.max_wr;
attr.attr.max_sge = cmd.max_sge;
attr.attr.srq_limit = cmd.srq_limit;

uobj->user_handle = cmd.user_handle;
uobj->context = file->ucontext;

srq = pd->device->create_srq(pd, &attr, &udata);
if (IS_ERR(srq)) {
ret = PTR_ERR(srq);
goto err_up;
}

srq->device = pd->device;
srq->pd = pd;
srq->uobject = uobj;
srq->event_handler = attr.event_handler;
srq->srq_context = attr.srq_context;
atomic_inc(&pd->usecnt);
atomic_set(&srq->usecnt, 0);

memset(&resp, 0, sizeof resp);

retry:
if (!idr_pre_get(&ib_uverbs_srq_idr, GFP_KERNEL)) {
ret = -ENOMEM;
goto err_destroy;
}

ret = idr_get_new(&ib_uverbs_srq_idr, srq, &uobj->id);

if (ret == -EAGAIN)
goto retry;
if (ret)
goto err_destroy;

resp.srq_handle = uobj->id;

spin_lock_irq(&file->ucontext->lock);
list_add_tail(&uobj->list, &file->ucontext->srq_list);
spin_unlock_irq(&file->ucontext->lock);

if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
ret = -EFAULT;
goto err_list;
}

up(&ib_uverbs_idr_mutex);

return in_len;

err_list:
spin_lock_irq(&file->ucontext->lock);
list_del(&uobj->list);
spin_unlock_irq(&file->ucontext->lock);

err_destroy:
ib_destroy_srq(srq);

err_up:
up(&ib_uverbs_idr_mutex);

kfree(uobj);
return ret;
}

ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
struct ib_uverbs_modify_srq cmd;
struct ib_srq *srq;
struct ib_srq_attr attr;
int ret;

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

down(&ib_uverbs_idr_mutex);

srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
if (!srq || srq->uobject->context != file->ucontext) {
ret = -EINVAL;
goto out;
}

attr.max_wr = cmd.max_wr;
attr.max_sge = cmd.max_sge;
attr.srq_limit = cmd.srq_limit;

ret = ib_modify_srq(srq, &attr, cmd.attr_mask);

out:
up(&ib_uverbs_idr_mutex);

return ret ? ret : in_len;
}

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

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

down(&ib_uverbs_idr_mutex);

srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
if (!srq || srq->uobject->context != file->ucontext)
goto out;

uobj = srq->uobject;

ret = ib_destroy_srq(srq);
if (ret)
goto out;

idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle);

spin_lock_irq(&file->ucontext->lock);
list_del(&uobj->list);
spin_unlock_irq(&file->ucontext->lock);

kfree(uobj);

out:
up(&ib_uverbs_idr_mutex);

return ret ? ret : in_len;
}
20 changes: 19 additions & 1 deletion trunk/drivers/infiniband/core/uverbs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ DEFINE_IDR(ib_uverbs_mw_idr);
DEFINE_IDR(ib_uverbs_ah_idr);
DEFINE_IDR(ib_uverbs_cq_idr);
DEFINE_IDR(ib_uverbs_qp_idr);
DEFINE_IDR(ib_uverbs_srq_idr);

static spinlock_t map_lock;
static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
Expand All @@ -93,6 +94,9 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
[IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp,
[IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast,
[IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast,
[IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq,
[IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq,
[IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq,
};

static struct vfsmount *uverbs_event_mnt;
Expand Down Expand Up @@ -127,7 +131,14 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context)
kfree(uobj);
}

/* XXX Free SRQs */
list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
struct ib_srq *srq = idr_find(&ib_uverbs_srq_idr, uobj->id);
idr_remove(&ib_uverbs_srq_idr, uobj->id);
ib_destroy_srq(srq);
list_del(&uobj->list);
kfree(uobj);
}

/* XXX Free MWs */

list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) {
Expand Down Expand Up @@ -346,6 +357,13 @@ void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
event->event);
}

void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr)
{
ib_uverbs_async_handler(context_ptr,
event->element.srq->uobject->user_handle,
event->event);
}

static void ib_uverbs_event_handler(struct ib_event_handler *handler,
struct ib_event *event)
{
Expand Down
35 changes: 34 additions & 1 deletion trunk/drivers/infiniband/include/ib_user_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,12 @@ enum {
IB_USER_VERBS_CMD_POST_SEND,
IB_USER_VERBS_CMD_POST_RECV,
IB_USER_VERBS_CMD_ATTACH_MCAST,
IB_USER_VERBS_CMD_DETACH_MCAST
IB_USER_VERBS_CMD_DETACH_MCAST,
IB_USER_VERBS_CMD_CREATE_SRQ,
IB_USER_VERBS_CMD_MODIFY_SRQ,
IB_USER_VERBS_CMD_QUERY_SRQ,
IB_USER_VERBS_CMD_DESTROY_SRQ,
IB_USER_VERBS_CMD_POST_SRQ_RECV
};

/*
Expand Down Expand Up @@ -386,4 +391,32 @@ struct ib_uverbs_detach_mcast {
__u64 driver_data[0];
};

struct ib_uverbs_create_srq {
__u64 response;
__u64 user_handle;
__u32 pd_handle;
__u32 max_wr;
__u32 max_sge;
__u32 srq_limit;
__u64 driver_data[0];
};

struct ib_uverbs_create_srq_resp {
__u32 srq_handle;
};

struct ib_uverbs_modify_srq {
__u32 srq_handle;
__u32 attr_mask;
__u32 max_wr;
__u32 max_sge;
__u32 srq_limit;
__u32 reserved;
__u64 driver_data[0];
};

struct ib_uverbs_destroy_srq {
__u32 srq_handle;
};

#endif /* IB_USER_VERBS_H */

0 comments on commit 407b366

Please sign in to comment.