Skip to content

Instantly share code, notes, and snippets.

@rokuyama
Created June 6, 2022 07:05
Show Gist options
  • Save rokuyama/62f4b8b3eb486109629358df9ca31e62 to your computer and use it in GitHub Desktop.
Save rokuyama/62f4b8b3eb486109629358df9ca31e62 to your computer and use it in GitHub Desktop.
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