| 3693 | } |
| 3694 | |
| 3695 | static uma_slab_t |
| 3696 | keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int rdomain, const int flags) |
| 3697 | { |
| 3698 | struct vm_domainset_iter di; |
| 3699 | uma_slab_t slab; |
| 3700 | int aflags, domain; |
| 3701 | bool rr; |
| 3702 | |
| 3703 | restart: |
| 3704 | /* |
| 3705 | * Use the keg's policy if upper layers haven't already specified a |
| 3706 | * domain (as happens with first-touch zones). |
| 3707 | * |
| 3708 | * To avoid races we run the iterator with the keg lock held, but that |
| 3709 | * means that we cannot allow the vm_domainset layer to sleep. Thus, |
| 3710 | * clear M_WAITOK and handle low memory conditions locally. |
| 3711 | */ |
| 3712 | rr = rdomain == UMA_ANYDOMAIN; |
| 3713 | if (rr) { |
| 3714 | aflags = (flags & ~M_WAITOK) | M_NOWAIT; |
| 3715 | vm_domainset_iter_policy_ref_init(&di, &keg->uk_dr, &domain, |
| 3716 | &aflags); |
| 3717 | } else { |
| 3718 | aflags = flags; |
| 3719 | domain = rdomain; |
| 3720 | } |
| 3721 | |
| 3722 | for (;;) { |
| 3723 | slab = keg_fetch_free_slab(keg, domain, rr, flags); |
| 3724 | if (slab != NULL) |
| 3725 | return (slab); |
| 3726 | |
| 3727 | /* |
| 3728 | * M_NOVM means don't ask at all! |
| 3729 | */ |
| 3730 | if (flags & M_NOVM) |
| 3731 | break; |
| 3732 | |
| 3733 | slab = keg_alloc_slab(keg, zone, domain, flags, aflags); |
| 3734 | if (slab != NULL) |
| 3735 | return (slab); |
| 3736 | if (!rr && (flags & M_WAITOK) == 0) |
| 3737 | break; |
| 3738 | if (rr && vm_domainset_iter_policy(&di, &domain) != 0) { |
| 3739 | if ((flags & M_WAITOK) != 0) { |
| 3740 | vm_wait_doms(&keg->uk_dr.dr_policy->ds_mask, 0); |
| 3741 | goto restart; |
| 3742 | } |
| 3743 | break; |
| 3744 | } |
| 3745 | } |
| 3746 | |
| 3747 | /* |
| 3748 | * We might not have been able to get a slab but another cpu |
| 3749 | * could have while we were unlocked. Check again before we |
| 3750 | * fail. |
| 3751 | */ |
| 3752 | if ((slab = keg_fetch_free_slab(keg, domain, rr, flags)) != NULL) |
no test coverage detected