Subject: Re: new pmap
To: UCHIYAMA Yasushi <uch@vnop.net>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: port-sh3
Date: 05/06/2002 13:01:45
On Fri, May 03, 2002 at 08:23:12AM -0700, Jason R Thorpe wrote:

 > I will send another message shortly with my specific comments.

UCHIYAMA-san...

Ok, sorry for the delay, but here are my comments on the new pmap module.

Global comments:

	* I notice there isn't any locking going on in here.  This is
	  probably OK for all existing SuperH systems, but it might
	  be nice to add it later, if only for debugging purposes when
	  LOCKDEBUG is defined.

	* You are using splvm() an awful lot.  It should not really
	  be necessary in very many parts of the pmap module.

pmap_create()

	* Since you are only using 512 slots out of a 1024 slot table,
	  you might want to consider using a pool for the L1 table,
	  which would allow you to using one page for every 2 pmaps,
	  rather than 1 page for each pmap.  Saving memory on SuperH
	  systems is good, since they tend not to have very much :-)

pmap_destroy()

	* See above about the L1 table.

	* Since you are throwing away the data for the pages you
	  are freeing, you might consider changing the wbinv_range
	  to just inv_range, so that it's faster if you're using
	  the cache in write-back mode.

pmap_enter():

	* You should be using the "flags" argument to seed the
	  REFERENCED and MODIFIED bits in the mdpage.  I.e. something
	  like this:

#ifdef DIAGNOSTIC
		if ((flags & VM_PROT_ALL) & ~prot)
			panic("pmap_enter: access type exceeds prot");
#endif
		if (flags & VM_PROT_WRITE)
			pg->mdpage.pvh_flags |= PVH_MODIFIED|PVH_REFERENCED;
		else if (flags & VM_PROT_ALL)
			pg->mdpage.pvh_flags |= PVH_REFRENCED;

		.
		.
		.

	  ...and then use the combination of the prot and the current
	  pvh_flags to set the protection in the PTE.

	  Note that you must also do modified/referenced emulation for
	  the kernel pmap -- the "flags" argument will always specify
	  the correct pvh_flags seed for wired kernel mappings.

	  Also, in regards to modified emulation, you the algorithm for
	  setting the protection in the PTE needs to be like this:

		if (prot & VM_PROT_WRITE) {
			if (page-is-modified)
				set dirty+valid in the PTE;
			else if (page-is-referenced)
				set valid in the PTE;
		}

	  Likewise when you take the modified emulation fault.  This
	  can reduce the number of faults you have to take.

	* pmap_enter() can be called when there is already a valid mapping
	  at the specified VA.  This means you need to:

		if (already-mapping-at-va) {
			if (old-pa == new-pa) {
				adjust protection if necessary;
				adjust pm_stats.wired_count if necessary;
			} else {
				remove old mapping;// decrements resident_count
				goto enter_it;
			}
		} else {
 enter_it:
			enter new mapping; // increments resident_count
		}

pmap_is_referenced()

	* Return TRUE or FALSE.

__pmap_pte_load():

	* I would change the KDASSERT() to read:

		KDASSERT(((intptr_t) va < 0 && pmap == pmap_kernel()) ||
			 ((intptr_t) va >= 0 && pmap != pmap_kernel()))

	  i.e. remove the "va != 0" bit -- whether or not something is
	  mapped at 0 is a policy decision made by the upper layers of
	  the VM code (unless va 0 is magic, like it is on the ARM).

__pmap_asid_alloc():

	* Would a generational ASID allocator work for the SuperH?  See
	  the Alpha pmap_asn_alloc().

Anyway, terrific work!  I'm looking forward to seeing this committed to
the source tree!

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>