⬢ DragonFlyBSD Kernel Audit
DF-4522 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/amdgpu/amdgpu_vm.c
+++ b/sys/dev/drm/amd/amdgpu/amdgpu_vm.c
@@ -3318,12 +3318,15 @@
 					     &vm->va.rb_root, rb) {
 #else
 	/*
-	 * DFly interval tree mock-up does not use RB trees, the RB iterator
-	 * can not be used.
-	 * This code is removing all entries so it is fairly easy to replace.
+	 * DFly interval tree shim: the linux rb_root_cached emulation does
+	 * NOT maintain rb_leftmost (rb_insert_color_cached/rb_erase_cached
+	 * in dev/drm/include/linux/rbtree.h ignore it), so we cannot iterate
+	 * on it.  Walk the real tree instead: rb_first() is a real RB_MIN
+	 * walk on this port.  Take the minimum, unlink it, free it, repeat.
 	 */
-	while (vm->va.rb_leftmost) {
-		mapping = container_of((void *)vm->va.rb_leftmost, struct amdgpu_bo_va_mapping, rb);
+	while (!RB_EMPTY_ROOT(&vm->va.rb_root)) {
+		mapping = rb_entry(rb_first(&vm->va.rb_root),
+				   struct amdgpu_bo_va_mapping, rb);
 #endif
 		/* Don't remove the mapping here, we don't want to trigger a
 		 * rebalance and the tree is about to be destroyed anyway.