diff options
Diffstat (limited to 'include/linux/genalloc.h')
| -rw-r--r-- | include/linux/genalloc.h | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 5bbebda78b02..5e98eeb2af3b 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h | |||
| @@ -1,8 +1,26 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Basic general purpose allocator for managing special purpose memory | 2 | * Basic general purpose allocator for managing special purpose |
| 3 | * not managed by the regular kmalloc/kfree interface. | 3 | * memory, for example, memory that is not managed by the regular |
| 4 | * Uses for this includes on-device special memory, uncached memory | 4 | * kmalloc/kfree interface. Uses for this includes on-device special |
| 5 | * etc. | 5 | * memory, uncached memory etc. |
| 6 | * | ||
| 7 | * It is safe to use the allocator in NMI handlers and other special | ||
| 8 | * unblockable contexts that could otherwise deadlock on locks. This | ||
| 9 | * is implemented by using atomic operations and retries on any | ||
| 10 | * conflicts. The disadvantage is that there may be livelocks in | ||
| 11 | * extreme cases. For better scalability, one allocator can be used | ||
| 12 | * for each CPU. | ||
| 13 | * | ||
| 14 | * The lockless operation only works if there is enough memory | ||
| 15 | * available. If new memory is added to the pool a lock has to be | ||
| 16 | * still taken. So any user relying on locklessness has to ensure | ||
| 17 | * that sufficient memory is preallocated. | ||
| 18 | * | ||
| 19 | * The basic atomic operation of this allocator is cmpxchg on long. | ||
| 20 | * On architectures that don't have NMI-safe cmpxchg implementation, | ||
| 21 | * the allocator can NOT be used in NMI handler. So code uses the | ||
| 22 | * allocator in NMI handler should depend on | ||
| 23 | * CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG. | ||
| 6 | * | 24 | * |
| 7 | * This source code is licensed under the GNU General Public License, | 25 | * This source code is licensed under the GNU General Public License, |
| 8 | * Version 2. See the file COPYING for more details. | 26 | * Version 2. See the file COPYING for more details. |
| @@ -15,7 +33,7 @@ | |||
| 15 | * General purpose special memory pool descriptor. | 33 | * General purpose special memory pool descriptor. |
| 16 | */ | 34 | */ |
| 17 | struct gen_pool { | 35 | struct gen_pool { |
| 18 | rwlock_t lock; | 36 | spinlock_t lock; |
| 19 | struct list_head chunks; /* list of chunks in this pool */ | 37 | struct list_head chunks; /* list of chunks in this pool */ |
| 20 | int min_alloc_order; /* minimum allocation order */ | 38 | int min_alloc_order; /* minimum allocation order */ |
| 21 | }; | 39 | }; |
| @@ -24,8 +42,8 @@ struct gen_pool { | |||
| 24 | * General purpose special memory pool chunk descriptor. | 42 | * General purpose special memory pool chunk descriptor. |
| 25 | */ | 43 | */ |
| 26 | struct gen_pool_chunk { | 44 | struct gen_pool_chunk { |
| 27 | spinlock_t lock; | ||
| 28 | struct list_head next_chunk; /* next chunk in pool */ | 45 | struct list_head next_chunk; /* next chunk in pool */ |
| 46 | atomic_t avail; | ||
| 29 | phys_addr_t phys_addr; /* physical starting address of memory chunk */ | 47 | phys_addr_t phys_addr; /* physical starting address of memory chunk */ |
| 30 | unsigned long start_addr; /* starting address of memory chunk */ | 48 | unsigned long start_addr; /* starting address of memory chunk */ |
| 31 | unsigned long end_addr; /* ending address of memory chunk */ | 49 | unsigned long end_addr; /* ending address of memory chunk */ |
| @@ -56,4 +74,8 @@ static inline int gen_pool_add(struct gen_pool *pool, unsigned long addr, | |||
| 56 | extern void gen_pool_destroy(struct gen_pool *); | 74 | extern void gen_pool_destroy(struct gen_pool *); |
| 57 | extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); | 75 | extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); |
| 58 | extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); | 76 | extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); |
| 77 | extern void gen_pool_for_each_chunk(struct gen_pool *, | ||
| 78 | void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); | ||
| 79 | extern size_t gen_pool_avail(struct gen_pool *); | ||
| 80 | extern size_t gen_pool_size(struct gen_pool *); | ||
| 59 | #endif /* __GENALLOC_H__ */ | 81 | #endif /* __GENALLOC_H__ */ |
