IB/qib: Avoid returning EBUSY from MR deregister
[linux.git] / drivers / infiniband / hw / qib / qib_keys.c
1 /*
2  * Copyright (c) 2006, 2007, 2009 QLogic Corporation. All rights reserved.
3  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33
34 #include "qib.h"
35
36 /**
37  * qib_alloc_lkey - allocate an lkey
38  * @mr: memory region that this lkey protects
39  * @dma_region: 0->normal key, 1->restricted DMA key
40  *
41  * Returns 0 if successful, otherwise returns -errno.
42  *
43  * Increments mr reference count and sets published
44  * as required.
45  *
46  * Sets the lkey field mr for non-dma regions.
47  *
48  */
49
50 int qib_alloc_lkey(struct qib_mregion *mr, int dma_region)
51 {
52         unsigned long flags;
53         u32 r;
54         u32 n;
55         int ret = 0;
56         struct qib_ibdev *dev = to_idev(mr->pd->device);
57         struct qib_lkey_table *rkt = &dev->lk_table;
58
59         spin_lock_irqsave(&rkt->lock, flags);
60
61         /* special case for dma_mr lkey == 0 */
62         if (dma_region) {
63                 /* should the dma_mr be relative to the pd? */
64                 if (!dev->dma_mr) {
65                         qib_get_mr(mr);
66                         dev->dma_mr = mr;
67                         mr->lkey_published = 1;
68                 }
69                 goto success;
70         }
71
72         /* Find the next available LKEY */
73         r = rkt->next;
74         n = r;
75         for (;;) {
76                 if (rkt->table[r] == NULL)
77                         break;
78                 r = (r + 1) & (rkt->max - 1);
79                 if (r == n)
80                         goto bail;
81         }
82         rkt->next = (r + 1) & (rkt->max - 1);
83         /*
84          * Make sure lkey is never zero which is reserved to indicate an
85          * unrestricted LKEY.
86          */
87         rkt->gen++;
88         mr->lkey = (r << (32 - ib_qib_lkey_table_size)) |
89                 ((((1 << (24 - ib_qib_lkey_table_size)) - 1) & rkt->gen)
90                  << 8);
91         if (mr->lkey == 0) {
92                 mr->lkey |= 1 << 8;
93                 rkt->gen++;
94         }
95         qib_get_mr(mr);
96         rkt->table[r] = mr;
97         mr->lkey_published = 1;
98 success:
99         spin_unlock_irqrestore(&rkt->lock, flags);
100 out:
101         return ret;
102 bail:
103         spin_unlock_irqrestore(&rkt->lock, flags);
104         ret = -ENOMEM;
105         goto out;
106 }
107
108 /**
109  * qib_free_lkey - free an lkey
110  * @mr: mr to free from tables
111  */
112 void qib_free_lkey(struct qib_mregion *mr)
113 {
114         unsigned long flags;
115         u32 lkey = mr->lkey;
116         u32 r;
117         struct qib_ibdev *dev = to_idev(mr->pd->device);
118         struct qib_lkey_table *rkt = &dev->lk_table;
119
120         spin_lock_irqsave(&rkt->lock, flags);
121         if (!mr->lkey_published)
122                 goto out;
123         mr->lkey_published = 0;
124
125
126         spin_lock_irqsave(&dev->lk_table.lock, flags);
127         if (lkey == 0) {
128                 if (dev->dma_mr && dev->dma_mr == mr) {
129                         qib_put_mr(dev->dma_mr);
130                         dev->dma_mr = NULL;
131                 }
132         } else {
133                 r = lkey >> (32 - ib_qib_lkey_table_size);
134                 qib_put_mr(dev->dma_mr);
135                 rkt->table[r] = NULL;
136         }
137 out:
138         spin_unlock_irqrestore(&dev->lk_table.lock, flags);
139 }
140
141 /**
142  * qib_lkey_ok - check IB SGE for validity and initialize
143  * @rkt: table containing lkey to check SGE against
144  * @isge: outgoing internal SGE
145  * @sge: SGE to check
146  * @acc: access flags
147  *
148  * Return 1 if valid and successful, otherwise returns 0.
149  *
150  * Check the IB SGE for validity and initialize our internal version
151  * of it.
152  */
153 int qib_lkey_ok(struct qib_lkey_table *rkt, struct qib_pd *pd,
154                 struct qib_sge *isge, struct ib_sge *sge, int acc)
155 {
156         struct qib_mregion *mr;
157         unsigned n, m;
158         size_t off;
159         unsigned long flags;
160
161         /*
162          * We use LKEY == zero for kernel virtual addresses
163          * (see qib_get_dma_mr and qib_dma.c).
164          */
165         spin_lock_irqsave(&rkt->lock, flags);
166         if (sge->lkey == 0) {
167                 struct qib_ibdev *dev = to_idev(pd->ibpd.device);
168
169                 if (pd->user)
170                         goto bail;
171                 if (!dev->dma_mr)
172                         goto bail;
173                 qib_get_mr(dev->dma_mr);
174                 spin_unlock_irqrestore(&rkt->lock, flags);
175
176                 isge->mr = dev->dma_mr;
177                 isge->vaddr = (void *) sge->addr;
178                 isge->length = sge->length;
179                 isge->sge_length = sge->length;
180                 isge->m = 0;
181                 isge->n = 0;
182                 goto ok;
183         }
184         mr = rkt->table[(sge->lkey >> (32 - ib_qib_lkey_table_size))];
185         if (unlikely(mr == NULL || mr->lkey != sge->lkey ||
186                      mr->pd != &pd->ibpd))
187                 goto bail;
188
189         off = sge->addr - mr->user_base;
190         if (unlikely(sge->addr < mr->user_base ||
191                      off + sge->length > mr->length ||
192                      (mr->access_flags & acc) != acc))
193                 goto bail;
194         qib_get_mr(mr);
195         spin_unlock_irqrestore(&rkt->lock, flags);
196
197         off += mr->offset;
198         if (mr->page_shift) {
199                 /*
200                 page sizes are uniform power of 2 so no loop is necessary
201                 entries_spanned_by_off is the number of times the loop below
202                 would have executed.
203                 */
204                 size_t entries_spanned_by_off;
205
206                 entries_spanned_by_off = off >> mr->page_shift;
207                 off -= (entries_spanned_by_off << mr->page_shift);
208                 m = entries_spanned_by_off/QIB_SEGSZ;
209                 n = entries_spanned_by_off%QIB_SEGSZ;
210         } else {
211                 m = 0;
212                 n = 0;
213                 while (off >= mr->map[m]->segs[n].length) {
214                         off -= mr->map[m]->segs[n].length;
215                         n++;
216                         if (n >= QIB_SEGSZ) {
217                                 m++;
218                                 n = 0;
219                         }
220                 }
221         }
222         isge->mr = mr;
223         isge->vaddr = mr->map[m]->segs[n].vaddr + off;
224         isge->length = mr->map[m]->segs[n].length - off;
225         isge->sge_length = sge->length;
226         isge->m = m;
227         isge->n = n;
228 ok:
229         return 1;
230 bail:
231         spin_unlock_irqrestore(&rkt->lock, flags);
232         return 0;
233 }
234
235 /**
236  * qib_rkey_ok - check the IB virtual address, length, and RKEY
237  * @dev: infiniband device
238  * @ss: SGE state
239  * @len: length of data
240  * @vaddr: virtual address to place data
241  * @rkey: rkey to check
242  * @acc: access flags
243  *
244  * Return 1 if successful, otherwise 0.
245  */
246 int qib_rkey_ok(struct qib_qp *qp, struct qib_sge *sge,
247                 u32 len, u64 vaddr, u32 rkey, int acc)
248 {
249         struct qib_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table;
250         struct qib_mregion *mr;
251         unsigned n, m;
252         size_t off;
253         unsigned long flags;
254
255         /*
256          * We use RKEY == zero for kernel virtual addresses
257          * (see qib_get_dma_mr and qib_dma.c).
258          */
259         spin_lock_irqsave(&rkt->lock, flags);
260         if (rkey == 0) {
261                 struct qib_pd *pd = to_ipd(qp->ibqp.pd);
262                 struct qib_ibdev *dev = to_idev(pd->ibpd.device);
263
264                 if (pd->user)
265                         goto bail;
266                 if (!dev->dma_mr)
267                         goto bail;
268                 qib_get_mr(dev->dma_mr);
269                 spin_unlock_irqrestore(&rkt->lock, flags);
270
271                 sge->mr = dev->dma_mr;
272                 sge->vaddr = (void *) vaddr;
273                 sge->length = len;
274                 sge->sge_length = len;
275                 sge->m = 0;
276                 sge->n = 0;
277                 goto ok;
278         }
279
280         mr = rkt->table[(rkey >> (32 - ib_qib_lkey_table_size))];
281         if (unlikely(mr == NULL || mr->lkey != rkey || qp->ibqp.pd != mr->pd))
282                 goto bail;
283
284         off = vaddr - mr->iova;
285         if (unlikely(vaddr < mr->iova || off + len > mr->length ||
286                      (mr->access_flags & acc) == 0))
287                 goto bail;
288         qib_get_mr(mr);
289         spin_unlock_irqrestore(&rkt->lock, flags);
290
291         off += mr->offset;
292         if (mr->page_shift) {
293                 /*
294                 page sizes are uniform power of 2 so no loop is necessary
295                 entries_spanned_by_off is the number of times the loop below
296                 would have executed.
297                 */
298                 size_t entries_spanned_by_off;
299
300                 entries_spanned_by_off = off >> mr->page_shift;
301                 off -= (entries_spanned_by_off << mr->page_shift);
302                 m = entries_spanned_by_off/QIB_SEGSZ;
303                 n = entries_spanned_by_off%QIB_SEGSZ;
304         } else {
305                 m = 0;
306                 n = 0;
307                 while (off >= mr->map[m]->segs[n].length) {
308                         off -= mr->map[m]->segs[n].length;
309                         n++;
310                         if (n >= QIB_SEGSZ) {
311                                 m++;
312                                 n = 0;
313                         }
314                 }
315         }
316         sge->mr = mr;
317         sge->vaddr = mr->map[m]->segs[n].vaddr + off;
318         sge->length = mr->map[m]->segs[n].length - off;
319         sge->sge_length = len;
320         sge->m = m;
321         sge->n = n;
322 ok:
323         return 1;
324 bail:
325         spin_unlock_irqrestore(&rkt->lock, flags);
326         return 0;
327 }
328
329 /*
330  * Initialize the memory region specified by the work reqeust.
331  */
332 int qib_fast_reg_mr(struct qib_qp *qp, struct ib_send_wr *wr)
333 {
334         struct qib_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table;
335         struct qib_pd *pd = to_ipd(qp->ibqp.pd);
336         struct qib_mregion *mr;
337         u32 rkey = wr->wr.fast_reg.rkey;
338         unsigned i, n, m;
339         int ret = -EINVAL;
340         unsigned long flags;
341         u64 *page_list;
342         size_t ps;
343
344         spin_lock_irqsave(&rkt->lock, flags);
345         if (pd->user || rkey == 0)
346                 goto bail;
347
348         mr = rkt->table[(rkey >> (32 - ib_qib_lkey_table_size))];
349         if (unlikely(mr == NULL || qp->ibqp.pd != mr->pd))
350                 goto bail;
351
352         if (wr->wr.fast_reg.page_list_len > mr->max_segs)
353                 goto bail;
354
355         ps = 1UL << wr->wr.fast_reg.page_shift;
356         if (wr->wr.fast_reg.length > ps * wr->wr.fast_reg.page_list_len)
357                 goto bail;
358
359         mr->user_base = wr->wr.fast_reg.iova_start;
360         mr->iova = wr->wr.fast_reg.iova_start;
361         mr->lkey = rkey;
362         mr->length = wr->wr.fast_reg.length;
363         mr->access_flags = wr->wr.fast_reg.access_flags;
364         page_list = wr->wr.fast_reg.page_list->page_list;
365         m = 0;
366         n = 0;
367         for (i = 0; i < wr->wr.fast_reg.page_list_len; i++) {
368                 mr->map[m]->segs[n].vaddr = (void *) page_list[i];
369                 mr->map[m]->segs[n].length = ps;
370                 if (++n == QIB_SEGSZ) {
371                         m++;
372                         n = 0;
373                 }
374         }
375
376         ret = 0;
377 bail:
378         spin_unlock_irqrestore(&rkt->lock, flags);
379         return ret;
380 }