diff options
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_srq.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_srq.c | 47 |
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 | |||
168 | bail: | 182 | bail: |
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 | ||
248 | bail: | 269 | bail: |
@@ -266,7 +287,9 @@ int ipath_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) | |||
266 | int ipath_destroy_srq(struct ib_srq *ibsrq) | 287 | int 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 | ||