vm_domainset.c (3af64f03119a159ac15eb75b92d346705b490385) vm_domainset.c (463406ac4a531b8f4c6102715c17da6183d10be3)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2017, Jeffrey Roberson <jeff@freebsd.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 52 unchanged lines hidden (view full) ---

61/*
62 * Determine which policy is to be used for this allocation.
63 */
64static void
65vm_domainset_iter_init(struct vm_domainset_iter *di, struct vm_object *obj,
66 vm_pindex_t pindex)
67{
68 struct domainset *domain;
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2017, Jeffrey Roberson <jeff@freebsd.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 52 unchanged lines hidden (view full) ---

61/*
62 * Determine which policy is to be used for this allocation.
63 */
64static void
65vm_domainset_iter_init(struct vm_domainset_iter *di, struct vm_object *obj,
66 vm_pindex_t pindex)
67{
68 struct domainset *domain;
69 struct thread *td;
69
70 /*
71 * object policy takes precedence over thread policy. The policies
72 * are immutable and unsynchronized. Updates can race but pointer
73 * loads are assumed to be atomic.
74 */
75 if (obj != NULL && (domain = obj->domain.dr_policy) != NULL) {
76 di->di_domain = domain;
77 di->di_iter = &obj->domain.dr_iterator;
78 } else {
70
71 /*
72 * object policy takes precedence over thread policy. The policies
73 * are immutable and unsynchronized. Updates can race but pointer
74 * loads are assumed to be atomic.
75 */
76 if (obj != NULL && (domain = obj->domain.dr_policy) != NULL) {
77 di->di_domain = domain;
78 di->di_iter = &obj->domain.dr_iterator;
79 } else {
79 di->di_domain = curthread->td_domain.dr_policy;
80 di->di_iter = &curthread->td_domain.dr_iterator;
80 td = curthread;
81 di->di_domain = td->td_domain.dr_policy;
82 di->di_iter = &td->td_domain.dr_iterator;
81 }
82 di->di_policy = di->di_domain->ds_policy;
83 if (di->di_policy == DOMAINSET_POLICY_INTERLEAVE) {
84#if VM_NRESERVLEVEL > 0
85 if (vm_object_reserv(obj)) {
86 /*
87 * Color the pindex so we end up on the correct
88 * reservation boundary.

--- 121 unchanged lines hidden (view full) ---

210 vm_pindex_t pindex, int *domain, int *req)
211{
212
213 vm_domainset_iter_init(di, obj, pindex);
214 di->di_flags = *req;
215 *req = (di->di_flags & ~(VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL)) |
216 VM_ALLOC_NOWAIT;
217 vm_domainset_iter_first(di, domain);
83 }
84 di->di_policy = di->di_domain->ds_policy;
85 if (di->di_policy == DOMAINSET_POLICY_INTERLEAVE) {
86#if VM_NRESERVLEVEL > 0
87 if (vm_object_reserv(obj)) {
88 /*
89 * Color the pindex so we end up on the correct
90 * reservation boundary.

--- 121 unchanged lines hidden (view full) ---

212 vm_pindex_t pindex, int *domain, int *req)
213{
214
215 vm_domainset_iter_init(di, obj, pindex);
216 di->di_flags = *req;
217 *req = (di->di_flags & ~(VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL)) |
218 VM_ALLOC_NOWAIT;
219 vm_domainset_iter_first(di, domain);
218 if (DOMAINSET_ISSET(*domain, &vm_min_domains))
220 if (vm_page_count_min_domain(*domain))
219 vm_domainset_iter_page(di, domain, req);
220}
221
222int
223vm_domainset_iter_page(struct vm_domainset_iter *di, int *domain, int *req)
224{
225
226 /*
227 * If we exhausted all options with NOWAIT and did a WAITFAIL it
228 * is time to return an error to the caller.
229 */
230 if ((*req & VM_ALLOC_WAITFAIL) != 0)
231 return (ENOMEM);
232
233 /* If there are more domains to visit we run the iterator. */
234 while (--di->di_n != 0) {
235 vm_domainset_iter_next(di, domain);
221 vm_domainset_iter_page(di, domain, req);
222}
223
224int
225vm_domainset_iter_page(struct vm_domainset_iter *di, int *domain, int *req)
226{
227
228 /*
229 * If we exhausted all options with NOWAIT and did a WAITFAIL it
230 * is time to return an error to the caller.
231 */
232 if ((*req & VM_ALLOC_WAITFAIL) != 0)
233 return (ENOMEM);
234
235 /* If there are more domains to visit we run the iterator. */
236 while (--di->di_n != 0) {
237 vm_domainset_iter_next(di, domain);
236 if (!di->di_minskip ||
237 !DOMAINSET_ISSET(*domain, &vm_min_domains))
238 if (!di->di_minskip || !vm_page_count_min_domain(*domain))
238 return (0);
239 }
240 if (di->di_minskip) {
241 di->di_minskip = false;
242 vm_domainset_iter_first(di, domain);
243 return (0);
244 }
245

--- 18 unchanged lines hidden (view full) ---

264{
265
266 vm_domainset_iter_init(di, obj, 0);
267 if (di->di_policy == DOMAINSET_POLICY_INTERLEAVE)
268 di->di_policy = DOMAINSET_POLICY_ROUNDROBIN;
269 di->di_flags = *flags;
270 *flags = (di->di_flags & ~M_WAITOK) | M_NOWAIT;
271 vm_domainset_iter_first(di, domain);
239 return (0);
240 }
241 if (di->di_minskip) {
242 di->di_minskip = false;
243 vm_domainset_iter_first(di, domain);
244 return (0);
245 }
246

--- 18 unchanged lines hidden (view full) ---

265{
266
267 vm_domainset_iter_init(di, obj, 0);
268 if (di->di_policy == DOMAINSET_POLICY_INTERLEAVE)
269 di->di_policy = DOMAINSET_POLICY_ROUNDROBIN;
270 di->di_flags = *flags;
271 *flags = (di->di_flags & ~M_WAITOK) | M_NOWAIT;
272 vm_domainset_iter_first(di, domain);
272 if (DOMAINSET_ISSET(*domain, &vm_min_domains))
273 if (vm_page_count_min_domain(*domain))
273 vm_domainset_iter_malloc(di, domain, flags);
274}
275
276int
277vm_domainset_iter_malloc(struct vm_domainset_iter *di, int *domain, int *flags)
278{
279
280 /* If there are more domains to visit we run the iterator. */
281 while (--di->di_n != 0) {
282 vm_domainset_iter_next(di, domain);
274 vm_domainset_iter_malloc(di, domain, flags);
275}
276
277int
278vm_domainset_iter_malloc(struct vm_domainset_iter *di, int *domain, int *flags)
279{
280
281 /* If there are more domains to visit we run the iterator. */
282 while (--di->di_n != 0) {
283 vm_domainset_iter_next(di, domain);
283 if (!di->di_minskip ||
284 !DOMAINSET_ISSET(*domain, &vm_min_domains))
284 if (!di->di_minskip || !vm_page_count_min_domain(*domain))
285 return (0);
286 }
287
288 /* If we skipped domains below min restart the search. */
289 if (di->di_minskip) {
290 di->di_minskip = false;
291 vm_domainset_iter_first(di, domain);
292 return (0);

--- 48 unchanged lines hidden ---
285 return (0);
286 }
287
288 /* If we skipped domains below min restart the search. */
289 if (di->di_minskip) {
290 di->di_minskip = false;
291 vm_domainset_iter_first(di, domain);
292 return (0);

--- 48 unchanged lines hidden ---