diff options
| -rw-r--r-- | mm/slab.c | 48 |
1 files changed, 27 insertions, 21 deletions
| @@ -565,9 +565,31 @@ static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep) | |||
| 565 | return cachep->array[smp_processor_id()]; | 565 | return cachep->array[smp_processor_id()]; |
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | static size_t slab_mgmt_size(size_t nr_objs, size_t align) | 568 | static int calculate_nr_objs(size_t slab_size, size_t buffer_size, |
| 569 | size_t idx_size, size_t align) | ||
| 569 | { | 570 | { |
| 570 | return ALIGN(nr_objs * sizeof(unsigned int), align); | 571 | int nr_objs; |
| 572 | size_t freelist_size; | ||
| 573 | |||
| 574 | /* | ||
| 575 | * Ignore padding for the initial guess. The padding | ||
| 576 | * is at most @align-1 bytes, and @buffer_size is at | ||
| 577 | * least @align. In the worst case, this result will | ||
| 578 | * be one greater than the number of objects that fit | ||
| 579 | * into the memory allocation when taking the padding | ||
| 580 | * into account. | ||
| 581 | */ | ||
| 582 | nr_objs = slab_size / (buffer_size + idx_size); | ||
| 583 | |||
| 584 | /* | ||
| 585 | * This calculated number will be either the right | ||
| 586 | * amount, or one greater than what we want. | ||
| 587 | */ | ||
| 588 | freelist_size = slab_size - nr_objs * buffer_size; | ||
| 589 | if (freelist_size < ALIGN(nr_objs * idx_size, align)) | ||
| 590 | nr_objs--; | ||
| 591 | |||
| 592 | return nr_objs; | ||
| 571 | } | 593 | } |
| 572 | 594 | ||
| 573 | /* | 595 | /* |
| @@ -600,25 +622,9 @@ static void cache_estimate(unsigned long gfporder, size_t buffer_size, | |||
| 600 | nr_objs = slab_size / buffer_size; | 622 | nr_objs = slab_size / buffer_size; |
| 601 | 623 | ||
| 602 | } else { | 624 | } else { |
| 603 | /* | 625 | nr_objs = calculate_nr_objs(slab_size, buffer_size, |
| 604 | * Ignore padding for the initial guess. The padding | 626 | sizeof(unsigned int), align); |
| 605 | * is at most @align-1 bytes, and @buffer_size is at | 627 | mgmt_size = ALIGN(nr_objs * sizeof(unsigned int), align); |
| 606 | * least @align. In the worst case, this result will | ||
| 607 | * be one greater than the number of objects that fit | ||
| 608 | * into the memory allocation when taking the padding | ||
| 609 | * into account. | ||
| 610 | */ | ||
| 611 | nr_objs = (slab_size) / (buffer_size + sizeof(unsigned int)); | ||
| 612 | |||
| 613 | /* | ||
| 614 | * This calculated number will be either the right | ||
| 615 | * amount, or one greater than what we want. | ||
| 616 | */ | ||
| 617 | if (slab_mgmt_size(nr_objs, align) + nr_objs*buffer_size | ||
| 618 | > slab_size) | ||
| 619 | nr_objs--; | ||
| 620 | |||
| 621 | mgmt_size = slab_mgmt_size(nr_objs, align); | ||
| 622 | } | 628 | } |
| 623 | *num = nr_objs; | 629 | *num = nr_objs; |
| 624 | *left_over = slab_size - nr_objs*buffer_size - mgmt_size; | 630 | *left_over = slab_size - nr_objs*buffer_size - mgmt_size; |
