aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_srq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_srq.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_srq.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c
index 84db5765998e..f760434660bd 100644
--- a/drivers/infiniband/hw/ipath/ipath_srq.c
+++ b/drivers/infiniband/hw/ipath/ipath_srq.c
@@ -126,11 +126,23 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
126 struct ib_srq_init_attr *srq_init_attr, 126 struct ib_srq_init_attr *srq_init_attr,
127 struct ib_udata *udata) 127 struct ib_udata *udata)
128{ 128{
129 struct ipath_ibdev *dev = to_idev(ibpd->device);
129 struct ipath_srq *srq; 130 struct ipath_srq *srq;
130 u32 sz; 131 u32 sz;
131 struct ib_srq *ret; 132 struct ib_srq *ret;
132 133
133 if (srq_init_attr->attr.max_sge < 1) { 134 if (dev->n_srqs_allocated == ib_ipath_max_srqs) {
135 ret = ERR_PTR(-ENOMEM);
136 goto bail;
137 }
138
139 if (srq_init_attr->attr.max_wr == 0) {
140 ret = ERR_PTR(-EINVAL);
141 goto bail;
142 }
143
144 if ((srq_init_attr->attr.max_sge > ib_ipath_max_srq_sges) ||
145 (srq_init_attr->attr.max_wr > ib_ipath_max_srq_wrs)) {
134 ret = ERR_PTR(-EINVAL); 146 ret = ERR_PTR(-EINVAL);
135 goto bail; 147 goto bail;
136 } 148 }
@@ -165,6 +177,8 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
165 177
166 ret = &srq->ibsrq; 178 ret = &srq->ibsrq;
167 179
180 dev->n_srqs_allocated++;
181
168bail: 182bail:
169 return ret; 183 return ret;
170} 184}
@@ -182,24 +196,26 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
182 unsigned long flags; 196 unsigned long flags;
183 int ret; 197 int ret;
184 198
185 if (attr_mask & IB_SRQ_LIMIT) { 199 if (attr_mask & IB_SRQ_MAX_WR)
186 spin_lock_irqsave(&srq->rq.lock, flags); 200 if ((attr->max_wr > ib_ipath_max_srq_wrs) ||
187 srq->limit = attr->srq_limit; 201 (attr->max_sge > srq->rq.max_sge)) {
188 spin_unlock_irqrestore(&srq->rq.lock, flags); 202 ret = -EINVAL;
189 } 203 goto bail;
190 if (attr_mask & IB_SRQ_MAX_WR) { 204 }
191 u32 size = attr->max_wr + 1;
192 struct ipath_rwqe *wq, *p;
193 u32 n;
194 u32 sz;
195 205
196 if (attr->max_sge < srq->rq.max_sge) { 206 if (attr_mask & IB_SRQ_LIMIT)
207 if (attr->srq_limit >= srq->rq.size) {
197 ret = -EINVAL; 208 ret = -EINVAL;
198 goto bail; 209 goto bail;
199 } 210 }
200 211
212 if (attr_mask & IB_SRQ_MAX_WR) {
213 struct ipath_rwqe *wq, *p;
214 u32 sz, size, n;
215
201 sz = sizeof(struct ipath_rwqe) + 216 sz = sizeof(struct ipath_rwqe) +
202 attr->max_sge * sizeof(struct ipath_sge); 217 attr->max_sge * sizeof(struct ipath_sge);
218 size = attr->max_wr + 1;
203 wq = vmalloc(size * sz); 219 wq = vmalloc(size * sz);
204 if (!wq) { 220 if (!wq) {
205 ret = -ENOMEM; 221 ret = -ENOMEM;
@@ -243,6 +259,11 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
243 spin_unlock_irqrestore(&srq->rq.lock, flags); 259 spin_unlock_irqrestore(&srq->rq.lock, flags);
244 } 260 }
245 261
262 if (attr_mask & IB_SRQ_LIMIT) {
263 spin_lock_irqsave(&srq->rq.lock, flags);
264 srq->limit = attr->srq_limit;
265 spin_unlock_irqrestore(&srq->rq.lock, flags);
266 }
246 ret = 0; 267 ret = 0;
247 268
248bail: 269bail:
@@ -266,7 +287,9 @@ int ipath_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr)
266int ipath_destroy_srq(struct ib_srq *ibsrq) 287int ipath_destroy_srq(struct ib_srq *ibsrq)
267{ 288{
268 struct ipath_srq *srq = to_isrq(ibsrq); 289 struct ipath_srq *srq = to_isrq(ibsrq);
290 struct ipath_ibdev *dev = to_idev(ibsrq->device);
269 291
292 dev->n_srqs_allocated--;
270 vfree(srq->rq.wq); 293 vfree(srq->rq.wq);
271 kfree(srq); 294 kfree(srq);
272 295