Rev 4065 | Rev 5056 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4065 | Rev 4103 | ||
---|---|---|---|
Line 31... | Line 31... | ||
31 | #include |
31 | #include |
32 | #include |
32 | #include |
33 | #include |
33 | #include |
34 | //#include |
34 | //#include |
Line -... | Line 35... | ||
- | 35 | ||
- | 36 | static inline void * __must_check ERR_PTR(long error) |
|
- | 37 | { |
|
- | 38 | return (void *) error; |
|
- | 39 | } |
|
35 | 40 | ||
36 | unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, |
41 | unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, |
Line 37... | Line 42... | ||
37 | unsigned long offset); |
42 | unsigned long offset); |
Line 47... | Line 52... | ||
47 | #define MAX_IDR_FREE (MAX_IDR_LEVEL * 2) |
52 | #define MAX_IDR_FREE (MAX_IDR_LEVEL * 2) |
Line 48... | Line 53... | ||
48 | 53 | ||
49 | static struct idr_layer *idr_preload_head; |
54 | static struct idr_layer *idr_preload_head; |
Line -... | Line 55... | ||
- | 55 | static int idr_preload_cnt; |
|
Line 50... | Line 56... | ||
50 | static int idr_preload_cnt; |
56 | |
51 | 57 | static DEFINE_SPINLOCK(simple_ida_lock); |
|
52 | 58 | ||
53 | /* the maximum ID which can be allocated given idr->layers */ |
59 | /* the maximum ID which can be allocated given idr->layers */ |
Line 460... | Line 466... | ||
460 | idr_fill_slot(idr, ptr, id, pa); |
466 | idr_fill_slot(idr, ptr, id, pa); |
461 | return id; |
467 | return id; |
462 | } |
468 | } |
463 | EXPORT_SYMBOL_GPL(idr_alloc); |
469 | EXPORT_SYMBOL_GPL(idr_alloc); |
Line -... | Line 470... | ||
- | 470 | ||
- | 471 | /** |
|
- | 472 | * idr_alloc_cyclic - allocate new idr entry in a cyclical fashion |
|
- | 473 | * @idr: the (initialized) idr |
|
- | 474 | * @ptr: pointer to be associated with the new id |
|
- | 475 | * @start: the minimum id (inclusive) |
|
- | 476 | * @end: the maximum id (exclusive, <= 0 for max) |
|
- | 477 | * @gfp_mask: memory allocation flags |
|
- | 478 | * |
|
- | 479 | * Essentially the same as idr_alloc, but prefers to allocate progressively |
|
- | 480 | * higher ids if it can. If the "cur" counter wraps, then it will start again |
|
- | 481 | * at the "start" end of the range and allocate one that has already been used. |
|
- | 482 | */ |
|
- | 483 | int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, |
|
- | 484 | gfp_t gfp_mask) |
|
- | 485 | { |
|
- | 486 | int id; |
|
- | 487 | ||
- | 488 | id = idr_alloc(idr, ptr, max(start, idr->cur), end, gfp_mask); |
|
- | 489 | if (id == -ENOSPC) |
|
- | 490 | id = idr_alloc(idr, ptr, start, end, gfp_mask); |
|
- | 491 | ||
- | 492 | if (likely(id >= 0)) |
|
- | 493 | idr->cur = id + 1; |
|
- | 494 | return id; |
|
- | 495 | } |
|
- | 496 | EXPORT_SYMBOL(idr_alloc_cyclic); |
|
464 | 497 | ||
465 | static void idr_remove_warning(int id) |
498 | static void idr_remove_warning(int id) |
466 | { |
499 | { |
467 | WARN(1, "idr_remove called for id=%d which is not allocated.\n", id); |
500 | WARN(1, "idr_remove called for id=%d which is not allocated.\n", id); |
Line 630... | Line 663... | ||
630 | } |
663 | } |
631 | return((void *)p); |
664 | return((void *)p); |
632 | } |
665 | } |
633 | EXPORT_SYMBOL(idr_find_slowpath); |
666 | EXPORT_SYMBOL(idr_find_slowpath); |
Line 634... | Line -... | ||
634 | - | ||
635 | #if 0 |
667 | |
636 | /** |
668 | /** |
637 | * idr_for_each - iterate through all stored pointers |
669 | * idr_for_each - iterate through all stored pointers |
638 | * @idp: idr handle |
670 | * @idp: idr handle |
639 | * @fn: function to be called for each pointer |
671 | * @fn: function to be called for each pointer |
Line 788... | Line 820... | ||
788 | 820 | ||
789 | return old_p; |
821 | return old_p; |
790 | } |
822 | } |
Line 791... | Line -... | ||
791 | EXPORT_SYMBOL(idr_replace); |
- | |
792 | - | ||
793 | - | ||
794 | #endif |
- | |
795 | 823 | EXPORT_SYMBOL(idr_replace); |
|
796 | 824 | ||
797 | void __init idr_init_cache(void) |
825 | void __init idr_init_cache(void) |
798 | { |
826 | { |
799 | //idr_layer_cache = kmem_cache_create("idr_layer_cache", |
827 | //idr_layer_cache = kmem_cache_create("idr_layer_cache", |
Line 856... | Line 884... | ||
856 | * otherwise %1. |
884 | * otherwise %1. |
857 | */ |
885 | */ |
858 | int ida_pre_get(struct ida *ida, gfp_t gfp_mask) |
886 | int ida_pre_get(struct ida *ida, gfp_t gfp_mask) |
859 | { |
887 | { |
860 | /* allocate idr_layers */ |
888 | /* allocate idr_layers */ |
861 | if (!idr_pre_get(&ida->idr, gfp_mask)) |
889 | if (!__idr_pre_get(&ida->idr, gfp_mask)) |
862 | return 0; |
890 | return 0; |
Line 863... | Line 891... | ||
863 | 891 | ||
864 | /* allocate free_bitmap */ |
892 | /* allocate free_bitmap */ |
865 | if (!ida->free_bitmap) { |
893 | if (!ida->free_bitmap) { |
Line 1021... | Line 1049... | ||
1021 | kfree(ida->free_bitmap); |
1049 | kfree(ida->free_bitmap); |
1022 | } |
1050 | } |
1023 | EXPORT_SYMBOL(ida_destroy); |
1051 | EXPORT_SYMBOL(ida_destroy); |
Line 1024... | Line 1052... | ||
1024 | 1052 | ||
- | 1053 | /** |
|
- | 1054 | * ida_simple_get - get a new id. |
|
- | 1055 | * @ida: the (initialized) ida. |
|
- | 1056 | * @start: the minimum id (inclusive, < 0x8000000) |
|
- | 1057 | * @end: the maximum id (exclusive, < 0x8000000 or 0) |
|
- | 1058 | * @gfp_mask: memory allocation flags |
|
- | 1059 | * |
|
- | 1060 | * Allocates an id in the range start <= id < end, or returns -ENOSPC. |
|
- | 1061 | * On memory allocation failure, returns -ENOMEM. |
|
- | 1062 | * |
|
- | 1063 | * Use ida_simple_remove() to get rid of an id. |
|
- | 1064 | */ |
|
- | 1065 | int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, |
|
- | 1066 | gfp_t gfp_mask) |
|
- | 1067 | { |
|
- | 1068 | int ret, id; |
|
- | 1069 | unsigned int max; |
|
- | 1070 | unsigned long flags; |
|
- | 1071 | ||
- | 1072 | BUG_ON((int)start < 0); |
|
- | 1073 | BUG_ON((int)end < 0); |
|
- | 1074 | ||
- | 1075 | if (end == 0) |
|
- | 1076 | max = 0x80000000; |
|
- | 1077 | else { |
|
- | 1078 | BUG_ON(end < start); |
|
- | 1079 | max = end - 1; |
|
- | 1080 | } |
|
- | 1081 | ||
- | 1082 | again: |
|
- | 1083 | if (!ida_pre_get(ida, gfp_mask)) |
|
- | 1084 | return -ENOMEM; |
|
- | 1085 | ||
- | 1086 | spin_lock_irqsave(&simple_ida_lock, flags); |
|
- | 1087 | ret = ida_get_new_above(ida, start, &id); |
|
- | 1088 | if (!ret) { |
|
- | 1089 | if (id > max) { |
|
- | 1090 | ida_remove(ida, id); |
|
- | 1091 | ret = -ENOSPC; |
|
- | 1092 | } else { |
|
- | 1093 | ret = id; |
|
- | 1094 | } |
|
- | 1095 | } |
|
- | 1096 | spin_unlock_irqrestore(&simple_ida_lock, flags); |
|
- | 1097 | ||
- | 1098 | if (unlikely(ret == -EAGAIN)) |
|
- | 1099 | goto again; |
|
- | 1100 | ||
- | 1101 | return ret; |
|
- | 1102 | } |
|
- | 1103 | EXPORT_SYMBOL(ida_simple_get); |
|
- | 1104 | ||
- | 1105 | /** |
|
- | 1106 | * ida_simple_remove - remove an allocated id. |
|
- | 1107 | * @ida: the (initialized) ida. |
|
- | 1108 | * @id: the id returned by ida_simple_get. |
|
- | 1109 | */ |
|
- | 1110 | void ida_simple_remove(struct ida *ida, unsigned int id) |
|
- | 1111 | { |
|
- | 1112 | unsigned long flags; |
|
- | 1113 | ||
- | 1114 | BUG_ON((int)id < 0); |
|
- | 1115 | spin_lock_irqsave(&simple_ida_lock, flags); |
|
- | 1116 | ida_remove(ida, id); |
|
- | 1117 | spin_unlock_irqrestore(&simple_ida_lock, flags); |
|
- | 1118 | } |
|
- | 1119 | EXPORT_SYMBOL(ida_simple_remove); |
|
- | 1120 | ||
1025 | /** |
1121 | /** |
1026 | * ida_init - initialize ida handle |
1122 | * ida_init - initialize ida handle |
1027 | * @ida: ida handle |
1123 | * @ida: ida handle |
1028 | * |
1124 | * |
1029 | * This function is use to set up the handle (@ida) that you will pass |
1125 | * This function is use to set up the handle (@ida) that you will pass |