diff options
author | Doug Moore <dougm@FreeBSD.org> | 2021-12-31 04:09:08 +0000 |
---|---|---|
committer | Doug Moore <dougm@FreeBSD.org> | 2021-12-31 04:09:08 +0000 |
commit | c606ab59e7f9423f7027320e9a4514c7db39658d (patch) | |
tree | b2bc719125dca33ade16287cbc9dd663b4f19bc0 /sys/vm | |
parent | c09981f1422ef0d44042dacc5d1265392fba39f1 (diff) | |
download | src-c606ab59e7f9423f7027320e9a4514c7db39658d.tar.gz src-c606ab59e7f9423f7027320e9a4514c7db39658d.zip |
vm_extern: use standard address checkers everywhere
Define simple functions for alignment and boundary checks and use them
everywhere instead of having slightly different implementations
scattered about. Define them in vm_extern.h and use them where
possible where vm_extern.h is included.
Reviewed by: kib, markj
Differential Revision: https://reviews.freebsd.org/D33685
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vm_extern.h | 27 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 6 | ||||
-rw-r--r-- | sys/vm/vm_page.c | 5 | ||||
-rw-r--r-- | sys/vm/vm_phys.c | 4 | ||||
-rw-r--r-- | sys/vm/vm_reserv.c | 21 |
5 files changed, 41 insertions, 22 deletions
diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index ed365bd41689..4e03bba66eeb 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -133,5 +133,32 @@ u_int vm_active_count(void); u_int vm_inactive_count(void); u_int vm_laundry_count(void); u_int vm_wait_count(void); + +/* + * Is pa a multiple of alignment, which is a power-of-two? + */ +static inline bool +vm_addr_align_ok(vm_paddr_t pa, u_long alignment) +{ + return ((pa & (alignment - 1)) == 0); +} + +/* + * Do the first and last addresses of a range match in all bits except the ones + * in -boundary (a power-of-two)? For boundary == 0, all addresses match. + */ +static inline bool +vm_addr_bound_ok(vm_paddr_t pa, vm_paddr_t size, vm_paddr_t boundary) +{ + return (((pa ^ (pa + size - 1)) & -boundary) == 0); +} + +static inline bool +vm_addr_ok(vm_paddr_t pa, vm_paddr_t size, u_long alignment, + vm_paddr_t boundary) +{ + return (vm_addr_align_ok(pa, alignment) && + vm_addr_bound_ok(pa, size, boundary)); +} #endif /* _KERNEL */ #endif /* !_VM_EXTERN_H_ */ diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 87a290b998b9..1b2b5eb8d5e9 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -2032,10 +2032,8 @@ vm_map_alignspace(vm_map_t map, vm_object_t object, vm_ooffset_t offset, */ if (alignment == 0) pmap_align_superpage(object, offset, addr, length); - else if ((*addr & (alignment - 1)) != 0) { - *addr &= ~(alignment - 1); - *addr += alignment; - } + else + *addr = roundup2(*addr, alignment); aligned_addr = *addr; if (aligned_addr == free_addr) { /* diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 07691c15d8ef..3398690a9661 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -2656,12 +2656,11 @@ vm_page_scan_contig(u_long npages, vm_page_t m_start, vm_page_t m_end, if (m + npages > m_end) break; pa = VM_PAGE_TO_PHYS(m); - if ((pa & (alignment - 1)) != 0) { + if (!vm_addr_align_ok(pa, alignment)) { m_inc = atop(roundup2(pa, alignment) - pa); continue; } - if (rounddown2(pa ^ (pa + ptoa(npages) - 1), - boundary) != 0) { + if (!vm_addr_bound_ok(pa, ptoa(npages), boundary)) { m_inc = atop(roundup2(pa, boundary) - pa); continue; } diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c index ad997581e77c..9a13fe23c874 100644 --- a/sys/vm/vm_phys.c +++ b/sys/vm/vm_phys.c @@ -179,6 +179,7 @@ static void _vm_phys_create_seg(vm_paddr_t start, vm_paddr_t end, int domain); static void vm_phys_create_seg(vm_paddr_t start, vm_paddr_t end); static void vm_phys_split_pages(vm_page_t m, int oind, struct vm_freelist *fl, int order, int tail); + /* * Red-black tree helpers for vm fictitious range management. */ @@ -1465,8 +1466,7 @@ vm_phys_alloc_seg_contig(struct vm_phys_seg *seg, u_long npages, pa = VM_PAGE_TO_PHYS(m_ret); pa_end = pa + size; if (pa >= low && pa_end <= high && - (pa & (alignment - 1)) == 0 && - rounddown2(pa ^ (pa_end - 1), boundary) == 0) + vm_addr_ok(pa, size, alignment, boundary)) goto done; } } diff --git a/sys/vm/vm_reserv.c b/sys/vm/vm_reserv.c index b4902942224d..639121806857 100644 --- a/sys/vm/vm_reserv.c +++ b/sys/vm/vm_reserv.c @@ -656,10 +656,8 @@ vm_reserv_alloc_contig(vm_object_t object, vm_pindex_t pindex, int domain, * possible size satisfy the alignment and boundary requirements? */ pa = VM_RESERV_INDEX(object, pindex) << PAGE_SHIFT; - if ((pa & (alignment - 1)) != 0) - return (NULL); size = npages << PAGE_SHIFT; - if (((pa ^ (pa + size - 1)) & ~(boundary - 1)) != 0) + if (!vm_addr_ok(pa, size, alignment, boundary)) return (NULL); /* @@ -682,8 +680,7 @@ vm_reserv_alloc_contig(vm_object_t object, vm_pindex_t pindex, int domain, m = &rv->pages[index]; pa = VM_PAGE_TO_PHYS(m); if (pa < low || pa + size > high || - (pa & (alignment - 1)) != 0 || - ((pa ^ (pa + size - 1)) & ~(boundary - 1)) != 0) + !vm_addr_ok(pa, size, alignment, boundary)) goto out; /* Handle vm_page_rename(m, new_object, ...). */ for (i = 0; i < npages; i++) @@ -1333,7 +1330,7 @@ vm_reserv_reclaim_contig(int domain, u_long npages, vm_paddr_t low, * doesn't include a boundary-multiple within it. Otherwise, * no boundary-constrained allocation is possible. */ - if (size > boundary && boundary > 0) + if (!vm_addr_bound_ok(0, size, boundary)) return (NULL); marker = &vm_rvd[domain].marker; queue = &vm_rvd[domain].partpop; @@ -1360,7 +1357,7 @@ vm_reserv_reclaim_contig(int domain, u_long npages, vm_paddr_t low, /* This entire reservation is too high; go to next. */ continue; } - if ((pa & (alignment - 1)) != 0) { + if (!vm_addr_align_ok(pa, alignment)) { /* This entire reservation is unaligned; go to next. */ continue; } @@ -1397,12 +1394,10 @@ vm_reserv_reclaim_contig(int domain, u_long npages, vm_paddr_t low, vm_reserv_unlock(rv); m_ret = &rv->pages[posn]; pa = VM_PAGE_TO_PHYS(m_ret); - KASSERT((pa & (alignment - 1)) == 0, - ("%s: adjusted address does not align to %lx", - __func__, alignment)); - KASSERT(((pa ^ (pa + size - 1)) & -boundary) == 0, - ("%s: adjusted address spans boundary to %jx", - __func__, (uintmax_t)boundary)); + KASSERT(vm_addr_ok(pa, size, alignment, boundary), + ("%s: adjusted address not aligned/bounded to " + "%lx/%jx", + __func__, alignment, (uintmax_t)boundary)); return (m_ret); } vm_reserv_domain_lock(domain); |