#include"srq.h" #include"vt.h" #include"qp.h" /** * rvt_driver_srq_init - init srq resources on a per driver basis * @rdi: rvt dev structure * * Do any initialization needed when a driver registers with rdmavt.
*/ void rvt_driver_srq_init(struct rvt_dev_info *rdi)
{
spin_lock_init(&rdi->n_srqs_lock);
rdi->n_srqs_allocated = 0;
}
/** * rvt_create_srq - create a shared receive queue * @ibsrq: the protection domain of the SRQ to create * @srq_init_attr: the attributes of the SRQ * @udata: data from libibverbs when creating a user SRQ * * Return: 0 on success
*/ int rvt_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *srq_init_attr, struct ib_udata *udata)
{ struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device); struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq);
u32 sz; int ret;
if (srq_init_attr->srq_type != IB_SRQT_BASIC) return -EOPNOTSUPP;
/* * Need to use vmalloc() if we want to support large #s of entries.
*/
srq->rq.size = srq_init_attr->attr.max_wr + 1;
srq->rq.max_sge = srq_init_attr->attr.max_sge;
sz = sizeof(struct ib_sge) * srq->rq.max_sge + sizeof(struct rvt_rwqe); if (rvt_alloc_rq(&srq->rq, srq->rq.size * sz,
dev->dparms.node, udata)) {
ret = -ENOMEM; goto bail_srq;
}
/* * Return the address of the RWQ as the offset to mmap. * See rvt_mmap() for details.
*/ if (udata && udata->outlen >= sizeof(__u64)) {
u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz;
srq->ip = rvt_create_mmap_info(dev, s, udata, srq->rq.wq); if (IS_ERR(srq->ip)) {
ret = PTR_ERR(srq->ip); goto bail_wq;
}
ret = ib_copy_to_udata(udata, &srq->ip->offset, sizeof(srq->ip->offset)); if (ret) goto bail_ip;
}
/** * rvt_modify_srq - modify a shared receive queue * @ibsrq: the SRQ to modify * @attr: the new attributes of the SRQ * @attr_mask: indicates which attributes to modify * @udata: user data for libibverbs.so * * Return: 0 on success
*/ int rvt_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, enum ib_srq_attr_mask attr_mask, struct ib_udata *udata)
{ struct rvt_srq *srq = ibsrq_to_rvtsrq(ibsrq); struct rvt_dev_info *dev = ib_to_rvt(ibsrq->device); struct rvt_rq tmp_rq = {}; int ret = 0;
/* Check that the requested sizes are below the limits. */ if ((attr->max_wr > dev->dparms.props.max_srq_wr) ||
((attr_mask & IB_SRQ_LIMIT) ?
attr->srq_limit : srq->limit) > attr->max_wr) return -EINVAL;
sz = sizeof(struct rvt_rwqe) +
srq->rq.max_sge * sizeof(struct ib_sge);
size = attr->max_wr + 1; if (rvt_alloc_rq(&tmp_rq, size * sz, dev->dparms.node,
udata)) return -ENOMEM; /* Check that we can write the offset to mmap. */ if (udata && udata->inlen >= sizeof(__u64)) {
__u64 offset_addr;
__u64 offset = 0;
ret = ib_copy_from_udata(&offset_addr, udata, sizeof(offset_addr)); if (ret) goto bail_free;
udata->outbuf = (void __user *)
(unsignedlong)offset_addr;
ret = ib_copy_to_udata(udata, &offset, sizeof(offset)); if (ret) goto bail_free;
}
spin_lock_irq(&srq->rq.kwq->c_lock); /* * validate head and tail pointer values and compute * the number of remaining WQEs.
*/ if (udata) {
owq = srq->rq.wq;
head = RDMA_READ_UAPI_ATOMIC(owq->head);
tail = RDMA_READ_UAPI_ATOMIC(owq->tail);
} else {
okwq = srq->rq.kwq;
head = okwq->head;
tail = okwq->tail;
} if (head >= srq->rq.size || tail >= srq->rq.size) {
ret = -EINVAL; goto bail_unlock;
}
n = head; if (n < tail)
n += srq->rq.size - tail; else
n -= tail; if (size <= n) {
ret = -EINVAL; goto bail_unlock;
}
n = 0;
p = tmp_rq.kwq->curr_wq; while (tail != head) { struct rvt_rwqe *wqe; int i;
/* * Return the offset to mmap. * See rvt_mmap() for details.
*/ if (udata && udata->inlen >= sizeof(__u64)) {
ret = ib_copy_to_udata(udata, &ip->offset, sizeof(ip->offset)); if (ret) return ret;
}
/* * Put user mapping info onto the pending list * unless it already is on the list.
*/
spin_lock_irq(&dev->pending_lock); if (list_empty(&ip->pending_mmaps))
list_add(&ip->pending_mmaps,
&dev->pending_mmaps);
spin_unlock_irq(&dev->pending_lock);
}
} elseif (attr_mask & IB_SRQ_LIMIT) {
spin_lock_irq(&srq->rq.kwq->c_lock); if (attr->srq_limit >= srq->rq.size)
ret = -EINVAL; else
srq->limit = attr->srq_limit;
spin_unlock_irq(&srq->rq.kwq->c_lock);
} return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.