* pmap_page_wired_mappings: * * Return the number of managed mappings to the given physical page * that are wired. */
| 7887 | * that are wired. |
| 7888 | */ |
| 7889 | int |
| 7890 | pmap_page_wired_mappings(vm_page_t m) |
| 7891 | { |
| 7892 | struct rwlock *lock; |
| 7893 | struct md_page *pvh; |
| 7894 | pmap_t pmap; |
| 7895 | pt_entry_t *pte; |
| 7896 | pv_entry_t pv; |
| 7897 | int count, md_gen, pvh_gen; |
| 7898 | |
| 7899 | if ((m->oflags & VPO_UNMANAGED) != 0) |
| 7900 | return (0); |
| 7901 | lock = VM_PAGE_TO_PV_LIST_LOCK(m); |
| 7902 | rw_rlock(lock); |
| 7903 | restart: |
| 7904 | count = 0; |
| 7905 | TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { |
| 7906 | pmap = PV_PMAP(pv); |
| 7907 | if (!PMAP_TRYLOCK(pmap)) { |
| 7908 | md_gen = m->md.pv_gen; |
| 7909 | rw_runlock(lock); |
| 7910 | PMAP_LOCK(pmap); |
| 7911 | rw_rlock(lock); |
| 7912 | if (md_gen != m->md.pv_gen) { |
| 7913 | PMAP_UNLOCK(pmap); |
| 7914 | goto restart; |
| 7915 | } |
| 7916 | } |
| 7917 | pte = pmap_pte(pmap, pv->pv_va); |
| 7918 | if ((*pte & PG_W) != 0) |
| 7919 | count++; |
| 7920 | PMAP_UNLOCK(pmap); |
| 7921 | } |
| 7922 | if ((m->flags & PG_FICTITIOUS) == 0) { |
| 7923 | pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m)); |
| 7924 | TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { |
| 7925 | pmap = PV_PMAP(pv); |
| 7926 | if (!PMAP_TRYLOCK(pmap)) { |
| 7927 | md_gen = m->md.pv_gen; |
| 7928 | pvh_gen = pvh->pv_gen; |
| 7929 | rw_runlock(lock); |
| 7930 | PMAP_LOCK(pmap); |
| 7931 | rw_rlock(lock); |
| 7932 | if (md_gen != m->md.pv_gen || |
| 7933 | pvh_gen != pvh->pv_gen) { |
| 7934 | PMAP_UNLOCK(pmap); |
| 7935 | goto restart; |
| 7936 | } |
| 7937 | } |
| 7938 | pte = pmap_pde(pmap, pv->pv_va); |
| 7939 | if ((*pte & PG_W) != 0) |
| 7940 | count++; |
| 7941 | PMAP_UNLOCK(pmap); |
| 7942 | } |
| 7943 | } |
| 7944 | rw_runlock(lock); |
| 7945 | return (count); |
| 7946 | } |