Diff for /src/sys/i386/i386/Attic/pmap.c between versions 1.38 and 1.39

version 1.38, 2004/05/05 22:09:16 version 1.39, 2004/05/13 17:40:14
Line 863  pmap_qremove(vm_offset_t va, int count) Line 863  pmap_qremove(vm_offset_t va, int count)
 #endif  #endif
 }  }
   
   /*
    * This routine works like vm_page_lookup() but also blocks as long as the
    * page is busy.  This routine does not busy the page it returns.
    *
    * Unless the caller is managing objects whos pages are in a known state,
    * the call should be made at splvm() so the page's object association
    * remains valid on return.
    */
 static vm_page_t  static vm_page_t
 pmap_page_lookup(vm_object_t object, vm_pindex_t pindex)  pmap_page_lookup(vm_object_t object, vm_pindex_t pindex)
 {  {
         vm_page_t m;          vm_page_t m;
   
 retry:  retry:
         m = vm_page_lookup(object, pindex);          m = vm_page_lookup(object, pindex);
         if (m && vm_page_sleep_busy(m, FALSE, "pplookp"))          if (m && vm_page_sleep_busy(m, FALSE, "pplookp"))
                 goto retry;                  goto retry;
        return m;        return(m);
 }  }
   
 /*  /*
Line 930  pmap_swapout_proc(struct proc *p) Line 939  pmap_swapout_proc(struct proc *p)
 {  {
 #if 0  #if 0
         int i;          int i;
           int s;
         vm_object_t upobj;          vm_object_t upobj;
         vm_page_t m;          vm_page_t m;
   
         upobj = p->p_upages_obj;          upobj = p->p_upages_obj;
   
         /*          /*
         * let the upages be paged         * Unwiring the pages allow them to be paged to their backing store
          * (swap).
          *
          * splvm() protection not required since nobody will be messing with
          * the pages but us.
          */           */
        for(i=0;i<UPAGES;i++) {        for (i = 0; i < UPAGES; i++) {
                 if ((m = vm_page_lookup(upobj, i)) == NULL)                  if ((m = vm_page_lookup(upobj, i)) == NULL)
                         panic("pmap_swapout_proc: upage already missing???");                          panic("pmap_swapout_proc: upage already missing???");
                 vm_page_dirty(m);                  vm_page_dirty(m);
Line 958  pmap_swapin_proc(struct proc *p) Line 973  pmap_swapin_proc(struct proc *p)
         vm_object_t upobj;          vm_object_t upobj;
         vm_page_t m;          vm_page_t m;
   
           /*
            * splvm() protection not required since nobody will be messing with
            * the pages but us.
            */
         upobj = p->p_upages_obj;          upobj = p->p_upages_obj;
        for(i=0;i<UPAGES;i++) {        for (i = 0; i < UPAGES; i++) {
 
                 m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);                  m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
   
                 pmap_kenter((vm_offset_t)p->p_addr + (i * PAGE_SIZE),                  pmap_kenter((vm_offset_t)p->p_addr + (i * PAGE_SIZE),
Line 973  pmap_swapin_proc(struct proc *p) Line 991  pmap_swapin_proc(struct proc *p)
                         m = vm_page_lookup(upobj, i);                          m = vm_page_lookup(upobj, i);
                         m->valid = VM_PAGE_BITS_ALL;                          m->valid = VM_PAGE_BITS_ALL;
                 }                  }
   
                 vm_page_wire(m);                  vm_page_wire(m);
                 vm_page_wakeup(m);                  vm_page_wakeup(m);
                 vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE);                  vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE);
Line 1327  pmap_release(struct pmap *pmap) Line 1344  pmap_release(struct pmap *pmap)
         vm_page_t p,n,ptdpg;          vm_page_t p,n,ptdpg;
         vm_object_t object = pmap->pm_pteobj;          vm_object_t object = pmap->pm_pteobj;
         int curgeneration;          int curgeneration;
           int s;
   
 #if defined(DIAGNOSTIC)  #if defined(DIAGNOSTIC)
         if (object->ref_count != 1)          if (object->ref_count != 1)
Line 1335  pmap_release(struct pmap *pmap) Line 1353  pmap_release(struct pmap *pmap)
                   
         ptdpg = NULL;          ptdpg = NULL;
 retry:  retry:
           s = splvm();
         curgeneration = object->generation;          curgeneration = object->generation;
         for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) {          for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) {
                 n = TAILQ_NEXT(p, listq);                  n = TAILQ_NEXT(p, listq);
Line 1344  retry: Line 1363  retry:
                 }                  }
                 while (1) {                  while (1) {
                         if (!pmap_release_free_page(pmap, p) &&                          if (!pmap_release_free_page(pmap, p) &&
                                (object->generation != curgeneration))                            (object->generation != curgeneration)) {
                                 splx(s);
                                 goto retry;                                  goto retry;
                           }
                 }                  }
         }          }
           splx(s);
   
         if (ptdpg && !pmap_release_free_page(pmap, ptdpg))          if (ptdpg && !pmap_release_free_page(pmap, ptdpg))
                 goto retry;                  goto retry;
Line 2197  pmap_kenter_temporary(vm_paddr_t pa, int Line 2219  pmap_kenter_temporary(vm_paddr_t pa, int
 }  }
   
 #define MAX_INIT_PT (96)  #define MAX_INIT_PT (96)
   
 /*  /*
 * pmap_object_init_pt preloads the ptes for a given object * This routine preloads the ptes for a given object into the specified pmap.
 * into the specified pmap.  This eliminates the blast of soft * This eliminates the blast of soft faults on process startup and
 * faults on process startup and immediately after an mmap. * immediately after an mmap.
  */   */
 void  void
 pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_prot_t prot,  pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_prot_t prot,
Line 2211  pmap_object_init_pt(pmap_t pmap, vm_offs Line 2234  pmap_object_init_pt(pmap_t pmap, vm_offs
         int psize;          int psize;
         vm_page_t p, mpte;          vm_page_t p, mpte;
         int objpgs;          int objpgs;
           int s;
   
         if ((prot & VM_PROT_READ) == 0 || pmap == NULL || object == NULL)          if ((prot & VM_PROT_READ) == 0 || pmap == NULL || object == NULL)
                 return;                  return;
   
   #if 0
           /* 
            * XXX you must be joking, entering PTE's into a user page table
            * without any accounting?  This could result in the page table
            * being freed while it still contains mappings (free with PG_ZERO
            * assumption leading to a non-zero page being marked PG_ZERO).
            */
         /*          /*
          * This code maps large physical mmap regions into the           * This code maps large physical mmap regions into the
          * processor address space.  Note that some shortcuts           * processor address space.  Note that some shortcuts
          * are taken, but the code works.           * are taken, but the code works.
          */           */
         if (pseflag &&          if (pseflag &&
                (object->type == OBJT_DEVICE) &&            (object->type == OBJT_DEVICE) &&
                ((addr & (NBPDR - 1)) == 0) &&            ((addr & (NBPDR - 1)) == 0) &&
                ((size & (NBPDR - 1)) == 0) ) {            ((size & (NBPDR - 1)) == 0) ) {
                 int i;                  int i;
                 vm_page_t m[1];                  vm_page_t m[1];
                 unsigned int ptepindex;                  unsigned int ptepindex;
Line 2262  retry: Line 2293  retry:
   
                 pmap->pm_stats.resident_count += size >> PAGE_SHIFT;                  pmap->pm_stats.resident_count += size >> PAGE_SHIFT;
                 npdes = size >> PDRSHIFT;                  npdes = size >> PDRSHIFT;
                for(i=0;i<npdes;i++) {                for (i = 0; i < npdes; i++) {
                         pmap->pm_pdir[ptepindex] =                          pmap->pm_pdir[ptepindex] =
                                (pd_entry_t) (ptepa | PG_U | PG_RW | PG_V | PG_PS);                            (pd_entry_t) (ptepa | PG_U | PG_RW | PG_V | PG_PS);
                         ptepa += NBPDR;                          ptepa += NBPDR;
                         ptepindex += 1;                          ptepindex += 1;
                 }                  }
Line 2273  retry: Line 2304  retry:
                 smp_invltlb();                  smp_invltlb();
                 return;                  return;
         }          }
   #endif
   
         psize = i386_btop(size);          psize = i386_btop(size);
   
Line 2288  retry: Line 2320  retry:
                 psize = object->size - pindex;                  psize = object->size - pindex;
         }          }
   
        mpte = NULL;
         /*          /*
         * if we are processing a major portion of the object, then scan the         * If we are processing a major portion of the object, then scan the
          * entire thing.           * entire thing.
            *
            * We cannot safely scan the object's memq unless we are at splvm(),
            * since interrupts can remove pages from objects.
          */           */
           s = splvm();
           mpte = NULL;
         if (psize > (object->resident_page_count >> 2)) {          if (psize > (object->resident_page_count >> 2)) {
                 objpgs = psize;                  objpgs = psize;
   
                 for (p = TAILQ_FIRST(&object->memq);                  for (p = TAILQ_FIRST(&object->memq);
                    ((objpgs > 0) && (p != NULL));                    objpgs > 0 && p != NULL;
                    p = TAILQ_NEXT(p, listq)) {                    p = TAILQ_NEXT(p, listq)
                ) {
                         tmpidx = p->pindex;                          tmpidx = p->pindex;
                        if (tmpidx < pindex) {                        if (tmpidx < pindex)
                                 continue;                                  continue;
                         }  
                         tmpidx -= pindex;                          tmpidx -= pindex;
                        if (tmpidx >= psize) {                        if (tmpidx >= psize)
                                 continue;                                  continue;
                        }
                         /*                          /*
                          * don't allow an madvise to blow away our really                           * don't allow an madvise to blow away our really
                          * free pages allocating pv entries.                           * free pages allocating pv entries.
Line 2357  retry: Line 2393  retry:
                         }                          }
                 }                  }
         }          }
           splx(s);
 }  }
   
 /*  /*
 * pmap_prefault provides a quick way of clustering * pmap_prefault provides a quick way of clustering pagefaults into a
 * pagefaults into a processes address space.  It is a "cousin" * processes address space.  It is a "cousin" of pmap_object_init_pt, 
 * of pmap_object_init_pt, except it runs at page fault time instead * except it runs at page fault time instead of mmap time.
 * of mmap time. 
  */   */
 #define PFBAK 4  #define PFBAK 4
 #define PFFOR 4  #define PFFOR 4
Line 2380  void Line 2416  void
 pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)  pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)
 {  {
         int i;          int i;
           int s;
         vm_offset_t starta;          vm_offset_t starta;
         vm_offset_t addr;          vm_offset_t addr;
         vm_pindex_t pindex;          vm_pindex_t pindex;
Line 2392  pmap_prefault(pmap_t pmap, vm_offset_t a Line 2429  pmap_prefault(pmap_t pmap, vm_offset_t a
         object = entry->object.vm_object;          object = entry->object.vm_object;
   
         starta = addra - PFBAK * PAGE_SIZE;          starta = addra - PFBAK * PAGE_SIZE;
        if (starta < entry->start) {        if (starta < entry->start)
                 starta = entry->start;                  starta = entry->start;
        } else if (starta > addra) {        else if (starta > addra)
                 starta = 0;                  starta = 0;
         }  
   
           /*
            * splvm() protection is required to maintain the page/object 
            * association, interrupts can free pages and remove them from
            * their objects.
            */
         mpte = NULL;          mpte = NULL;
           s = splvm();
         for (i = 0; i < PAGEORDER_SIZE; i++) {          for (i = 0; i < PAGEORDER_SIZE; i++) {
                 vm_object_t lobject;                  vm_object_t lobject;
                 unsigned *pte;                  unsigned *pte;
Line 2419  pmap_prefault(pmap_t pmap, vm_offset_t a Line 2461  pmap_prefault(pmap_t pmap, vm_offset_t a
   
                 pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;                  pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;
                 lobject = object;                  lobject = object;
   
                 for (m = vm_page_lookup(lobject, pindex);                  for (m = vm_page_lookup(lobject, pindex);
                    (!m && (lobject->type == OBJT_DEFAULT) && (lobject->backing_object));                    (!m && (lobject->type == OBJT_DEFAULT) &&
                    lobject = lobject->backing_object) {                     (lobject->backing_object));
                     lobject = lobject->backing_object
                 ) {
                         if (lobject->backing_object_offset & PAGE_MASK)                          if (lobject->backing_object_offset & PAGE_MASK)
                                 break;                                  break;
                         pindex += (lobject->backing_object_offset >> PAGE_SHIFT);                          pindex += (lobject->backing_object_offset >> PAGE_SHIFT);
Line 2447  pmap_prefault(pmap_t pmap, vm_offset_t a Line 2492  pmap_prefault(pmap_t pmap, vm_offset_t a
                         vm_page_wakeup(m);                          vm_page_wakeup(m);
                 }                  }
         }          }
           splx(s);
 }  }
   
 /*  /*
Line 2510  pmap_copy(pmap_t dst_pmap, pmap_t src_pm Line 2556  pmap_copy(pmap_t dst_pmap, pmap_t src_pm
         vm_offset_t pdnxt;          vm_offset_t pdnxt;
         unsigned src_frame, dst_frame;          unsigned src_frame, dst_frame;
         vm_page_t m;          vm_page_t m;
           int s;
   
         if (dst_addr != src_addr)          if (dst_addr != src_addr)
                 return;                  return;
Line 2529  pmap_copy(pmap_t dst_pmap, pmap_t src_pm Line 2576  pmap_copy(pmap_t dst_pmap, pmap_t src_pm
         pmap_inval_add(&info, dst_pmap, -1);          pmap_inval_add(&info, dst_pmap, -1);
         pmap_inval_add(&info, src_pmap, -1);          pmap_inval_add(&info, src_pmap, -1);
   
        for(addr = src_addr; addr < end_addr; addr = pdnxt) {        /*
          * splvm() protection is required to maintain the page/object
          * association, interrupts can free pages and remove them from 
          * their objects.
          */
         s = splvm();
         for (addr = src_addr; addr < end_addr; addr = pdnxt) {
                 unsigned *src_pte, *dst_pte;                  unsigned *src_pte, *dst_pte;
                 vm_page_t dstmpte, srcmpte;                  vm_page_t dstmpte, srcmpte;
                 vm_offset_t srcptepaddr;                  vm_offset_t srcptepaddr;
Line 2607  pmap_copy(pmap_t dst_pmap, pmap_t src_pm Line 2660  pmap_copy(pmap_t dst_pmap, pmap_t src_pm
                         dst_pte++;                          dst_pte++;
                 }                  }
         }          }
           splx(s);
         pmap_inval_flush(&info);          pmap_inval_flush(&info);
 }         }       
   

Removed from v.1.38  
changed lines
  Added in v.1.39