Created
June 6, 2022 07:05
-
-
Save rokuyama/62f4b8b3eb486109629358df9ca31e62 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: uvm_map.c | |
=================================================================== | |
RCS file: /cvsroot/src/sys/uvm/uvm_map.c,v | |
retrieving revision 1.401 | |
diff -p -u -r1.401 uvm_map.c | |
--- uvm_map.c 6 Jun 2022 07:00:02 -0000 1.401 | |
+++ uvm_map.c 6 Jun 2022 07:04:27 -0000 | |
@@ -199,6 +199,53 @@ uvm_map_align_va(vaddr_t *vap, vsize_t a | |
} | |
/* | |
+ * uvm_map_adjust_va: adjust va according to constraints and PMAP_PREFER | |
+ */ | |
+static void | |
+uvm_map_adjust_va(vaddr_t *vap, vsize_t length, voff_t uoffset, vsize_t align, | |
+ int flags, int topdown) | |
+{ | |
+ | |
+#ifdef PMAP_PREFER | |
+ /* | |
+ * push va forward as needed to avoid VAC alias problems. | |
+ * we only do this if a valid offset is specified. | |
+ */ | |
+ | |
+ if (uoffset != UVM_UNKNOWN_OFFSET) | |
+ PMAP_PREFER(uoffset, vap, length, topdown); | |
+#endif | |
+ if ((flags & UVM_FLAG_COLORMATCH) != 0) { | |
+ KASSERT(align < uvmexp.ncolors); | |
+ if (uvmexp.ncolors > 1) { | |
+ const u_int colormask = uvmexp.colormask; | |
+ const u_int colorsize = colormask + 1; | |
+ vaddr_t hint = atop(*vap); | |
+ const u_int color = hint & colormask; | |
+ if (color != align) { | |
+ hint -= color; /* adjust to color boundary */ | |
+ KASSERT((hint & colormask) == 0); | |
+ if (topdown) { | |
+ if (align > color) | |
+ hint -= colorsize; | |
+ } else { | |
+ if (align < color) | |
+ hint += colorsize; | |
+ } | |
+ *vap = ptoa(hint + align); /* adjust to color */ | |
+ } | |
+ } | |
+ } else { | |
+ KASSERT(powerof2(align)); | |
+ uvm_map_align_va(vap, align, topdown); | |
+ /* | |
+ * XXX Should we PMAP_PREFER() here again? | |
+ * eh...i think we're okay | |
+ */ | |
+ } | |
+} | |
+ | |
+/* | |
* UVM_ET_ISCOMPATIBLE: check some requirements for map entry merging | |
*/ | |
extern struct vm_map *pager_map; | |
@@ -1724,43 +1771,11 @@ uvm_map_space_avail(vaddr_t *start, vsiz | |
{ | |
vaddr_t end; | |
-#ifdef PMAP_PREFER | |
/* | |
- * push start address forward as needed to avoid VAC alias problems. | |
- * we only do this if a valid offset is specified. | |
+ * First, adjust start according to constraints and PMAP_PREFER. | |
*/ | |
- if (uoffset != UVM_UNKNOWN_OFFSET) | |
- PMAP_PREFER(uoffset, start, length, topdown); | |
-#endif | |
- if ((flags & UVM_FLAG_COLORMATCH) != 0) { | |
- KASSERT(align < uvmexp.ncolors); | |
- if (uvmexp.ncolors > 1) { | |
- const u_int colormask = uvmexp.colormask; | |
- const u_int colorsize = colormask + 1; | |
- vaddr_t hint = atop(*start); | |
- const u_int color = hint & colormask; | |
- if (color != align) { | |
- hint -= color; /* adjust to color boundary */ | |
- KASSERT((hint & colormask) == 0); | |
- if (topdown) { | |
- if (align > color) | |
- hint -= colorsize; | |
- } else { | |
- if (align < color) | |
- hint += colorsize; | |
- } | |
- *start = ptoa(hint + align); /* adjust to color */ | |
- } | |
- } | |
- } else { | |
- KASSERT(powerof2(align)); | |
- uvm_map_align_va(start, align, topdown); | |
- /* | |
- * XXX Should we PMAP_PREFER() here again? | |
- * eh...i think we're okay | |
- */ | |
- } | |
+ uvm_map_adjust_va(start, length, uoffset, align, flags, topdown); | |
/* | |
* Find the end of the proposed new region. Be sure we didn't | |
@@ -1870,11 +1885,15 @@ uvm_map_findspace(struct vm_map *map, va | |
hint, vm_map_min(map), vm_map_max(map), 0); | |
/* | |
- * hint may not be aligned properly; we need round up or down it | |
- * before proceeding further. | |
+ * hint may not satisfy constraints and PMAP_PREFER; we need | |
+ * round up or down it before proceeding further. Otherwise, | |
+ * we end up with inconsistencies; see kern/51254 and 54395. | |
+ * | |
+ * XXX UVM_FLAG_FIXED is superior to PMAP_PREFER? | |
*/ | |
- if ((flags & UVM_FLAG_COLORMATCH) == 0) { | |
- uvm_map_align_va(&hint, align, topdown); | |
+ if ((flags & UVM_FLAG_FIXED) == 0) { | |
+ uvm_map_adjust_va(&hint, length, uoffset, align, flags, | |
+ topdown); | |
INVARIANTS(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment