This function moves a page from one queue to another. To change the
"queue" field from one index to another, the page queue lock for the old
queue must be held. When the cmpset succeeds, this lock no longer
protects the page queue state, so it is incorrect to call
vm_pagequeue_remove() after that point. Thus, we must preemptively
remove the page from its queue, and re-insert it if the state commit
fails.
Also remove the assertion about VPO_UNMANAGED. There is no guarantee
that the page has not been reallocated as an unmanaged page. In this
case, though, the cmpset must fail since the "queue" field for an
unmanaged page will be PQ_NONE, and we assert oldq != PQ_NONE.
BTW, my aim is to convert all queue state updates (i.e. modifications to
"queue", "aflags" and "act_count" fields) into transactional blocks,
using a 32-bit atomic cmpset on the vm_page structure. In my tree I
added a counter for failed cmpsets, and found that they are very rare in
practice.