Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 272363
b: refs/heads/master
c: d3d72d9
h: refs/heads/master
i:
  272361: 4bb142e
  272359: 8b1d284
v: v3
  • Loading branch information
Sean Hefty authored and Roland Dreier committed Oct 13, 2011
1 parent c1347c1 commit 3e8ae34
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 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: b42b63cf0dde2af6eec462b2d6cca7d938702a28
refs/heads/master: d3d72d909e783d048ee39046aa7b4fa798a4dda8
47 changes: 47 additions & 0 deletions trunk/drivers/infiniband/core/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,20 @@ EXPORT_SYMBOL(ib_destroy_srq);

/* Queue pairs */

static void __ib_insert_xrcd_qp(struct ib_xrcd *xrcd, struct ib_qp *qp)
{
mutex_lock(&xrcd->tgt_qp_mutex);
list_add(&qp->xrcd_list, &xrcd->tgt_qp_list);
mutex_unlock(&xrcd->tgt_qp_mutex);
}

static void __ib_remove_xrcd_qp(struct ib_xrcd *xrcd, struct ib_qp *qp)
{
mutex_lock(&xrcd->tgt_qp_mutex);
list_del(&qp->xrcd_list);
mutex_unlock(&xrcd->tgt_qp_mutex);
}

struct ib_qp *ib_create_qp(struct ib_pd *pd,
struct ib_qp_init_attr *qp_init_attr)
{
Expand All @@ -334,6 +348,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->srq = NULL;
qp->xrcd = qp_init_attr->xrcd;
atomic_inc(&qp_init_attr->xrcd->usecnt);
__ib_insert_xrcd_qp(qp_init_attr->xrcd, qp);
} else {
if (qp_init_attr->qp_type == IB_QPT_XRC_INI) {
qp->recv_cq = NULL;
Expand Down Expand Up @@ -730,6 +745,8 @@ int ib_destroy_qp(struct ib_qp *qp)
rcq = qp->recv_cq;
srq = qp->srq;
xrcd = qp->xrcd;
if (xrcd)
__ib_remove_xrcd_qp(xrcd, qp);

ret = qp->device->destroy_qp(qp);
if (!ret) {
Expand All @@ -743,12 +760,30 @@ int ib_destroy_qp(struct ib_qp *qp)
atomic_dec(&srq->usecnt);
if (xrcd)
atomic_dec(&xrcd->usecnt);
} else if (xrcd) {
__ib_insert_xrcd_qp(xrcd, qp);
}

return ret;
}
EXPORT_SYMBOL(ib_destroy_qp);

int ib_release_qp(struct ib_qp *qp)
{
unsigned long flags;

if (qp->qp_type != IB_QPT_XRC_TGT)
return -EINVAL;

spin_lock_irqsave(&qp->device->event_handler_lock, flags);
qp->event_handler = NULL;
spin_unlock_irqrestore(&qp->device->event_handler_lock, flags);

atomic_dec(&qp->xrcd->usecnt);
return 0;
}
EXPORT_SYMBOL(ib_release_qp);

/* Completion queues */

struct ib_cq *ib_create_cq(struct ib_device *device,
Expand Down Expand Up @@ -1062,6 +1097,8 @@ struct ib_xrcd *ib_alloc_xrcd(struct ib_device *device)
if (!IS_ERR(xrcd)) {
xrcd->device = device;
atomic_set(&xrcd->usecnt, 0);
mutex_init(&xrcd->tgt_qp_mutex);
INIT_LIST_HEAD(&xrcd->tgt_qp_list);
}

return xrcd;
Expand All @@ -1070,9 +1107,19 @@ EXPORT_SYMBOL(ib_alloc_xrcd);

int ib_dealloc_xrcd(struct ib_xrcd *xrcd)
{
struct ib_qp *qp;
int ret;

if (atomic_read(&xrcd->usecnt))
return -EBUSY;

while (!list_empty(&xrcd->tgt_qp_list)) {
qp = list_entry(xrcd->tgt_qp_list.next, struct ib_qp, xrcd_list);
ret = ib_destroy_qp(qp);
if (ret)
return ret;
}

return xrcd->device->dealloc_xrcd(xrcd);
}
EXPORT_SYMBOL(ib_dealloc_xrcd);
17 changes: 16 additions & 1 deletion trunk/include/rdma/ib_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,10 @@ struct ib_pd {

struct ib_xrcd {
struct ib_device *device;
atomic_t usecnt; /* count all resources */
atomic_t usecnt; /* count all exposed resources */

struct mutex tgt_qp_mutex;
struct list_head tgt_qp_list;
};

struct ib_ah {
Expand Down Expand Up @@ -926,6 +929,7 @@ struct ib_qp {
struct ib_cq *recv_cq;
struct ib_srq *srq;
struct ib_xrcd *xrcd; /* XRC TGT QPs only */
struct list_head xrcd_list;
struct ib_uobject *uobject;
void (*event_handler)(struct ib_event *, void *);
void *qp_context;
Expand Down Expand Up @@ -1481,6 +1485,17 @@ int ib_query_qp(struct ib_qp *qp,
*/
int ib_destroy_qp(struct ib_qp *qp);

/**
* ib_release_qp - Release an external reference to a QP.
* @qp: The QP handle to release
*
* The specified QP handle is released by the caller. If the QP is
* referenced internally, it is not destroyed until all internal
* references are released. After releasing the qp, the caller
* can no longer access it and all events on the QP are discarded.
*/
int ib_release_qp(struct ib_qp *qp);

/**
* ib_post_send - Posts a list of work requests to the send queue of
* the specified QP.
Expand Down

0 comments on commit 3e8ae34

Please sign in to comment.