Subject: More R/M problems
To: None <tech-kern@netbsd.org>
From: Charles M. Hannum <root@ihack.net>
List: tech-kern
Date: 03/31/1999 04:09:04
So it turns out there are some other problems with the way R/M
information is handled.  It's possible for modified bits to be thrown
away in some cases:

* if pmap_pageable() (which is called by uvm_vsunlock()) happens to do
  a pmap_clear_modify() (as mentioned previously),

* if you're doing raw I/O through physio, and the driver does DMA, or

* if you're doing raw I/O through physio, and vunmapbuf() throws away
  the modification info (as it does with direct PTE frobbing on some
  platforms).

This doesn't actually happen much, because few things do raw device
I/O, and the major one (fsck(8)) normally runs at boot time.  However,
it could become problematic with things like lfs_cleanerd, which are
persistent and will typically be most active exactly when the machine
is busy and memory is likely to be more scarce.

In addition, it would be useful to be able to tell uvm_fault_wire() to
`really wire this page now, damn it'.  As it stands, both the Alpha
and ARM ports have to explicitly frob the M bits for the u area (PCB
and kernel stack) in cpu_swapin() to prevent possibly taking faults,
because there's no general way to do this through the VM system when
wiring the pages.

Therefore, I suggest the following changes to correct this situation:

* Require all ports to use the access_type passed to pmap_enter() to
  add (but never delete) R/M information immediately -- even in the
  case where this information is managed by hardware.

* Pass an access_type, derived from the I/O direction, to
  uvm_vslock().  From there it will be passed down to
  uvm_fault_wire(), uvm_fault(), and eventually to pmap_enter(), so
  that the R/M bits are always preset and the pages are truly wired.
  This will also eliminate the hack in uvm_fault() to set
  access_type=enter_prot in the wired case -- which, given the
  previous modification, would cause M bits to get set even if the
  memory is not being modified.

  In addition, this should prevent R/M emulation faults inside
  interrupt handlers in most cases.

I believe these fairly simple modifications will resolve all known
problems in this area.

Assuming no serious technical problems, I will implement this next
weekend.