Daemon News Ezine BSD News BSD Mall BSD Support Forum BSD Advocacy BSD Updates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

PERFORCE change 90537 for review



http://perforce.freebsd.org/chv.cgi?CH=90537

Change 90537 by alc@alc_home on 2006/01/28 00:21:15

	Introduce buddy_unfree().  It is used to yank a cache state page out
	of the buddy queues.

Affected files ...

.. //depot/projects/superpages/src/sys/vm/vm_buddy.c#4 edit
.. //depot/projects/superpages/src/sys/vm/vm_buddy.h#4 edit

Differences ...

==== //depot/projects/superpages/src/sys/vm/vm_buddy.c#4 (text+ko) ====

@@ -253,6 +253,54 @@
 }
 
 /*
+ * Extract the give page from the buddy queues.
+ */
+boolean_t
+buddy_unfree(vm_page_t m)
+{
+	vm_paddr_t half;
+	vm_page_t buddy, other;
+	int q;
+
+	KASSERT(m->flags & PG_CACHE, ("xxx"));
+	buddy = m;
+	mtx_lock_spin(&vm_page_queue_free_mtx);
+	for (q = 0; (buddy->queue - buddy->buddyq) != PQ_BUDDY &&
+	    q < BUDDY_QUEUES; q++) {
+		buddy = PHYS_TO_VM_PAGE(m->phys_addr &
+		    (~(vm_paddr_t)0 << (PAGE_SHIFT + q)));
+	}
+	if (q == BUDDY_QUEUES || buddy->buddyq < q) {
+		mtx_unlock_spin(&vm_page_queue_free_mtx);
+		return (FALSE);
+	}
+	q = buddy->buddyq;
+
+	/*
+	 * m is in the free list as part of a chunk of size 1<<q whose
+	 * first page is buddy; now we only have to take m out of
+	 * there. For that, we remove the whole chunk, return the half
+	 * where m is not, and iterate.
+	 */
+	buddy_remove(buddy);
+	while (q > 0) {
+		q--;
+		half = buddy->phys_addr ^ (1 << (PAGE_SHIFT + q));
+		if (m->phys_addr < half)
+			other = PHYS_TO_VM_PAGE(half);
+		else {
+			other = buddy;
+			buddy = PHYS_TO_VM_PAGE(half);
+		}
+		buddy_insert(q, other);
+	}
+	cnt.v_free_count--;
+	mtx_unlock_spin(&vm_page_queue_free_mtx);
+	KASSERT(buddy == m, ("yyy"));
+	return (TRUE);
+}
+
+/*
  *
  */
 vm_page_t

==== //depot/projects/superpages/src/sys/vm/vm_buddy.h#4 (text+ko) ====

@@ -6,3 +6,4 @@
 vm_page_t buddy_alloc_locked(int magn, boolean_t prefer_zero);
 void buddy_free(vm_page_t m, int magn);
 void buddy_free_locked(vm_page_t m, int magn);
+boolean_t buddy_unfree(vm_page_t m);