tests/linux: use Akaros's CFLAGS
[akaros.git] / kern / drivers / net / mlx4 / alloc.c
1 /*
2  * Copyright (c) 2006, 2007 Cisco Systems, Inc.  All rights reserved.
3  * Copyright (c) 2007, 2008 Mellanox Technologies. 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 <linux_compat.h>
35 #include "mlx4.h"
36
37 uint32_t mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap)
38 {
39         uint32_t obj;
40
41         spin_lock(&bitmap->lock);
42
43         obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
44         if (obj >= bitmap->max) {
45                 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
46                                 & bitmap->mask;
47                 obj = find_first_zero_bit(bitmap->table, bitmap->max);
48         }
49
50         if (obj < bitmap->max) {
51                 set_bit(obj, bitmap->table);
52                 bitmap->last = (obj + 1);
53                 if (bitmap->last == bitmap->max)
54                         bitmap->last = 0;
55                 obj |= bitmap->top;
56         } else
57                 obj = -1;
58
59         if (obj != -1)
60                 --bitmap->avail;
61
62         spin_unlock(&bitmap->lock);
63
64         return obj;
65 }
66
67 void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, uint32_t obj, int use_rr)
68 {
69         mlx4_bitmap_free_range(bitmap, obj, 1, use_rr);
70 }
71
72 static unsigned long find_aligned_range(unsigned long *bitmap,
73                                         uint32_t start, uint32_t nbits,
74                                         int len, int align,
75                                         uint32_t skip_mask)
76 {
77         unsigned long end, i;
78
79 again:
80         start = ALIGN(start, align);
81
82         while ((start < nbits) && (test_bit(start, bitmap) ||
83                                    (start & skip_mask)))
84                 start += align;
85
86         if (start >= nbits)
87                 return -1;
88
89         end = start+len;
90         if (end > nbits)
91                 return -1;
92
93         for (i = start + 1; i < end; i++) {
94                 if (test_bit(i, bitmap) || ((uint32_t)i & skip_mask)) {
95                         start = i + 1;
96                         goto again;
97                 }
98         }
99
100         return start;
101 }
102
103 uint32_t mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt,
104                             int align, uint32_t skip_mask)
105 {
106         uint32_t obj;
107
108         if (likely(cnt == 1 && align == 1 && !skip_mask))
109                 return mlx4_bitmap_alloc(bitmap);
110
111         spin_lock(&bitmap->lock);
112
113         obj = find_aligned_range(bitmap->table, bitmap->last,
114                                  bitmap->max, cnt, align, skip_mask);
115         if (obj >= bitmap->max) {
116                 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
117                                 & bitmap->mask;
118                 obj = find_aligned_range(bitmap->table, 0, bitmap->max,
119                                          cnt, align, skip_mask);
120         }
121
122         if (obj < bitmap->max) {
123                 bitmap_set(bitmap->table, obj, cnt);
124                 if (obj == bitmap->last) {
125                         bitmap->last = (obj + cnt);
126                         if (bitmap->last >= bitmap->max)
127                                 bitmap->last = 0;
128                 }
129                 obj |= bitmap->top;
130         } else
131                 obj = -1;
132
133         if (obj != -1)
134                 bitmap->avail -= cnt;
135
136         spin_unlock(&bitmap->lock);
137
138         return obj;
139 }
140
141 uint32_t mlx4_bitmap_avail(struct mlx4_bitmap *bitmap)
142 {
143         return bitmap->avail;
144 }
145
146 static uint32_t mlx4_bitmap_masked_value(struct mlx4_bitmap *bitmap,
147                                          uint32_t obj)
148 {
149         return obj & (bitmap->max + bitmap->reserved_top - 1);
150 }
151
152 void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, uint32_t obj, int cnt,
153                             int use_rr)
154 {
155         obj &= bitmap->max + bitmap->reserved_top - 1;
156
157         spin_lock(&bitmap->lock);
158         if (!use_rr) {
159                 bitmap->last = MIN(bitmap->last, obj);
160                 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
161                                 & bitmap->mask;
162         }
163         bitmap_clear(bitmap->table, obj, cnt);
164         bitmap->avail += cnt;
165         spin_unlock(&bitmap->lock);
166 }
167
168 int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, uint32_t num, uint32_t mask,
169                      uint32_t reserved_bot, uint32_t reserved_top)
170 {
171         /* num must be a power of 2 */
172         if (num != ROUNDUPPWR2(num))
173                 return -EINVAL;
174
175         bitmap->last = 0;
176         bitmap->top  = 0;
177         bitmap->max  = num - reserved_top;
178         bitmap->mask = mask;
179         bitmap->reserved_top = reserved_top;
180         bitmap->avail = num - reserved_top - reserved_bot;
181         bitmap->effective_len = bitmap->avail;
182         spinlock_init(&bitmap->lock);
183         bitmap->table = kzmalloc(BITS_TO_LONGS(bitmap->max) * sizeof(long),
184                                  MEM_WAIT);
185         if (!bitmap->table)
186                 return -ENOMEM;
187
188         bitmap_set(bitmap->table, 0, reserved_bot);
189
190         return 0;
191 }
192
193 void mlx4_bitmap_cleanup(struct mlx4_bitmap *bitmap)
194 {
195         kfree(bitmap->table);
196 }
197
198 struct mlx4_zone_allocator {
199         struct list_head                entries;
200         struct list_head                prios;
201         uint32_t                                last_uid;
202         uint32_t                                mask;
203         /* protect the zone_allocator from concurrent accesses */
204         spinlock_t                      lock;
205         enum mlx4_zone_alloc_flags      flags;
206 };
207
208 struct mlx4_zone_entry {
209         struct list_head                list;
210         struct list_head                prio_list;
211         uint32_t                                uid;
212         struct mlx4_zone_allocator      *allocator;
213         struct mlx4_bitmap              *bitmap;
214         int                             use_rr;
215         int                             priority;
216         int                             offset;
217         enum mlx4_zone_flags            flags;
218 };
219
220 struct mlx4_zone_allocator *mlx4_zone_allocator_create(enum mlx4_zone_alloc_flags flags)
221 {
222         struct mlx4_zone_allocator *zones = kmalloc(sizeof(*zones),
223                                                     MEM_WAIT);
224
225         if (NULL == zones)
226                 return NULL;
227
228         INIT_LIST_HEAD(&zones->entries);
229         INIT_LIST_HEAD(&zones->prios);
230         spinlock_init(&zones->lock);
231         zones->last_uid = 0;
232         zones->mask = 0;
233         zones->flags = flags;
234
235         return zones;
236 }
237
238 int mlx4_zone_add_one(struct mlx4_zone_allocator *zone_alloc,
239                       struct mlx4_bitmap *bitmap,
240                       uint32_t flags,
241                       int priority,
242                       int offset,
243                       uint32_t *puid)
244 {
245         uint32_t mask = mlx4_bitmap_masked_value(bitmap, (uint32_t)-1);
246         struct mlx4_zone_entry *it;
247         struct mlx4_zone_entry *zone = kmalloc(sizeof(*zone), MEM_WAIT);
248
249         if (NULL == zone)
250                 return -ENOMEM;
251
252         zone->flags = flags;
253         zone->bitmap = bitmap;
254         zone->use_rr = (flags & MLX4_ZONE_USE_RR) ? MLX4_USE_RR : 0;
255         zone->priority = priority;
256         zone->offset = offset;
257
258         spin_lock(&zone_alloc->lock);
259
260         zone->uid = zone_alloc->last_uid++;
261         zone->allocator = zone_alloc;
262
263         if (zone_alloc->mask < mask)
264                 zone_alloc->mask = mask;
265
266         list_for_each_entry(it, &zone_alloc->prios, prio_list)
267                 if (it->priority >= priority)
268                         break;
269
270         if (&it->prio_list == &zone_alloc->prios || it->priority > priority)
271                 list_add_tail(&zone->prio_list, &it->prio_list);
272         list_add_tail(&zone->list, &it->list);
273
274         spin_unlock(&zone_alloc->lock);
275
276         *puid = zone->uid;
277
278         return 0;
279 }
280
281 /* Should be called under a lock */
282 static int __mlx4_zone_remove_one_entry(struct mlx4_zone_entry *entry)
283 {
284         struct mlx4_zone_allocator *zone_alloc = entry->allocator;
285
286         if (!list_empty(&entry->prio_list)) {
287                 /* Check if we need to add an alternative node to the prio list */
288                 if (!list_is_last(&entry->list, &zone_alloc->entries)) {
289                         struct mlx4_zone_entry *next = list_first_entry(&entry->list,
290                                                                         typeof(*next),
291                                                                         list);
292
293                         if (next->priority == entry->priority)
294                                 list_add_tail(&next->prio_list, &entry->prio_list);
295                 }
296
297                 list_del(&entry->prio_list);
298         }
299
300         list_del(&entry->list);
301
302         if (zone_alloc->flags & MLX4_ZONE_ALLOC_FLAGS_NO_OVERLAP) {
303                 uint32_t mask = 0;
304                 struct mlx4_zone_entry *it;
305
306                 list_for_each_entry(it, &zone_alloc->prios, prio_list) {
307                         uint32_t cur_mask = mlx4_bitmap_masked_value(it->bitmap,
308                                                                      (uint32_t)-1);
309
310                         if (mask < cur_mask)
311                                 mask = cur_mask;
312                 }
313                 zone_alloc->mask = mask;
314         }
315
316         return 0;
317 }
318
319 void mlx4_zone_allocator_destroy(struct mlx4_zone_allocator *zone_alloc)
320 {
321         struct mlx4_zone_entry *zone, *tmp;
322
323         spin_lock(&zone_alloc->lock);
324
325         list_for_each_entry_safe(zone, tmp, &zone_alloc->entries, list) {
326                 list_del(&zone->list);
327                 list_del(&zone->prio_list);
328                 kfree(zone);
329         }
330
331         spin_unlock(&zone_alloc->lock);
332         kfree(zone_alloc);
333 }
334
335 /* Should be called under a lock */
336 static uint32_t __mlx4_alloc_from_zone(struct mlx4_zone_entry *zone, int count,
337                                   int align, uint32_t skip_mask,
338                                   uint32_t *puid)
339 {
340         uint32_t uid;
341         uint32_t res;
342         struct mlx4_zone_allocator *zone_alloc = zone->allocator;
343         struct mlx4_zone_entry *curr_node;
344
345         res = mlx4_bitmap_alloc_range(zone->bitmap, count,
346                                       align, skip_mask);
347
348         if (res != (uint32_t)-1) {
349                 res += zone->offset;
350                 uid = zone->uid;
351                 goto out;
352         }
353
354         list_for_each_entry(curr_node, &zone_alloc->prios, prio_list) {
355                 if (unlikely(curr_node->priority == zone->priority))
356                         break;
357         }
358
359         if (zone->flags & MLX4_ZONE_ALLOW_ALLOC_FROM_LOWER_PRIO) {
360                 struct mlx4_zone_entry *it = curr_node;
361
362                 list_for_each_entry_continue_reverse(it, &zone_alloc->entries, list) {
363                         res = mlx4_bitmap_alloc_range(it->bitmap, count,
364                                                       align, skip_mask);
365                         if (res != (uint32_t)-1) {
366                                 res += it->offset;
367                                 uid = it->uid;
368                                 goto out;
369                         }
370                 }
371         }
372
373         if (zone->flags & MLX4_ZONE_ALLOW_ALLOC_FROM_EQ_PRIO) {
374                 struct mlx4_zone_entry *it = curr_node;
375
376                 list_for_each_entry_from(it, &zone_alloc->entries, list) {
377                         if (unlikely(it == zone))
378                                 continue;
379
380                         if (unlikely(it->priority != curr_node->priority))
381                                 break;
382
383                         res = mlx4_bitmap_alloc_range(it->bitmap, count,
384                                                       align, skip_mask);
385                         if (res != (uint32_t)-1) {
386                                 res += it->offset;
387                                 uid = it->uid;
388                                 goto out;
389                         }
390                 }
391         }
392
393         if (zone->flags & MLX4_ZONE_FALLBACK_TO_HIGHER_PRIO) {
394                 if (list_is_last(&curr_node->prio_list, &zone_alloc->prios))
395                         goto out;
396
397                 curr_node = list_first_entry(&curr_node->prio_list,
398                                              typeof(*curr_node),
399                                              prio_list);
400
401                 list_for_each_entry_from(curr_node, &zone_alloc->entries, list) {
402                         res = mlx4_bitmap_alloc_range(curr_node->bitmap, count,
403                                                       align, skip_mask);
404                         if (res != (uint32_t)-1) {
405                                 res += curr_node->offset;
406                                 uid = curr_node->uid;
407                                 goto out;
408                         }
409                 }
410         }
411
412 out:
413         if (NULL != puid && res != (uint32_t)-1)
414                 *puid = uid;
415         return res;
416 }
417
418 /* Should be called under a lock */
419 static void __mlx4_free_from_zone(struct mlx4_zone_entry *zone, uint32_t obj,
420                                   uint32_t count)
421 {
422         mlx4_bitmap_free_range(zone->bitmap, obj - zone->offset, count, zone->use_rr);
423 }
424
425 /* Should be called under a lock */
426 static struct mlx4_zone_entry *__mlx4_find_zone_by_uid(
427                 struct mlx4_zone_allocator *zones, uint32_t uid)
428 {
429         struct mlx4_zone_entry *zone;
430
431         list_for_each_entry(zone, &zones->entries, list) {
432                 if (zone->uid == uid)
433                         return zone;
434         }
435
436         return NULL;
437 }
438
439 struct mlx4_bitmap *mlx4_zone_get_bitmap(struct mlx4_zone_allocator *zones,
440                                          uint32_t uid)
441 {
442         struct mlx4_zone_entry *zone;
443         struct mlx4_bitmap *bitmap;
444
445         spin_lock(&zones->lock);
446
447         zone = __mlx4_find_zone_by_uid(zones, uid);
448
449         bitmap = zone == NULL ? NULL : zone->bitmap;
450
451         spin_unlock(&zones->lock);
452
453         return bitmap;
454 }
455
456 int mlx4_zone_remove_one(struct mlx4_zone_allocator *zones, uint32_t uid)
457 {
458         struct mlx4_zone_entry *zone;
459         int res;
460
461         spin_lock(&zones->lock);
462
463         zone = __mlx4_find_zone_by_uid(zones, uid);
464
465         if (NULL == zone) {
466                 res = -1;
467                 goto out;
468         }
469
470         res = __mlx4_zone_remove_one_entry(zone);
471
472 out:
473         spin_unlock(&zones->lock);
474         kfree(zone);
475
476         return res;
477 }
478
479 /* Should be called under a lock */
480 static struct mlx4_zone_entry *__mlx4_find_zone_by_uid_unique(
481                 struct mlx4_zone_allocator *zones, uint32_t obj)
482 {
483         struct mlx4_zone_entry *zone, *zone_candidate = NULL;
484         uint32_t dist = (uint32_t)-1;
485
486         /* Search for the smallest zone that this obj could be
487          * allocated from. This is done in order to handle
488          * situations when small bitmaps are allocated from bigger
489          * bitmaps (and the allocated space is marked as reserved in
490          * the bigger bitmap.
491          */
492         list_for_each_entry(zone, &zones->entries, list) {
493                 if (obj >= zone->offset) {
494                         uint32_t mobj = (obj - zone->offset) & zones->mask;
495
496                         if (mobj < zone->bitmap->max) {
497                                 uint32_t curr_dist = zone->bitmap->effective_len;
498
499                                 if (curr_dist < dist) {
500                                         dist = curr_dist;
501                                         zone_candidate = zone;
502                                 }
503                         }
504                 }
505         }
506
507         return zone_candidate;
508 }
509
510 uint32_t mlx4_zone_alloc_entries(struct mlx4_zone_allocator *zones,
511                                  uint32_t uid, int count,
512                                  int align, uint32_t skip_mask,
513                                  uint32_t *puid)
514 {
515         struct mlx4_zone_entry *zone;
516         int res = -1;
517
518         spin_lock(&zones->lock);
519
520         zone = __mlx4_find_zone_by_uid(zones, uid);
521
522         if (NULL == zone)
523                 goto out;
524
525         res = __mlx4_alloc_from_zone(zone, count, align, skip_mask, puid);
526
527 out:
528         spin_unlock(&zones->lock);
529
530         return res;
531 }
532
533 uint32_t mlx4_zone_free_entries(struct mlx4_zone_allocator *zones,
534                                 uint32_t uid, uint32_t obj, uint32_t count)
535 {
536         struct mlx4_zone_entry *zone;
537         int res = 0;
538
539         spin_lock(&zones->lock);
540
541         zone = __mlx4_find_zone_by_uid(zones, uid);
542
543         if (NULL == zone) {
544                 res = -1;
545                 goto out;
546         }
547
548         __mlx4_free_from_zone(zone, obj, count);
549
550 out:
551         spin_unlock(&zones->lock);
552
553         return res;
554 }
555
556 uint32_t mlx4_zone_free_entries_unique(struct mlx4_zone_allocator *zones,
557                                        uint32_t obj, uint32_t count)
558 {
559         struct mlx4_zone_entry *zone;
560         int res;
561
562         if (!(zones->flags & MLX4_ZONE_ALLOC_FLAGS_NO_OVERLAP))
563                 return -EFAULT;
564
565         spin_lock(&zones->lock);
566
567         zone = __mlx4_find_zone_by_uid_unique(zones, obj);
568
569         if (NULL == zone) {
570                 res = -1;
571                 goto out;
572         }
573
574         __mlx4_free_from_zone(zone, obj, count);
575         res = 0;
576
577 out:
578         spin_unlock(&zones->lock);
579
580         return res;
581 }
582 /*
583  * Handling for queue buffers -- we allocate a bunch of memory and
584  * register it in a memory region at HCA virtual address 0.  If the
585  * requested size is > max_direct, we split the allocation into
586  * multiple pages, so we don't require too much contiguous memory.
587  */
588
589 int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
590                    struct mlx4_buf *buf, gfp_t gfp)
591 {
592         dma_addr_t t;
593
594 #if 0 // AKAROS_PORT
595         if (size <= max_direct) {
596 #else
597         if (size > max_direct)
598                 printd("size %p max_direct %p\n", size, max_direct);
599         if (1) {
600 #endif
601                 buf->nbufs        = 1;
602                 buf->npages       = 1;
603                 buf->page_shift   = get_order(size) + PAGE_SHIFT;
604                 buf->direct.buf   =
605                         dma_alloc_coherent(&dev->persist->pdev->linux_dev, size,
606                                            &t, gfp);
607                 if (!buf->direct.buf)
608                         return -ENOMEM;
609
610                 buf->direct.map = t;
611
612                 while (t & ((1 << buf->page_shift) - 1)) {
613                         --buf->page_shift;
614                         buf->npages *= 2;
615                 }
616
617                 memset(buf->direct.buf, 0, size);
618         } else {
619                 panic("Disabled");
620 #if 0 // AKAROS_PORT
621                 int i;
622
623                 buf->direct.buf  = NULL;
624                 buf->nbufs       = (size + PAGE_SIZE - 1) / PAGE_SIZE;
625                 buf->npages      = buf->nbufs;
626                 buf->page_shift  = PAGE_SHIFT;
627                 buf->page_list   = kzmalloc((buf->nbufs) * (sizeof(*buf->page_list)),
628                                             gfp);
629                 if (!buf->page_list)
630                         return -ENOMEM;
631
632                 for (i = 0; i < buf->nbufs; ++i) {
633                         buf->page_list[i].buf =
634                                 dma_alloc_coherent(&dev->persist->pdev->linux_dev,
635                                                    PAGE_SIZE,
636                                                    &t, gfp);
637                         if (!buf->page_list[i].buf)
638                                 goto err_free;
639
640                         buf->page_list[i].map = t;
641
642                         memset(buf->page_list[i].buf, 0, PAGE_SIZE);
643                 }
644
645                 if (BITS_PER_LONG == 64) {
646                         struct page **pages;
647                         pages = kmalloc(sizeof *pages * buf->nbufs, gfp);
648                         if (!pages)
649                                 goto err_free;
650                         for (i = 0; i < buf->nbufs; ++i)
651                                 pages[i] = kva2page(buf->page_list[i].buf);
652                         buf->direct.buf = vmap(pages, buf->nbufs, VM_MAP, PAGE_KERNEL);
653                         kfree(pages);
654                         if (!buf->direct.buf)
655                                 goto err_free;
656                 }
657 #endif
658         }
659
660         return 0;
661
662 err_free:
663         mlx4_buf_free(dev, size, buf);
664
665         return -ENOMEM;
666 }
667 EXPORT_SYMBOL_GPL(mlx4_buf_alloc);
668
669 void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf)
670 {
671         int i;
672
673         if (buf->nbufs == 1)
674                 dma_free_coherent(&dev->persist->pdev->linux_dev, size,
675                                   buf->direct.buf,
676                                   buf->direct.map);
677         else {
678                 panic("Disabled");
679 #if 0 // AKAROS_PORT
680                 if (BITS_PER_LONG == 64)
681                         vunmap(buf->direct.buf);
682
683                 for (i = 0; i < buf->nbufs; ++i)
684                         if (buf->page_list[i].buf)
685                                 dma_free_coherent(&dev->persist->pdev->linux_dev,
686                                                   PAGE_SIZE,
687                                                   buf->page_list[i].buf,
688                                                   buf->page_list[i].map);
689                 kfree(buf->page_list);
690 #endif
691         }
692 }
693 EXPORT_SYMBOL_GPL(mlx4_buf_free);
694
695 static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device,
696                                                  gfp_t gfp)
697 {
698         struct mlx4_db_pgdir *pgdir;
699
700         pgdir = kzmalloc(sizeof *pgdir, gfp);
701         if (!pgdir)
702                 return NULL;
703
704         bitmap_fill(pgdir->order1, MLX4_DB_PER_PAGE / 2);
705         pgdir->bits[0] = pgdir->order0;
706         pgdir->bits[1] = pgdir->order1;
707         pgdir->db_page = dma_alloc_coherent(dma_device, PAGE_SIZE,
708                                             &pgdir->db_dma, gfp);
709         if (!pgdir->db_page) {
710                 kfree(pgdir);
711                 return NULL;
712         }
713
714         return pgdir;
715 }
716
717 static int mlx4_alloc_db_from_pgdir(struct mlx4_db_pgdir *pgdir,
718                                     struct mlx4_db *db, int order)
719 {
720         int o;
721         int i;
722
723         for (o = order; o <= 1; ++o) {
724                 i = find_first_bit(pgdir->bits[o], MLX4_DB_PER_PAGE >> o);
725                 if (i < MLX4_DB_PER_PAGE >> o)
726                         goto found;
727         }
728
729         return -ENOMEM;
730
731 found:
732         clear_bit(i, pgdir->bits[o]);
733
734         i <<= o;
735
736         if (o > order)
737                 set_bit(i ^ 1, pgdir->bits[order]);
738
739         db->u.pgdir = pgdir;
740         db->index   = i;
741         db->db      = pgdir->db_page + db->index;
742         db->dma     = pgdir->db_dma  + db->index * 4;
743         db->order   = order;
744
745         return 0;
746 }
747
748 int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order, gfp_t gfp)
749 {
750         struct mlx4_priv *priv = mlx4_priv(dev);
751         struct mlx4_db_pgdir *pgdir;
752         int ret = 0;
753
754         qlock(&priv->pgdir_mutex);
755
756         list_for_each_entry(pgdir, &priv->pgdir_list, list)
757                 if (!mlx4_alloc_db_from_pgdir(pgdir, db, order))
758                         goto out;
759
760         pgdir = mlx4_alloc_db_pgdir(&dev->persist->pdev->linux_dev, gfp);
761         if (!pgdir) {
762                 ret = -ENOMEM;
763                 goto out;
764         }
765
766         list_add(&pgdir->list, &priv->pgdir_list);
767
768         /* This should never fail -- we just allocated an empty page: */
769         warn_on(mlx4_alloc_db_from_pgdir(pgdir, db, order));
770
771 out:
772         qunlock(&priv->pgdir_mutex);
773
774         return ret;
775 }
776 EXPORT_SYMBOL_GPL(mlx4_db_alloc);
777
778 void mlx4_db_free(struct mlx4_dev *dev, struct mlx4_db *db)
779 {
780         struct mlx4_priv *priv = mlx4_priv(dev);
781         int o;
782         int i;
783
784         qlock(&priv->pgdir_mutex);
785
786         o = db->order;
787         i = db->index;
788
789         if (db->order == 0 && test_bit(i ^ 1, db->u.pgdir->order0)) {
790                 clear_bit(i ^ 1, db->u.pgdir->order0);
791                 ++o;
792         }
793         i >>= o;
794         set_bit(i, db->u.pgdir->bits[o]);
795
796         if (bitmap_full(db->u.pgdir->order1, MLX4_DB_PER_PAGE / 2)) {
797                 dma_free_coherent(&dev->persist->pdev->linux_dev, PAGE_SIZE,
798                                   db->u.pgdir->db_page, db->u.pgdir->db_dma);
799                 list_del(&db->u.pgdir->list);
800                 kfree(db->u.pgdir);
801         }
802
803         qunlock(&priv->pgdir_mutex);
804 }
805 EXPORT_SYMBOL_GPL(mlx4_db_free);
806
807 int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
808                        int size, int max_direct)
809 {
810         int err;
811
812         err = mlx4_db_alloc(dev, &wqres->db, 1, MEM_WAIT);
813         if (err)
814                 return err;
815
816         *wqres->db.db = 0;
817
818         err = mlx4_buf_alloc(dev, size, max_direct, &wqres->buf, MEM_WAIT);
819         if (err)
820                 goto err_db;
821
822         err = mlx4_mtt_init(dev, wqres->buf.npages, wqres->buf.page_shift,
823                             &wqres->mtt);
824         if (err)
825                 goto err_buf;
826
827         err = mlx4_buf_write_mtt(dev, &wqres->mtt, &wqres->buf, MEM_WAIT);
828         if (err)
829                 goto err_mtt;
830
831         return 0;
832
833 err_mtt:
834         mlx4_mtt_cleanup(dev, &wqres->mtt);
835 err_buf:
836         mlx4_buf_free(dev, size, &wqres->buf);
837 err_db:
838         mlx4_db_free(dev, &wqres->db);
839
840         return err;
841 }
842 EXPORT_SYMBOL_GPL(mlx4_alloc_hwq_res);
843
844 void mlx4_free_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
845                        int size)
846 {
847         mlx4_mtt_cleanup(dev, &wqres->mtt);
848         mlx4_buf_free(dev, size, &wqres->buf);
849         mlx4_db_free(dev, &wqres->db);
850 }
851 EXPORT_SYMBOL_GPL(mlx4_free_hwq_res);