We can not block waiting for busy in the free path and nothing should be acquiring busy other than incorrect transients from unlocked lookup. I simply leave the pages xbusied from alloc until they are freed. uma_small_alloc/free does not have this problem because it uses NOOBJ allocation and so busy is not required on free. We technically could allow the asserts to skip xbusy on free for kmem_object but I think that is more confusing than simply leaving the pages locked.
vm_page_xbusy_claim() additionally allows us to improve our debugging in areas where the lock ownership is known to specifically change. It costs nothing on release kernels and it is safer than the KERNPROC approach that anyone can acquire. It should allow us to remove other unchecked busy asserts.