[PATCH] IB/ipath: enforce device resource limits

These limits are somewhat artificial in that we don't actually have any
device limits.  However, the verbs layer expects that such limits exist
and are enforced, so we make up arbitrary (but sensible) limits.

Signed-off-by: Robert Walsh <robert.walsh@qlogic.com>
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Cc: "Michael S. Tsirkin" <mst@mellanox.co.il>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Этот коммит содержится в:
Bryan O'Sullivan
2006-07-01 04:35:58 -07:00
коммит произвёл Linus Torvalds
родитель e8a88f09f2
Коммит fe62546a6a
6 изменённых файлов: 205 добавлений и 34 удалений

Просмотреть файл

@@ -126,11 +126,23 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
struct ib_srq_init_attr *srq_init_attr,
struct ib_udata *udata)
{
struct ipath_ibdev *dev = to_idev(ibpd->device);
struct ipath_srq *srq;
u32 sz;
struct ib_srq *ret;
if (srq_init_attr->attr.max_sge < 1) {
if (dev->n_srqs_allocated == ib_ipath_max_srqs) {
ret = ERR_PTR(-ENOMEM);
goto bail;
}
if (srq_init_attr->attr.max_wr == 0) {
ret = ERR_PTR(-EINVAL);
goto bail;
}
if ((srq_init_attr->attr.max_sge > ib_ipath_max_srq_sges) ||
(srq_init_attr->attr.max_wr > ib_ipath_max_srq_wrs)) {
ret = ERR_PTR(-EINVAL);
goto bail;
}
@@ -165,6 +177,8 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
ret = &srq->ibsrq;
dev->n_srqs_allocated++;
bail:
return ret;
}
@@ -182,24 +196,26 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
unsigned long flags;
int ret;
if (attr_mask & IB_SRQ_LIMIT) {
spin_lock_irqsave(&srq->rq.lock, flags);
srq->limit = attr->srq_limit;
spin_unlock_irqrestore(&srq->rq.lock, flags);
}
if (attr_mask & IB_SRQ_MAX_WR) {
u32 size = attr->max_wr + 1;
struct ipath_rwqe *wq, *p;
u32 n;
u32 sz;
if (attr->max_sge < srq->rq.max_sge) {
if (attr_mask & IB_SRQ_MAX_WR)
if ((attr->max_wr > ib_ipath_max_srq_wrs) ||
(attr->max_sge > srq->rq.max_sge)) {
ret = -EINVAL;
goto bail;
}
if (attr_mask & IB_SRQ_LIMIT)
if (attr->srq_limit >= srq->rq.size) {
ret = -EINVAL;
goto bail;
}
if (attr_mask & IB_SRQ_MAX_WR) {
struct ipath_rwqe *wq, *p;
u32 sz, size, n;
sz = sizeof(struct ipath_rwqe) +
attr->max_sge * sizeof(struct ipath_sge);
size = attr->max_wr + 1;
wq = vmalloc(size * sz);
if (!wq) {
ret = -ENOMEM;
@@ -243,6 +259,11 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
spin_unlock_irqrestore(&srq->rq.lock, flags);
}
if (attr_mask & IB_SRQ_LIMIT) {
spin_lock_irqsave(&srq->rq.lock, flags);
srq->limit = attr->srq_limit;
spin_unlock_irqrestore(&srq->rq.lock, flags);
}
ret = 0;
bail:
@@ -266,7 +287,9 @@ int ipath_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr)
int ipath_destroy_srq(struct ib_srq *ibsrq)
{
struct ipath_srq *srq = to_isrq(ibsrq);
struct ipath_ibdev *dev = to_idev(ibsrq->device);
dev->n_srqs_allocated--;
vfree(srq->rq.wq);
kfree(srq);