diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/idr.c | 379 | ||||
| -rw-r--r-- | lib/radix-tree.c | 71 |
2 files changed, 203 insertions, 247 deletions
| @@ -6,8 +6,6 @@ | |||
| 6 | #include <linux/spinlock.h> | 6 | #include <linux/spinlock.h> |
| 7 | #include <linux/xarray.h> | 7 | #include <linux/xarray.h> |
| 8 | 8 | ||
| 9 | DEFINE_PER_CPU(struct ida_bitmap *, ida_bitmap); | ||
| 10 | |||
| 11 | /** | 9 | /** |
| 12 | * idr_alloc_u32() - Allocate an ID. | 10 | * idr_alloc_u32() - Allocate an ID. |
| 13 | * @idr: IDR handle. | 11 | * @idr: IDR handle. |
| @@ -320,6 +318,9 @@ EXPORT_SYMBOL(idr_replace); | |||
| 320 | * free the individual IDs in it. You can use ida_is_empty() to find | 318 | * free the individual IDs in it. You can use ida_is_empty() to find |
| 321 | * out whether the IDA has any IDs currently allocated. | 319 | * out whether the IDA has any IDs currently allocated. |
| 322 | * | 320 | * |
| 321 | * The IDA handles its own locking. It is safe to call any of the IDA | ||
| 322 | * functions without synchronisation in your code. | ||
| 323 | * | ||
| 323 | * IDs are currently limited to the range [0-INT_MAX]. If this is an awkward | 324 | * IDs are currently limited to the range [0-INT_MAX]. If this is an awkward |
| 324 | * limitation, it should be quite straightforward to raise the maximum. | 325 | * limitation, it should be quite straightforward to raise the maximum. |
| 325 | */ | 326 | */ |
| @@ -327,151 +328,197 @@ EXPORT_SYMBOL(idr_replace); | |||
| 327 | /* | 328 | /* |
| 328 | * Developer's notes: | 329 | * Developer's notes: |
| 329 | * | 330 | * |
| 330 | * The IDA uses the functionality provided by the IDR & radix tree to store | 331 | * The IDA uses the functionality provided by the XArray to store bitmaps in |
| 331 | * bitmaps in each entry. The IDR_FREE tag means there is at least one bit | 332 | * each entry. The XA_FREE_MARK is only cleared when all bits in the bitmap |
| 332 | * free, unlike the IDR where it means at least one entry is free. | 333 | * have been set. |
| 333 | * | 334 | * |
| 334 | * I considered telling the radix tree that each slot is an order-10 node | 335 | * I considered telling the XArray that each slot is an order-10 node |
| 335 | * and storing the bit numbers in the radix tree, but the radix tree can't | 336 | * and indexing by bit number, but the XArray can't allow a single multi-index |
| 336 | * allow a single multiorder entry at index 0, which would significantly | 337 | * entry in the head, which would significantly increase memory consumption |
| 337 | * increase memory consumption for the IDA. So instead we divide the index | 338 | * for the IDA. So instead we divide the index by the number of bits in the |
| 338 | * by the number of bits in the leaf bitmap before doing a radix tree lookup. | 339 | * leaf bitmap before doing a radix tree lookup. |
| 339 | * | 340 | * |
| 340 | * As an optimisation, if there are only a few low bits set in any given | 341 | * As an optimisation, if there are only a few low bits set in any given |
| 341 | * leaf, instead of allocating a 128-byte bitmap, we store the bits | 342 | * leaf, instead of allocating a 128-byte bitmap, we store the bits |
| 342 | * directly in the entry. | 343 | * as a value entry. Value entries never have the XA_FREE_MARK cleared |
| 343 | * | 344 | * because we can always convert them into a bitmap entry. |
| 344 | * We allow the radix tree 'exceptional' count to get out of date. Nothing | 345 | * |
| 345 | * in the IDA nor the radix tree code checks it. If it becomes important | 346 | * It would be possible to optimise further; once we've run out of a |
| 346 | * to maintain an accurate exceptional count, switch the rcu_assign_pointer() | 347 | * single 128-byte bitmap, we currently switch to a 576-byte node, put |
| 347 | * calls to radix_tree_iter_replace() which will correct the exceptional | 348 | * the 128-byte bitmap in the first entry and then start allocating extra |
| 348 | * count. | 349 | * 128-byte entries. We could instead use the 512 bytes of the node's |
| 349 | * | 350 | * data as a bitmap before moving to that scheme. I do not believe this |
| 350 | * The IDA always requires a lock to alloc/free. If we add a 'test_bit' | 351 | * is a worthwhile optimisation; Rasmus Villemoes surveyed the current |
| 352 | * users of the IDA and almost none of them use more than 1024 entries. | ||
| 353 | * Those that do use more than the 8192 IDs that the 512 bytes would | ||
| 354 | * provide. | ||
| 355 | * | ||
| 356 | * The IDA always uses a lock to alloc/free. If we add a 'test_bit' | ||
| 351 | * equivalent, it will still need locking. Going to RCU lookup would require | 357 | * equivalent, it will still need locking. Going to RCU lookup would require |
| 352 | * using RCU to free bitmaps, and that's not trivial without embedding an | 358 | * using RCU to free bitmaps, and that's not trivial without embedding an |
| 353 | * RCU head in the bitmap, which adds a 2-pointer overhead to each 128-byte | 359 | * RCU head in the bitmap, which adds a 2-pointer overhead to each 128-byte |
| 354 | * bitmap, which is excessive. | 360 | * bitmap, which is excessive. |
| 355 | */ | 361 | */ |
| 356 | 362 | ||
| 357 | #define IDA_MAX (0x80000000U / IDA_BITMAP_BITS - 1) | 363 | /** |
| 358 | 364 | * ida_alloc_range() - Allocate an unused ID. | |
| 359 | static int ida_get_new_above(struct ida *ida, int start) | 365 | * @ida: IDA handle. |
| 366 | * @min: Lowest ID to allocate. | ||
| 367 | * @max: Highest ID to allocate. | ||
| 368 | * @gfp: Memory allocation flags. | ||
| 369 | * | ||
| 370 | * Allocate an ID between @min and @max, inclusive. The allocated ID will | ||
| 371 | * not exceed %INT_MAX, even if @max is larger. | ||
| 372 | * | ||
| 373 | * Context: Any context. | ||
| 374 | * Return: The allocated ID, or %-ENOMEM if memory could not be allocated, | ||
| 375 | * or %-ENOSPC if there are no free IDs. | ||
| 376 | */ | ||
| 377 | int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max, | ||
| 378 | gfp_t gfp) | ||
| 360 | { | 379 | { |
| 361 | struct radix_tree_root *root = &ida->ida_rt; | 380 | XA_STATE(xas, &ida->xa, min / IDA_BITMAP_BITS); |
| 362 | void __rcu **slot; | 381 | unsigned bit = min % IDA_BITMAP_BITS; |
| 363 | struct radix_tree_iter iter; | 382 | unsigned long flags; |
| 364 | struct ida_bitmap *bitmap; | 383 | struct ida_bitmap *bitmap, *alloc = NULL; |
| 365 | unsigned long index; | 384 | |
| 366 | unsigned bit; | 385 | if ((int)min < 0) |
| 367 | int new; | 386 | return -ENOSPC; |
| 368 | 387 | ||
| 369 | index = start / IDA_BITMAP_BITS; | 388 | if ((int)max < 0) |
| 370 | bit = start % IDA_BITMAP_BITS; | 389 | max = INT_MAX; |
| 371 | 390 | ||
| 372 | slot = radix_tree_iter_init(&iter, index); | 391 | retry: |
| 373 | for (;;) { | 392 | xas_lock_irqsave(&xas, flags); |
| 374 | if (slot) | 393 | next: |
| 375 | slot = radix_tree_next_slot(slot, &iter, | 394 | bitmap = xas_find_marked(&xas, max / IDA_BITMAP_BITS, XA_FREE_MARK); |
| 376 | RADIX_TREE_ITER_TAGGED); | 395 | if (xas.xa_index > min / IDA_BITMAP_BITS) |
| 377 | if (!slot) { | 396 | bit = 0; |
| 378 | slot = idr_get_free(root, &iter, GFP_NOWAIT, IDA_MAX); | 397 | if (xas.xa_index * IDA_BITMAP_BITS + bit > max) |
| 379 | if (IS_ERR(slot)) { | 398 | goto nospc; |
| 380 | if (slot == ERR_PTR(-ENOMEM)) | 399 | |
| 381 | return -EAGAIN; | 400 | if (xa_is_value(bitmap)) { |
| 382 | return PTR_ERR(slot); | 401 | unsigned long tmp = xa_to_value(bitmap); |
| 402 | |||
| 403 | if (bit < BITS_PER_XA_VALUE) { | ||
| 404 | bit = find_next_zero_bit(&tmp, BITS_PER_XA_VALUE, bit); | ||
| 405 | if (xas.xa_index * IDA_BITMAP_BITS + bit > max) | ||
| 406 | goto nospc; | ||
| 407 | if (bit < BITS_PER_XA_VALUE) { | ||
| 408 | tmp |= 1UL << bit; | ||
| 409 | xas_store(&xas, xa_mk_value(tmp)); | ||
| 410 | goto out; | ||
| 383 | } | 411 | } |
| 384 | } | 412 | } |
| 385 | if (iter.index > index) | 413 | bitmap = alloc; |
| 386 | bit = 0; | 414 | if (!bitmap) |
| 387 | new = iter.index * IDA_BITMAP_BITS; | 415 | bitmap = kzalloc(sizeof(*bitmap), GFP_NOWAIT); |
| 388 | bitmap = rcu_dereference_raw(*slot); | 416 | if (!bitmap) |
| 389 | if (xa_is_value(bitmap)) { | 417 | goto alloc; |
| 390 | unsigned long tmp = xa_to_value(bitmap); | 418 | bitmap->bitmap[0] = tmp; |
| 391 | int vbit = find_next_zero_bit(&tmp, BITS_PER_XA_VALUE, | 419 | xas_store(&xas, bitmap); |
| 392 | bit); | 420 | if (xas_error(&xas)) { |
| 393 | if (vbit < BITS_PER_XA_VALUE) { | 421 | bitmap->bitmap[0] = 0; |
| 394 | tmp |= 1UL << vbit; | 422 | goto out; |
| 395 | rcu_assign_pointer(*slot, xa_mk_value(tmp)); | ||
| 396 | return new + vbit; | ||
| 397 | } | ||
| 398 | bitmap = this_cpu_xchg(ida_bitmap, NULL); | ||
| 399 | if (!bitmap) | ||
| 400 | return -EAGAIN; | ||
| 401 | bitmap->bitmap[0] = tmp; | ||
| 402 | rcu_assign_pointer(*slot, bitmap); | ||
| 403 | } | 423 | } |
| 424 | } | ||
| 404 | 425 | ||
| 405 | if (bitmap) { | 426 | if (bitmap) { |
| 406 | bit = find_next_zero_bit(bitmap->bitmap, | 427 | bit = find_next_zero_bit(bitmap->bitmap, IDA_BITMAP_BITS, bit); |
| 407 | IDA_BITMAP_BITS, bit); | 428 | if (xas.xa_index * IDA_BITMAP_BITS + bit > max) |
| 408 | new += bit; | 429 | goto nospc; |
| 409 | if (new < 0) | 430 | if (bit == IDA_BITMAP_BITS) |
| 410 | return -ENOSPC; | 431 | goto next; |
| 411 | if (bit == IDA_BITMAP_BITS) | ||
| 412 | continue; | ||
| 413 | 432 | ||
| 414 | __set_bit(bit, bitmap->bitmap); | 433 | __set_bit(bit, bitmap->bitmap); |
| 415 | if (bitmap_full(bitmap->bitmap, IDA_BITMAP_BITS)) | 434 | if (bitmap_full(bitmap->bitmap, IDA_BITMAP_BITS)) |
| 416 | radix_tree_iter_tag_clear(root, &iter, | 435 | xas_clear_mark(&xas, XA_FREE_MARK); |
| 417 | IDR_FREE); | 436 | } else { |
| 437 | if (bit < BITS_PER_XA_VALUE) { | ||
| 438 | bitmap = xa_mk_value(1UL << bit); | ||
| 418 | } else { | 439 | } else { |
| 419 | new += bit; | 440 | bitmap = alloc; |
| 420 | if (new < 0) | 441 | if (!bitmap) |
| 421 | return -ENOSPC; | 442 | bitmap = kzalloc(sizeof(*bitmap), GFP_NOWAIT); |
| 422 | if (bit < BITS_PER_XA_VALUE) { | 443 | if (!bitmap) |
| 423 | bitmap = xa_mk_value(1UL << bit); | 444 | goto alloc; |
| 424 | } else { | 445 | __set_bit(bit, bitmap->bitmap); |
| 425 | bitmap = this_cpu_xchg(ida_bitmap, NULL); | ||
| 426 | if (!bitmap) | ||
| 427 | return -EAGAIN; | ||
| 428 | __set_bit(bit, bitmap->bitmap); | ||
| 429 | } | ||
| 430 | radix_tree_iter_replace(root, &iter, slot, bitmap); | ||
| 431 | } | 446 | } |
| 432 | < | ||
