| 3785 | } |
| 3786 | |
| 3787 | static int |
| 3788 | zone_import(void *arg, void **bucket, int max, int domain, int flags) |
| 3789 | { |
| 3790 | uma_domain_t dom; |
| 3791 | uma_zone_t zone; |
| 3792 | uma_slab_t slab; |
| 3793 | uma_keg_t keg; |
| 3794 | #ifdef NUMA |
| 3795 | int stripe; |
| 3796 | #endif |
| 3797 | int i; |
| 3798 | |
| 3799 | zone = arg; |
| 3800 | slab = NULL; |
| 3801 | keg = zone->uz_keg; |
| 3802 | /* Try to keep the buckets totally full */ |
| 3803 | for (i = 0; i < max; ) { |
| 3804 | if ((slab = keg_fetch_slab(keg, zone, domain, flags)) == NULL) |
| 3805 | break; |
| 3806 | #ifdef NUMA |
| 3807 | stripe = howmany(max, vm_ndomains); |
| 3808 | #endif |
| 3809 | dom = &keg->uk_domain[slab->us_domain]; |
| 3810 | do { |
| 3811 | bucket[i++] = slab_alloc_item(keg, slab); |
| 3812 | if (dom->ud_free_items <= keg->uk_reserve) { |
| 3813 | /* |
| 3814 | * Avoid depleting the reserve after a |
| 3815 | * successful item allocation, even if |
| 3816 | * M_USE_RESERVE is specified. |
| 3817 | */ |
| 3818 | KEG_UNLOCK(keg, slab->us_domain); |
| 3819 | goto out; |
| 3820 | } |
| 3821 | #ifdef NUMA |
| 3822 | /* |
| 3823 | * If the zone is striped we pick a new slab for every |
| 3824 | * N allocations. Eliminating this conditional will |
| 3825 | * instead pick a new domain for each bucket rather |
| 3826 | * than stripe within each bucket. The current option |
| 3827 | * produces more fragmentation and requires more cpu |
| 3828 | * time but yields better distribution. |
| 3829 | */ |
| 3830 | if ((zone->uz_flags & UMA_ZONE_ROUNDROBIN) != 0 && |
| 3831 | vm_ndomains > 1 && --stripe == 0) |
| 3832 | break; |
| 3833 | #endif |
| 3834 | } while (slab->us_freecount != 0 && i < max); |
| 3835 | KEG_UNLOCK(keg, slab->us_domain); |
| 3836 | |
| 3837 | /* Don't block if we allocated any successfully. */ |
| 3838 | flags &= ~M_WAITOK; |
| 3839 | flags |= M_NOWAIT; |
| 3840 | } |
| 3841 | out: |
| 3842 | return i; |
| 3843 | } |
| 3844 |
nothing calls this directly
no test coverage detected