Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lib, Make gen_pool memory allocator lockless

This version of the gen_pool memory allocator supports lockless
operation.

This makes it safe to use in NMI handlers and other special
unblockable contexts that could otherwise deadlock on locks. This is
implemented by using atomic operations and retries on any conflicts.
The disadvantage is that there may be livelocks in extreme cases. For
better scalability, one gen_pool allocator can be used for each CPU.

The lockless operation only works if there is enough memory available.
If new memory is added to the pool a lock has to be still taken. So
any user relying on locklessness has to ensure that sufficient memory
is preallocated.

The basic atomic operation of this allocator is cmpxchg on long. On
architectures that don't have NMI-safe cmpxchg implementation, the
allocator can NOT be used in NMI handler. So code uses the allocator
in NMI handler should depend on CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG.

Signed-off-by: Huang Ying <ying.huang@intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by

Huang Ying and committed by
Len Brown
7f184275 f49f23ab

+272 -65
+1
include/linux/bitmap.h
··· 145 145 extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order); 146 146 extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits); 147 147 148 + #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG)) 148 149 #define BITMAP_LAST_WORD_MASK(nbits) \ 149 150 ( \ 150 151 ((nbits) % BITS_PER_LONG) ? \
+28 -6
include/linux/genalloc.h
··· 1 1 /* 2 - * Basic general purpose allocator for managing special purpose memory 3 - * not managed by the regular kmalloc/kfree interface. 4 - * Uses for this includes on-device special memory, uncached memory 5 - * etc. 2 + * Basic general purpose allocator for managing special purpose 3 + * memory, for example, memory that is not managed by the regular 4 + * kmalloc/kfree interface. Uses for this includes on-device special 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 25 * This source code is licensed under the GNU General Public License, 8 26 * Version 2. See the file COPYING for more details. ··· 33 15 * General purpose special memory pool descriptor. 34 16 */ 35 17 struct gen_pool { 36 - rwlock_t lock; 18 + spinlock_t lock; 37 19 struct list_head chunks; /* list of chunks in this pool */ 38 20 int min_alloc_order; /* minimum allocation order */ 39 21 }; ··· 42 24 * General purpose special memory pool chunk descriptor. 43 25 */ 44 26 struct gen_pool_chunk { 45 - spinlock_t lock; 46 27 struct list_head next_chunk; /* next chunk in pool */ 28 + atomic_t avail; 47 29 phys_addr_t phys_addr; /* physical starting address of memory chunk */ 48 30 unsigned long start_addr; /* starting address of memory chunk */ 49 31 unsigned long end_addr; /* ending address of memory chunk */ ··· 74 56 extern void gen_pool_destroy(struct gen_pool *); 75 57 extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); 76 58 extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); 59 + extern void gen_pool_for_each_chunk(struct gen_pool *, 60 + void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); 61 + extern size_t gen_pool_avail(struct gen_pool *); 62 + extern size_t gen_pool_size(struct gen_pool *); 77 63 #endif /* __GENALLOC_H__ */
-2
lib/bitmap.c
··· 271 271 } 272 272 EXPORT_SYMBOL(__bitmap_weight); 273 273 274 - #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG)) 275 - 276 274 void bitmap_set(unsigned long *map, int start, int nr) 277 275 { 278 276 unsigned long *p = map + BIT_WORD(start);
+243 -57
lib/genalloc.c
··· 1 1 /* 2 - * Basic general purpose allocator for managing special purpose memory 3 - * not managed by the regular kmalloc/kfree interface. 4 - * Uses for this includes on-device special memory, uncached memory 5 - * etc. 2 + * Basic general purpose allocator for managing special purpose 3 + * memory, for example, memory that is not managed by the regular 4 + * kmalloc/kfree interface. Uses for this includes on-device special 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 25 * Copyright 2005 (C) Jes Sorensen <jes@trained-monkey.org> 8 26 * ··· 31 13 #include <linux/slab.h> 32 14 #include <linux/module.h> 33 15 #include <linux/bitmap.h> 16 + #include <linux/rculist.h> 17 + #include <linux/interrupt.h> 34 18 #include <linux/genalloc.h> 35 19 20 + static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) 21 + { 22 + unsigned long val, nval; 23 + 24 + nval = *addr; 25 + do { 26 + val = nval; 27 + if (val & mask_to_set) 28 + return -EBUSY; 29 + cpu_relax(); 30 + } while ((nval = cmpxchg(addr, val, val | mask_to_set)) != val); 31 + 32 + return 0; 33 + } 34 + 35 + static int clear_bits_ll(unsigned long *addr, unsigned long mask_to_clear) 36 + { 37 + unsigned long val, nval; 38 + 39 + nval = *addr; 40 + do { 41 + val = nval; 42 + if ((val & mask_to_clear) != mask_to_clear) 43 + return -EBUSY; 44 + cpu_relax(); 45 + } while ((nval = cmpxchg(addr, val, val & ~mask_to_clear)) != val); 46 + 47 + return 0; 48 + } 49 + 50 + /* 51 + * bitmap_set_ll - set the specified number of bits at the specified position 52 + * @map: pointer to a bitmap 53 + * @start: a bit position in @map 54 + * @nr: number of bits to set 55 + * 56 + * Set @nr bits start from @start in @map lock-lessly. Several users 57 + * can set/clear the same bitmap simultaneously without lock. If two 58 + * users set the same bit, one user will return remain bits, otherwise 59 + * return 0. 60 + */ 61 + static int bitmap_set_ll(unsigned long *map, int start, int nr) 62 + { 63 + unsigned long *p = map + BIT_WORD(start); 64 + const int size = start + nr; 65 + int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); 66 + unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); 67 + 68 + while (nr - bits_to_set >= 0) { 69 + if (set_bits_ll(p, mask_to_set)) 70 + return nr; 71 + nr -= bits_to_set; 72 + bits_to_set = BITS_PER_LONG; 73 + mask_to_set = ~0UL; 74 + p++; 75 + } 76 + if (nr) { 77 + mask_to_set &= BITMAP_LAST_WORD_MASK(size); 78 + if (set_bits_ll(p, mask_to_set)) 79 + return nr; 80 + } 81 + 82 + return 0; 83 + } 84 + 85 + /* 86 + * bitmap_clear_ll - clear the specified number of bits at the specified position 87 + * @map: pointer to a bitmap 88 + * @start: a bit position in @map 89 + * @nr: number of bits to set 90 + * 91 + * Clear @nr bits start from @start in @map lock-lessly. Several users 92 + * can set/clear the same bitmap simultaneously without lock. If two 93 + * users clear the same bit, one user will return remain bits, 94 + * otherwise return 0. 95 + */ 96 + static int bitmap_clear_ll(unsigned long *map, int start, int nr) 97 + { 98 + unsigned long *p = map + BIT_WORD(start); 99 + const int size = start + nr; 100 + int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); 101 + unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); 102 + 103 + while (nr - bits_to_clear >= 0) { 104 + if (clear_bits_ll(p, mask_to_clear)) 105 + return nr; 106 + nr -= bits_to_clear; 107 + bits_to_clear = BITS_PER_LONG; 108 + mask_to_clear = ~0UL; 109 + p++; 110 + } 111 + if (nr) { 112 + mask_to_clear &= BITMAP_LAST_WORD_MASK(size); 113 + if (clear_bits_ll(p, mask_to_clear)) 114 + return nr; 115 + } 116 + 117 + return 0; 118 + } 36 119 37 120 /** 38 121 * gen_pool_create - create a new special memory pool ··· 149 30 150 31 pool = kmalloc_node(sizeof(struct gen_pool), GFP_KERNEL, nid); 151 32 if (pool != NULL) { 152 - rwlock_init(&pool->lock); 33 + spin_lock_init(&pool->lock); 153 34 INIT_LIST_HEAD(&pool->chunks); 154 35 pool->min_alloc_order = min_alloc_order; 155 36 } ··· 182 63 if (unlikely(chunk == NULL)) 183 64 return -ENOMEM; 184 65 185 - spin_lock_init(&chunk->lock); 186 66 chunk->phys_addr = phys; 187 67 chunk->start_addr = virt; 188 68 chunk->end_addr = virt + size; 69 + atomic_set(&chunk->avail, size); 189 70 190 - write_lock(&pool->lock); 191 - list_add(&chunk->next_chunk, &pool->chunks); 192 - write_unlock(&pool->lock); 71 + spin_lock(&pool->lock); 72 + list_add_rcu(&chunk->next_chunk, &pool->chunks); 73 + spin_unlock(&pool->lock); 193 74 194 75 return 0; 195 76 } ··· 204 85 */ 205 86 phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr) 206 87 { 207 - struct list_head *_chunk; 208 88 struct gen_pool_chunk *chunk; 89 + phys_addr_t paddr = -1; 209 90 210 - read_lock(&pool->lock); 211 - list_for_each(_chunk, &pool->chunks) { 212 - chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); 213 - 214 - if (addr >= chunk->start_addr && addr < chunk->end_addr) 215 - return chunk->phys_addr + addr - chunk->start_addr; 91 + rcu_read_lock(); 92 + list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { 93 + if (addr >= chunk->start_addr && addr < chunk->end_addr) { 94 + paddr = chunk->phys_addr + (addr - chunk->start_addr); 95 + break; 96 + } 216 97 } 217 - read_unlock(&pool->lock); 98 + rcu_read_unlock(); 218 99 219 - return -1; 100 + return paddr; 220 101 } 221 102 EXPORT_SYMBOL(gen_pool_virt_to_phys); 222 103 ··· 233 114 struct gen_pool_chunk *chunk; 234 115 int order = pool->min_alloc_order; 235 116 int bit, end_bit; 236 - 237 117 238 118 list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { 239 119 chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); ··· 255 137 * @size: number of bytes to allocate from the pool 256 138 * 257 139 * Allocate the requested number of bytes from the specified pool. 258 - * Uses a first-fit algorithm. 140 + * Uses a first-fit algorithm. Can not be used in NMI handler on 141 + * architectures without NMI-safe cmpxchg implementation. 259 142 */ 260 143 unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) 261 144 { 262 - struct list_head *_chunk; 263 145 struct gen_pool_chunk *chunk; 264 - unsigned long addr, flags; 146 + unsigned long addr = 0; 265 147 int order = pool->min_alloc_order; 266 - int nbits, start_bit, end_bit; 148 + int nbits, start_bit = 0, end_bit, remain; 149 + 150 + #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG 151 + BUG_ON(in_nmi()); 152 + #endif 267 153 268 154 if (size == 0) 269 155 return 0; 270 156 271 157 nbits = (size + (1UL << order) - 1) >> order; 272 - 273 - read_lock(&pool->lock); 274 - list_for_each(_chunk, &pool->chunks) { 275 - chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); 158 + rcu_read_lock(); 159 + list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { 160 + if (size > atomic_read(&chunk->avail)) 161 + continue; 276 162 277 163 end_bit = (chunk->end_addr - chunk->start_addr) >> order; 278 - 279 - spin_lock_irqsave(&chunk->lock, flags); 280 - start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, 0, 281 - nbits, 0); 282 - if (start_bit >= end_bit) { 283 - spin_unlock_irqrestore(&chunk->lock, flags); 164 + retry: 165 + start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, 166 + start_bit, nbits, 0); 167 + if (start_bit >= end_bit) 284 168 continue; 169 + remain = bitmap_set_ll(chunk->bits, start_bit, nbits); 170 + if (remain) { 171 + remain = bitmap_clear_ll(chunk->bits, start_bit, 172 + nbits - remain); 173 + BUG_ON(remain); 174 + goto retry; 285 175 } 286 176 287 177 addr = chunk->start_addr + ((unsigned long)start_bit << order); 288 - 289 - bitmap_set(chunk->bits, start_bit, nbits); 290 - spin_unlock_irqrestore(&chunk->lock, flags); 291 - read_unlock(&pool->lock); 292 - return addr; 178 + size = nbits << order; 179 + atomic_sub(size, &chunk->avail); 180 + break; 293 181 } 294 - read_unlock(&pool->lock); 295 - return 0; 182 + rcu_read_unlock(); 183 + return addr; 296 184 } 297 185 EXPORT_SYMBOL(gen_pool_alloc); 298 186 ··· 308 184 * @addr: starting address of memory to free back to pool 309 185 * @size: size in bytes of memory to free 310 186 * 311 - * Free previously allocated special memory back to the specified pool. 187 + * Free previously allocated special memory back to the specified 188 + * pool. Can not be used in NMI handler on architectures without 189 + * NMI-safe cmpxchg implementation. 312 190 */ 313 191 void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size) 314 192 { 315 - struct list_head *_chunk; 316 193 struct gen_pool_chunk *chunk; 317 - unsigned long flags; 318 194 int order = pool->min_alloc_order; 319 - int bit, nbits; 195 + int start_bit, nbits, remain; 196 + 197 + #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG 198 + BUG_ON(in_nmi()); 199 + #endif 320 200 321 201 nbits = (size + (1UL << order) - 1) >> order; 322 - 323 - read_lock(&pool->lock); 324 - list_for_each(_chunk, &pool->chunks) { 325 - chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); 326 - 202 + rcu_read_lock(); 203 + list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { 327 204 if (addr >= chunk->start_addr && addr < chunk->end_addr) { 328 205 BUG_ON(addr + size > chunk->end_addr); 329 - spin_lock_irqsave(&chunk->lock, flags); 330 - bit = (addr - chunk->start_addr) >> order; 331 - while (nbits--) 332 - __clear_bit(bit++, chunk->bits); 333 - spin_unlock_irqrestore(&chunk->lock, flags); 334 - break; 206 + start_bit = (addr - chunk->start_addr) >> order; 207 + remain = bitmap_clear_ll(chunk->bits, start_bit, nbits); 208 + BUG_ON(remain); 209 + size = nbits << order; 210 + atomic_add(size, &chunk->avail); 211 + rcu_read_unlock(); 212 + return; 335 213 } 336 214 } 337 - BUG_ON(nbits > 0); 338 - read_unlock(&pool->lock); 215 + rcu_read_unlock(); 216 + BUG(); 339 217 } 340 218 EXPORT_SYMBOL(gen_pool_free); 219 + 220 + /** 221 + * gen_pool_for_each_chunk - call func for every chunk of generic memory pool 222 + * @pool: the generic memory pool 223 + * @func: func to call 224 + * @data: additional data used by @func 225 + * 226 + * Call @func for every chunk of generic memory pool. The @func is 227 + * called with rcu_read_lock held. 228 + */ 229 + void gen_pool_for_each_chunk(struct gen_pool *pool, 230 + void (*func)(struct gen_pool *pool, struct gen_pool_chunk *chunk, void *data), 231 + void *data) 232 + { 233 + struct gen_pool_chunk *chunk; 234 + 235 + rcu_read_lock(); 236 + list_for_each_entry_rcu(chunk, &(pool)->chunks, next_chunk) 237 + func(pool, chunk, data); 238 + rcu_read_unlock(); 239 + } 240 + EXPORT_SYMBOL(gen_pool_for_each_chunk); 241 + 242 + /** 243 + * gen_pool_avail - get available free space of the pool 244 + * @pool: pool to get available free space 245 + * 246 + * Return available free space of the specified pool. 247 + */ 248 + size_t gen_pool_avail(struct gen_pool *pool) 249 + { 250 + struct gen_pool_chunk *chunk; 251 + size_t avail = 0; 252 + 253 + rcu_read_lock(); 254 + list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) 255 + avail += atomic_read(&chunk->avail); 256 + rcu_read_unlock(); 257 + return avail; 258 + } 259 + EXPORT_SYMBOL_GPL(gen_pool_avail); 260 + 261 + /** 262 + * gen_pool_size - get size in bytes of memory managed by the pool 263 + * @pool: pool to get size 264 + * 265 + * Return size in bytes of memory managed by the pool. 266 + */ 267 + size_t gen_pool_size(struct gen_pool *pool) 268 + { 269 + struct gen_pool_chunk *chunk; 270 + size_t size = 0; 271 + 272 + rcu_read_lock(); 273 + list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) 274 + size += chunk->end_addr - chunk->start_addr; 275 + rcu_read_unlock(); 276 + return size; 277 + } 278 + EXPORT_SYMBOL_GPL(gen_pool_size);