From 34c5030361b3c3b0c1a1435e302ce32677d145c4 Mon Sep 17 00:00:00 2001 From: kn Date: Mon, 21 Feb 2022 16:08:36 +0000 Subject: [PATCH] Grab vmobjlocks with RW_DUPOK in vm_obj_wire() to silence WITNESS The drm subsystem implements graphics buffers as uvm objects backed by anonymous memory, thus drm locks and aobj locks share the same "vmobjlock" type. uvm_obj_wire() is only called from sys/dev/pci/drm/, so instead of changing drm's lock init/alloc routines to mark allow duplicate locks in general, enter uvm's vmobjlock with RW_DUPOK in this function to allow duplicate lock types per thread in this specific call path alone. Fixes the following WITNESS report when booting/starting X (as seen already in other unrelated bugs@ reports): wsdisplay0: screen 1-5 added (std, vt100 emulation) witness: acquiring duplicate lock of same type: "&uobj->vmobjlock" 1st uobjlk 2nd uobjlk Starting stack trace... witness_checkorder(fffffd83b625f9b0,9,0) at witness_checkorder+0x8ac rw_enter(fffffd83b625f9a0,1) at rw_enter+0x68 uvm_obj_wire(fffffd843c39e948,0,40000,ffff800033b70428) at uvm_obj_wire+0x46 shmem_get_pages(ffff800008008500) at shmem_get_pages+0xb8 __i915_gem_object_get_pages(ffff800008008500) at __i915_gem_object_get_pages+0x6d i915_gem_fault(ffff800008008500,ffff800033b707c0,10009b000,a43d6b1c000,ffff800033b70740,1,35ba896911df1241,ffff8000000aa078,ffff8000000aa178) at i915_gem_fault+0x203 drm_fault(ffff800033b707c0,a43d6b1c000,ffff800033b70740,1,0,0,7eca45006f70ee0,ffff800033b707c0) at drm_fault+0x156 uvm_fault(fffffd843a7cf480,a43d6b1c000,0,2) at uvm_fault+0x179 upageflttrap(ffff800033b70920,a43d6b1c000) at upageflttrap+0x62 usertrap(ffff800033b70920) at usertrap+0x129 recall_trap() at recall_trap+0x8 end of kernel end trace frame: 0x7f7ffffdc7c0, count: 246 End of stack trace. Input kettenis OK mpi --- sys/uvm/uvm_object.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/uvm/uvm_object.c b/sys/uvm/uvm_object.c index 4de508e3abe..15166378dcf 100644 --- a/sys/uvm/uvm_object.c +++ b/sys/uvm/uvm_object.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_object.c,v 1.24 2022/01/17 13:55:32 mpi Exp $ */ +/* $OpenBSD: uvm_object.c,v 1.25 2022/02/21 16:08:36 kn Exp $ */ /* * Copyright (c) 2006, 2010, 2019 The NetBSD Foundation, Inc. @@ -133,7 +133,7 @@ uvm_obj_wire(struct uvm_object *uobj, voff_t start, voff_t end, left = (end - start) >> PAGE_SHIFT; - rw_enter(uobj->vmobjlock, RW_WRITE); + rw_enter(uobj->vmobjlock, RW_WRITE | RW_DUPOK); while (left) { npages = MIN(FETCH_PAGECOUNT, left); @@ -147,7 +147,7 @@ uvm_obj_wire(struct uvm_object *uobj, voff_t start, voff_t end, if (error) goto error; - rw_enter(uobj->vmobjlock, RW_WRITE); + rw_enter(uobj->vmobjlock, RW_WRITE | RW_DUPOK); for (i = 0; i < npages; i++) { KASSERT(pgs[i] != NULL); @@ -197,7 +197,7 @@ uvm_obj_unwire(struct uvm_object *uobj, voff_t start, voff_t end) struct vm_page *pg; off_t offset; - rw_enter(uobj->vmobjlock, RW_WRITE); + rw_enter(uobj->vmobjlock, RW_WRITE | RW_DUPOK); uvm_lock_pageq(); for (offset = start; offset < end; offset += PAGE_SIZE) { pg = uvm_pagelookup(uobj, offset); -- 2.20.1