Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 06 May 2012 12:35:33 -0500
From:      Alan Cox <alc@rice.edu>
To:        Warner Losh <imp@bsdimp.com>
Cc:        "arm@freebsd.org" <arm@FreeBSD.org>, Alan Cox <alc@FreeBSD.org>
Subject:   Re: Review needed
Message-ID:  <4FA6B665.1040709@rice.edu>
In-Reply-To: <EBCFF89A-18E8-48B8-A7BD-09C0B942DAB1@bsdimp.com>
References:  <EBCFF89A-18E8-48B8-A7BD-09C0B942DAB1@bsdimp.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 05/05/2012 01:45, Warner Losh wrote:
> I just tried to bring up an old Gateworks AVILA board that I'd acquired a long time ago....
>
> After fighting through a few bugs in the nanobsd build, I managed to get an image.
>
> That image failed to boot.  When it harvested entropy, it just started printing pmap_mincore() over and over again until I hit ^T enough to let the rest of the boot process continue.  Sure enough, arm's pmap_mincore() returns 0 after printing this.
>
> So, I cobbled together the following after looking at mips and amd64's pmap_mincore() functions.
>
> I've just cut and pasted it here since I think that might be easier to review than a diff, but I've also uploaded that as well to http://people.freebsd.org/~imp/arm-pmap_mincore.diff
>
> Comments?
>
> Warner
>
> /*
>   * perform the pmap work for mincore
>   */
> int
> pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa)
> {
>          struct l2_bucket *l2b;
>          pt_entry_t *ptep, pte;
>          vm_paddr_t pa;
>          vm_page_t m;
>          int val;
>          boolean_t managed;
>
>          PMAP_LOCK(pmap);
> retry:
>          l2b = pmap_get_l2_bucket(pmap, addr);
>          if (l2b == NULL) {
>                  val = 0;
>                  goto out;
>          }
>          ptep =&l2b->l2b_kva[l2pte_index(addr)];
>          pte = (ptep != NULL) ? *ptep : 0;
>          if (!l2pte_valid(pte)) {
>                  val = 0;
>                  goto out;
>          }
>          val = MINCORE_INCORE;
> 	if (pte&  L2_S_PROT_W)
>                  val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
>          managed = false;
>          pa = l2pte_pa(pte);
>          m = PHYS_TO_VM_PAGE(pa);
>          if (m != NULL&&  !(m->oflags&  VPO_UNMANAGED))
>                  managed = true;
>          if (managed) {
>                  /*
>                   * This may falsely report the given address as
>                   * MINCORE_REFERENCED.  Unfortunately, due to the lack of
>                   * per-PTE reference information, it is impossible to
>                   * determine if the address is MINCORE_REFERENCED.
>                   */
>                  if ((m->aflags&  PGA_REFERENCED) != 0)

I believe that you want to use "if ((m->md.pvh_attrs & PVF_REF) != 0)" 
here instead.

Strictly speaking, the ARM pmap tries to maintain a per-mapping 
reference bit.  The trouble is that it's kept in the PV entry, not the 
PTE, so it's costly to access here.  You would need to acquire the page 
queues lock, call pmap_find_pv(), and introduce a custom version of 
vm_page_pa_tryrelock() that releases and reacquires the page queues 
lock.  In the end, I doubt it's worthwhile.  However, it would make 
sense for the comment to mention this.

>                          val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER;
>          }
>          if ((val&  (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) !=
>              (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)&&  managed) {
>                  /* Ensure that "PHYS_TO_VM_PAGE(pa)->object" doesn't change. */
>                  if (vm_page_pa_tryrelock(pmap, pa, locked_pa))
>                          goto retry;
>          } else
> out:
>                  PA_UNLOCK_COND(*locked_pa);
>          PMAP_UNLOCK(pmap);
>          return (val);
> }
>
>




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4FA6B665.1040709>