Subject: Re: Strange VM behaviour
To: None <lennart@mail.augustsson.net, tech-kern@netbsd.org>
From: None <eeh@netbsd.org>
List: tech-kern
Date: 02/04/2001 19:33:30
	When my machine is heavily loaded memory-wise (which happens a lot
	with UBC) I've observed a strange behaviour.  Perhaps it's normal, but I
	doubt it.
	All of a sudden the machine freezes.  I can't move the mouse, there is no
	sound from my speakers anymore, and there is no disk activity.  This lasts
	1 - 5 seconds and then everything is back to normal again (i.e. paging like
	crazy).
	Can anyone shed any light?  (No, I've not been able to switch console
	to get into the debugger, so no stack traces.)

Haven't been paying very much attention to tech-kern lately,
have we?

What you're seeing is typical UBC behavior:

1) the buffer cache useage is unlimited,
so any/all pages are eventually swallowed
by the buffer cache, displacing everything
else including the X server.

2) there is no limit on dirty buffer cache
pages and nothing to force immediate writing
so when the sync-er runs a huge number of pages
are scheduled to be written, which swamps the
I/O subsystem.

3) The page scanner was broken so it degraded
to FIFO page replacement rather than LRU.  Jason
has fixed that a couple of weeks ago.

For #3, upgrade.

For #1, you can use a patch that Jason sent
out a few weeks ago.

For #1 and #2, you can try the following patch
(which potentially causes TLB issues, but those
are much less expensive than UBC issues):

Index: uvm_bio.c
===================================================================
RCS file: /cvsroot/syssrc/sys/uvm/uvm_bio.c,v
retrieving revision 1.6
diff -u -r1.6 uvm_bio.c
--- uvm_bio.c   2000/12/27 09:01:45     1.6
+++ uvm_bio.c   2001/02/04 19:33:04
@@ -439,6 +439,7 @@
                (umap - ubc_object.umap) * ubc_winsize + slot_offset;
 }
 
+int ubc_reclaim = 1;
 
 void
 ubc_release(va, wlen)
@@ -463,6 +464,24 @@
        umap->writelen = 0;
        umap->refcount--;
        if (umap->refcount == 0) {
+#if 1
+               if (ubc_reclaim) {
+                       struct vm_page *p;
+
+                       /* Take any pages in this uobj and put them on the inactive list. */
+                       uvm_lock_pageq();
+                       TAILQ_FOREACH(p, &uobj->memq, listq) {
+                               if ((p->pqflags & PQ_ACTIVE) && !(p->flags & PG_BUSY)) {
+                                       pmap_clear_reference(p);
+                               /* no need to check wire_count as pg is "active" */
+                                       uvm_pagedeactivate(p);
+                                       uvmexp.pddeact++;
+                               }
+                       }
+                       uvm_unlock_pageq();
+       }
+       
+#endif
                if (UBC_RELEASE_UNMAP &&
                    (((struct vnode *)uobj)->v_flag & VTEXT)) {
                        vaddr_t va;