The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/vm/vm_object.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1991, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * This code is derived from software contributed to Berkeley by
    6  * The Mach Operating System project at Carnegie-Mellon University.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by the University of
   19  *      California, Berkeley and its contributors.
   20  * 4. Neither the name of the University nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  *      from: @(#)vm_object.c   8.5 (Berkeley) 3/22/94
   37  *
   38  *
   39  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
   40  * All rights reserved.
   41  *
   42  * Authors: Avadis Tevanian, Jr., Michael Wayne Young
   43  *
   44  * Permission to use, copy, modify and distribute this software and
   45  * its documentation is hereby granted, provided that both the copyright
   46  * notice and this permission notice appear in all copies of the
   47  * software, derivative works or modified versions, and any portions
   48  * thereof, and that both notices appear in supporting documentation.
   49  *
   50  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   51  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
   52  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   53  *
   54  * Carnegie Mellon requests users of this software to return to
   55  *
   56  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   57  *  School of Computer Science
   58  *  Carnegie Mellon University
   59  *  Pittsburgh PA 15213-3890
   60  *
   61  * any improvements or extensions that they make and grant Carnegie the
   62  * rights to redistribute these changes.
   63  *
   64  * $FreeBSD: src/sys/vm/vm_object.c,v 1.82.2.3 1999/09/05 08:24:32 peter Exp $
   65  */
   66 
   67 /*
   68  *      Virtual memory object module.
   69  */
   70 
   71 #include <sys/param.h>
   72 #include <sys/systm.h>
   73 #include <sys/kernel.h>
   74 #include <sys/proc.h>           /* for curproc, pageproc */
   75 #include <sys/malloc.h>
   76 #include <sys/vnode.h>
   77 #include <sys/mount.h>
   78 #include <sys/vmmeter.h>
   79 #include <sys/mman.h>
   80 
   81 #include <vm/vm.h>
   82 #include <vm/vm_param.h>
   83 #include <vm/vm_prot.h>
   84 #include <vm/lock.h>
   85 #include <vm/pmap.h>
   86 #include <vm/vm_map.h>
   87 #include <vm/vm_object.h>
   88 #include <vm/vm_page.h>
   89 #include <vm/vm_pageout.h>
   90 #include <vm/vm_pager.h>
   91 #include <vm/swap_pager.h>
   92 #include <vm/vm_kern.h>
   93 #include <vm/vm_extern.h>
   94 
   95 static void     _vm_object_allocate __P((objtype_t, vm_size_t, vm_object_t));
   96 static void     vm_object_qcollapse __P((vm_object_t object));
   97 #ifdef not_used
   98 static void     vm_object_deactivate_pages __P((vm_object_t));
   99 #endif
  100 static void     vm_object_terminate __P((vm_object_t));
  101 static void     vm_object_cache_trim __P((void));
  102 
  103 /*
  104  *      Virtual memory objects maintain the actual data
  105  *      associated with allocated virtual memory.  A given
  106  *      page of memory exists within exactly one object.
  107  *
  108  *      An object is only deallocated when all "references"
  109  *      are given up.  Only one "reference" to a given
  110  *      region of an object should be writeable.
  111  *
  112  *      Associated with each object is a list of all resident
  113  *      memory pages belonging to that object; this list is
  114  *      maintained by the "vm_page" module, and locked by the object's
  115  *      lock.
  116  *
  117  *      Each object also records a "pager" routine which is
  118  *      used to retrieve (and store) pages to the proper backing
  119  *      storage.  In addition, objects may be backed by other
  120  *      objects from which they were virtual-copied.
  121  *
  122  *      The only items within the object structure which are
  123  *      modified after time of creation are:
  124  *              reference count         locked by object's lock
  125  *              pager routine           locked by object's lock
  126  *
  127  */
  128 
  129 int vm_object_cache_max;
  130 struct object_q vm_object_cached_list;
  131 static int vm_object_cached;
  132 struct object_q vm_object_list;
  133 static long vm_object_count;
  134 vm_object_t kernel_object;
  135 vm_object_t kmem_object;
  136 static struct vm_object kernel_object_store;
  137 static struct vm_object kmem_object_store;
  138 extern int vm_pageout_page_count;
  139 
  140 static long object_collapses;
  141 static long object_bypasses;
  142 static int next_index;
  143 
  144 static void
  145 _vm_object_allocate(type, size, object)
  146         objtype_t type;
  147         vm_size_t size;
  148         register vm_object_t object;
  149 {
  150         TAILQ_INIT(&object->memq);
  151         TAILQ_INIT(&object->shadow_head);
  152 
  153         object->type = type;
  154         object->size = size;
  155         object->ref_count = 1;
  156         object->flags = 0;
  157         object->behavior = OBJ_NORMAL;
  158         object->paging_in_progress = 0;
  159         object->resident_page_count = 0;
  160         object->shadow_count = 0;
  161         object->pg_color = next_index;
  162         next_index = (next_index + PQ_PRIME1) & PQ_L2_MASK;
  163         object->handle = NULL;
  164         object->paging_offset = (vm_ooffset_t) 0;
  165         object->backing_object = NULL;
  166         object->backing_object_offset = (vm_ooffset_t) 0;
  167         object->page_hint = NULL;
  168 
  169         object->last_read = 0;
  170 
  171         TAILQ_INSERT_TAIL(&vm_object_list, object, object_list);
  172         vm_object_count++;
  173 }
  174 
  175 /*
  176  *      vm_object_init:
  177  *
  178  *      Initialize the VM objects module.
  179  */
  180 void
  181 vm_object_init()
  182 {
  183         TAILQ_INIT(&vm_object_cached_list);
  184         TAILQ_INIT(&vm_object_list);
  185         vm_object_count = 0;
  186         
  187         vm_object_cache_max = 84;
  188         if (cnt.v_page_count > 1000)
  189                 vm_object_cache_max += (cnt.v_page_count - 1000) / 4;
  190 
  191         kernel_object = &kernel_object_store;
  192         _vm_object_allocate(OBJT_DEFAULT, OFF_TO_IDX(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS),
  193             kernel_object);
  194 
  195         kmem_object = &kmem_object_store;
  196         _vm_object_allocate(OBJT_DEFAULT, OFF_TO_IDX(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS),
  197             kmem_object);
  198 }
  199 
  200 /*
  201  *      vm_object_allocate:
  202  *
  203  *      Returns a new object with the given size.
  204  */
  205 
  206 vm_object_t
  207 vm_object_allocate(type, size)
  208         objtype_t type;
  209         vm_size_t size;
  210 {
  211         register vm_object_t result;
  212 
  213         result = (vm_object_t)
  214             malloc((u_long) sizeof *result, M_VMOBJ, M_WAITOK);
  215 
  216 
  217         _vm_object_allocate(type, size, result);
  218 
  219         return (result);
  220 }
  221 
  222 
  223 /*
  224  *      vm_object_reference:
  225  *
  226  *      Gets another reference to the given object.
  227  */
  228 void
  229 vm_object_reference(object)
  230         register vm_object_t object;
  231 {
  232         if (object == NULL)
  233                 return;
  234 
  235         if (object->ref_count == 0) {
  236                 if ((object->flags & OBJ_CANPERSIST) == 0)
  237                         panic("vm_object_reference: non-persistent object with 0 ref_count");
  238                 TAILQ_REMOVE(&vm_object_cached_list, object, cached_list);
  239                 vm_object_cached--;
  240         }
  241         object->ref_count++;
  242 }
  243 
  244 /*
  245  *      vm_object_deallocate:
  246  *
  247  *      Release a reference to the specified object,
  248  *      gained either through a vm_object_allocate
  249  *      or a vm_object_reference call.  When all references
  250  *      are gone, storage associated with this object
  251  *      may be relinquished.
  252  *
  253  *      No object may be locked.
  254  */
  255 void
  256 vm_object_deallocate(object)
  257         vm_object_t object;
  258 {
  259         vm_object_t temp;
  260 
  261         while (object != NULL) {
  262 
  263                 if (object->ref_count == 0)
  264                         panic("vm_object_deallocate: object deallocated too many times");
  265 
  266                 /*
  267                  * Lose the reference
  268                  */
  269                 object->ref_count--;
  270                 if (object->ref_count != 0) {
  271                         if ((object->ref_count == 1) &&
  272                             (object->handle == NULL) &&
  273                             (object->type == OBJT_DEFAULT ||
  274                              object->type == OBJT_SWAP)) {
  275                                 vm_object_t robject;
  276                                 robject = TAILQ_FIRST(&object->shadow_head);
  277                                 if ((robject != NULL) &&
  278                                     (robject->handle == NULL) &&
  279                                     (robject->type == OBJT_DEFAULT ||
  280                                      robject->type == OBJT_SWAP)) {
  281                                         int s;
  282                                         robject->ref_count += 2;
  283                                         object->ref_count += 2;
  284 
  285                                         do {
  286                                                 s = splvm();
  287                                                 while (robject->paging_in_progress) {
  288                                                         robject->flags |= OBJ_PIPWNT;
  289                                                         tsleep(robject, PVM, "objde1", 0);
  290                                                 }
  291 
  292                                                 while (object->paging_in_progress) {
  293                                                         object->flags |= OBJ_PIPWNT;
  294                                                         tsleep(object, PVM, "objde2", 0);
  295                                                 }
  296                                                 splx(s);
  297 
  298                                         } while( object->paging_in_progress || robject->paging_in_progress);
  299 
  300                                         object->ref_count -= 2;
  301                                         robject->ref_count -= 2;
  302                                         if( robject->ref_count == 0) {
  303                                                 robject->ref_count += 1;
  304                                                 object = robject;
  305                                                 continue;
  306                                         }
  307                                         vm_object_collapse(robject);
  308                                         return;
  309                                 }
  310                         }
  311                         /*
  312                          * If there are still references, then we are done.
  313                          */
  314                         return;
  315                 }
  316 
  317                 if (object->type == OBJT_VNODE) {
  318                         struct vnode *vp = object->handle;
  319 
  320                         vp->v_flag &= ~VTEXT;
  321                 }
  322 
  323                 /*
  324                  * See if this object can persist and has some resident
  325                  * pages.  If so, enter it in the cache.
  326                  */
  327                 if (object->flags & OBJ_CANPERSIST) {
  328                         if (object->resident_page_count != 0) {
  329 #if 0
  330                                 vm_object_page_clean(object, 0, 0 ,TRUE, TRUE);
  331 #endif
  332                                 TAILQ_INSERT_TAIL(&vm_object_cached_list, object,
  333                                     cached_list);
  334                                 vm_object_cached++;
  335 
  336                                 vm_object_cache_trim();
  337                                 return;
  338                         } else {
  339                                 object->flags &= ~OBJ_CANPERSIST;
  340                         }
  341                 }
  342 
  343                 /*
  344                  * Make sure no one uses us.
  345                  */
  346                 object->flags |= OBJ_DEAD;
  347 
  348                 temp = object->backing_object;
  349                 if (temp) {
  350                         TAILQ_REMOVE(&temp->shadow_head, object, shadow_list);
  351                         --temp->shadow_count;
  352                 }
  353                 vm_object_terminate(object);
  354                 /* unlocks and deallocates object */
  355                 object = temp;
  356         }
  357 }
  358 
  359 /*
  360  *      vm_object_terminate actually destroys the specified object, freeing
  361  *      up all previously used resources.
  362  *
  363  *      The object must be locked.
  364  */
  365 static void
  366 vm_object_terminate(object)
  367         register vm_object_t object;
  368 {
  369         register vm_page_t p;
  370         int s;
  371 
  372         /*
  373          * wait for the pageout daemon to be done with the object
  374          */
  375         s = splvm();
  376         while (object->paging_in_progress) {
  377                 object->flags |= OBJ_PIPWNT;
  378                 tsleep(object, PVM, "objtrm", 0);
  379         }
  380         splx(s);
  381 
  382         if (object->paging_in_progress != 0)
  383                 panic("vm_object_deallocate: pageout in progress");
  384 
  385         /*
  386          * Clean and free the pages, as appropriate. All references to the
  387          * object are gone, so we don't need to lock it.
  388          */
  389         if (object->type == OBJT_VNODE) {
  390                 struct vnode *vp = object->handle;
  391                 int waslocked;
  392 
  393                 waslocked = VOP_ISLOCKED(vp);
  394                 if (!waslocked)
  395                         VOP_LOCK(vp);
  396                 vm_object_page_clean(object, 0, 0, TRUE, FALSE);
  397                 vinvalbuf(vp, V_SAVE, NOCRED, NULL, 0, 0);
  398                 if (!waslocked)
  399                         VOP_UNLOCK(vp);
  400         } 
  401         /*
  402          * Now free the pages. For internal objects, this also removes them
  403          * from paging queues.
  404          */
  405         while ((p = TAILQ_FIRST(&object->memq)) != NULL) {
  406                 if (p->busy || (p->flags & PG_BUSY))
  407                         printf("vm_object_terminate: freeing busy page\n");
  408                 PAGE_WAKEUP(p);
  409                 vm_page_free(p);
  410                 cnt.v_pfree++;
  411         }
  412 
  413         /*
  414          * Let the pager know object is dead.
  415          */
  416         vm_pager_deallocate(object);
  417 
  418         TAILQ_REMOVE(&vm_object_list, object, object_list);
  419         vm_object_count--;
  420 
  421         wakeup(object);
  422 
  423         /*
  424          * Free the space for the object.
  425          */
  426         free((caddr_t) object, M_VMOBJ);
  427 }
  428 
  429 /*
  430  *      vm_object_page_clean
  431  *
  432  *      Clean all dirty pages in the specified range of object.
  433  *      Leaves page on whatever queue it is currently on.
  434  *
  435  *      Odd semantics: if start == end, we clean everything.
  436  *
  437  *      The object must be locked.
  438  */
  439 
  440 void
  441 vm_object_page_clean(object, start, end, syncio, lockflag)
  442         vm_object_t object;
  443         vm_pindex_t start;
  444         vm_pindex_t end;
  445         boolean_t syncio;
  446         boolean_t lockflag;
  447 {
  448         register vm_page_t p, np, tp;
  449         register vm_offset_t tstart, tend;
  450         vm_pindex_t pi;
  451         int s;
  452         struct vnode *vp;
  453         int runlen;
  454         int maxf;
  455         int chkb;
  456         int maxb;
  457         int i;
  458         vm_page_t maf[vm_pageout_page_count];
  459         vm_page_t mab[vm_pageout_page_count];
  460         vm_page_t ma[vm_pageout_page_count];
  461 
  462         if (object->type != OBJT_VNODE ||
  463                 (object->flags & OBJ_MIGHTBEDIRTY) == 0)
  464                 return;
  465 
  466         vp = object->handle;
  467 
  468         if (lockflag)
  469                 VOP_LOCK(vp);
  470         object->flags |= OBJ_CLEANING;
  471 
  472         tstart = start;
  473         if (end == 0) {
  474                 tend = object->size;
  475         } else {
  476                 tend = end;
  477         }
  478         if ((tstart == 0) && (tend == object->size)) {
  479                 object->flags &= ~(OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY);
  480         }
  481         for(p = TAILQ_FIRST(&object->memq); p; p = TAILQ_NEXT(p, listq))
  482                 p->flags |= PG_CLEANCHK;
  483 
  484 rescan:
  485         for(p = TAILQ_FIRST(&object->memq); p; p = np) {
  486                 np = TAILQ_NEXT(p, listq);
  487 
  488                 pi = p->pindex;
  489                 if (((p->flags & PG_CLEANCHK) == 0) ||
  490                         (pi < tstart) || (pi >= tend) ||
  491                         (p->valid == 0) ||
  492                         ((p->queue - p->pc) == PQ_CACHE)) {
  493                         p->flags &= ~PG_CLEANCHK;
  494                         continue;
  495                 }
  496 
  497                 vm_page_test_dirty(p);
  498                 if ((p->dirty & p->valid) == 0) {
  499                         p->flags &= ~PG_CLEANCHK;
  500                         continue;
  501                 }
  502 
  503                 s = splvm();
  504                 if ((p->flags & PG_BUSY) || p->busy) {
  505                         p->flags |= PG_WANTED|PG_REFERENCED;
  506                         tsleep(p, PVM, "vpcwai", 0);
  507                         splx(s);
  508                         goto rescan;
  509                 }
  510                 splx(s);
  511                         
  512                 s = splvm();
  513                 maxf = 0;
  514                 for(i=1;i<vm_pageout_page_count;i++) {
  515                         if (tp = vm_page_lookup(object, pi + i)) {
  516                                 if ((tp->flags & PG_BUSY) ||
  517                                         (tp->flags & PG_CLEANCHK) == 0)
  518                                         break;
  519                                 if((tp->queue - tp->pc) == PQ_CACHE) {
  520                                         tp->flags &= ~PG_CLEANCHK;
  521                                         break;
  522                                 }
  523                                 vm_page_test_dirty(tp);
  524                                 if ((tp->dirty & tp->valid) == 0) {
  525                                         tp->flags &= ~PG_CLEANCHK;
  526                                         break;
  527                                 }
  528                                 maf[ i - 1 ] = tp;
  529                                 maxf++;
  530                                 continue;
  531                         }
  532                         break;
  533                 }
  534 
  535                 maxb = 0;
  536                 chkb = vm_pageout_page_count -  maxf;
  537                 if (chkb) {
  538                         for(i = 1; i < chkb;i++) {
  539                                 if (tp = vm_page_lookup(object, pi - i)) {
  540                                         if ((tp->flags & PG_BUSY) ||
  541                                                 (tp->flags & PG_CLEANCHK) == 0)
  542                                                 break;
  543                                         if((tp->queue - tp->pc) == PQ_CACHE) {
  544                                                 tp->flags &= ~PG_CLEANCHK;
  545                                                 break;
  546                                         }
  547                                         vm_page_test_dirty(tp);
  548                                         if ((tp->dirty & tp->valid) == 0) {
  549                                                 tp->flags &= ~PG_CLEANCHK;
  550                                                 break;
  551                                         }
  552                                         mab[ i - 1 ] = tp;
  553                                         maxb++;
  554                                         continue;
  555                                 }
  556                                 break;
  557                         }
  558                 }
  559 
  560                 for(i=0;i<maxb;i++) {
  561                         int index = (maxb - i) - 1;
  562                         ma[index] = mab[i];
  563                         ma[index]->flags |= PG_BUSY;
  564                         ma[index]->flags &= ~PG_CLEANCHK;
  565                         vm_page_protect(ma[index], VM_PROT_READ);
  566                 }
  567                 vm_page_protect(p, VM_PROT_READ);
  568                 p->flags |= PG_BUSY;
  569                 p->flags &= ~PG_CLEANCHK;
  570                 ma[maxb] = p;
  571                 for(i=0;i<maxf;i++) {
  572                         int index = (maxb + i) + 1;
  573                         ma[index] = maf[i];
  574                         ma[index]->flags |= PG_BUSY;
  575                         ma[index]->flags &= ~PG_CLEANCHK;
  576                         vm_page_protect(ma[index], VM_PROT_READ);
  577                 }
  578                 runlen = maxb + maxf + 1;
  579                 splx(s);
  580                 vm_pageout_flush(ma, runlen, 0);
  581                 goto rescan;
  582         }
  583 
  584         VOP_FSYNC(vp, NULL, syncio, curproc);
  585 
  586         if (lockflag)
  587                 VOP_UNLOCK(vp);
  588         object->flags &= ~OBJ_CLEANING;
  589         return;
  590 }
  591 
  592 #ifdef not_used
  593 /* XXX I cannot tell if this should be an exported symbol */
  594 /*
  595  *      vm_object_deactivate_pages
  596  *
  597  *      Deactivate all pages in the specified object.  (Keep its pages
  598  *      in memory even though it is no longer referenced.)
  599  *
  600  *      The object must be locked.
  601  */
  602 static void
  603 vm_object_deactivate_pages(object)
  604         register vm_object_t object;
  605 {
  606         register vm_page_t p, next;
  607 
  608         for (p = TAILQ_FIRST(&object->memq); p != NULL; p = next) {
  609                 next = TAILQ_NEXT(p, listq);
  610                 vm_page_deactivate(p);
  611         }
  612 }
  613 #endif
  614 
  615 /*
  616  *      Trim the object cache to size.
  617  */
  618 static void
  619 vm_object_cache_trim()
  620 {
  621         register vm_object_t object;
  622 
  623         while (vm_object_cached > vm_object_cache_max) {
  624                 object = TAILQ_FIRST(&vm_object_cached_list);
  625 
  626                 vm_object_reference(object);
  627                 pager_cache(object, FALSE);
  628         }
  629 }
  630 
  631 
  632 /*
  633  *      vm_object_pmap_copy:
  634  *
  635  *      Makes all physical pages in the specified
  636  *      object range copy-on-write.  No writeable
  637  *      references to these pages should remain.
  638  *
  639  *      The object must *not* be locked.
  640  */
  641 void
  642 vm_object_pmap_copy(object, start, end)
  643         register vm_object_t object;
  644         register vm_pindex_t start;
  645         register vm_pindex_t end;
  646 {
  647         register vm_page_t p;
  648 
  649         if (object == NULL || (object->flags & OBJ_WRITEABLE) == 0)
  650                 return;
  651 
  652         for (p = TAILQ_FIRST(&object->memq);
  653                 p != NULL;
  654                 p = TAILQ_NEXT(p, listq)) {
  655                 vm_page_protect(p, VM_PROT_READ);
  656         }
  657 
  658         object->flags &= ~OBJ_WRITEABLE;
  659 }
  660 
  661 /*
  662  *      vm_object_pmap_remove:
  663  *
  664  *      Removes all physical pages in the specified
  665  *      object range from all physical maps.
  666  *
  667  *      The object must *not* be locked.
  668  */
  669 void
  670 vm_object_pmap_remove(object, start, end)
  671         register vm_object_t object;
  672         register vm_pindex_t start;
  673         register vm_pindex_t end;
  674 {
  675         register vm_page_t p;
  676         if (object == NULL)
  677                 return;
  678         for (p = TAILQ_FIRST(&object->memq);
  679                 p != NULL;
  680                 p = TAILQ_NEXT(p, listq)) {
  681                 if (p->pindex >= start && p->pindex < end)
  682                         vm_page_protect(p, VM_PROT_NONE);
  683         }
  684         if ((start == 0) && (object->size == end))
  685                 object->flags &= ~OBJ_WRITEABLE;
  686 }
  687 
  688 /*
  689  *      vm_object_madvise:
  690  *
  691  *      Implements the madvise function at the object/page level.
  692  */
  693 void
  694 vm_object_madvise(object, pindex, count, advise)
  695         vm_object_t object;
  696         vm_pindex_t pindex;
  697         int count;
  698         int advise;
  699 {
  700         int s;
  701         vm_pindex_t end, tpindex;
  702         vm_object_t tobject;
  703         vm_page_t m;
  704 
  705         if (object == NULL)
  706                 return;
  707 
  708         end = pindex + count;
  709 
  710         for (; pindex < end; pindex += 1) {
  711 
  712 relookup:
  713                 tobject = object;
  714                 tpindex = pindex;
  715 shadowlookup:
  716                 m = vm_page_lookup(tobject, tpindex);
  717                 if (m == NULL) {
  718                         if (tobject->type != OBJT_DEFAULT) {
  719                                 continue;
  720                         }
  721                                 
  722                         tobject = tobject->backing_object;
  723                         if ((tobject == NULL) || (tobject->ref_count != 1)) {
  724                                 continue;
  725                         }
  726                         tpindex += OFF_TO_IDX(tobject->backing_object_offset);
  727                         goto shadowlookup;
  728                 }
  729 
  730                 /*
  731                  * If the page is busy or not in a normal active state,
  732                  * we skip it.  Things can break if we mess with pages
  733                  * in any of the below states.
  734                  */
  735                 if (m->hold_count || m->wire_count ||
  736                         m->valid != VM_PAGE_BITS_ALL) {
  737                         continue;
  738                 }
  739 
  740                 if (m->busy || (m->flags & PG_BUSY)) {
  741                         s = splvm();
  742                         if (m->busy || (m->flags & PG_BUSY)) {
  743                                 m->flags |= PG_WANTED;
  744                                 tsleep(m, PVM, "madvpw", 0);
  745                         }
  746                         splx(s);
  747                         goto relookup;
  748                 }
  749 
  750                 if (advise == MADV_WILLNEED) {
  751                         if (m->queue != PQ_ACTIVE)
  752                                 vm_page_activate(m);
  753                 } else if (advise == MADV_DONTNEED) {
  754                         vm_page_deactivate(m);
  755                 } else if (advise == MADV_FREE) {
  756                         pmap_clear_modify(VM_PAGE_TO_PHYS(m));
  757                         m->dirty = 0;
  758                         /*
  759                          * Force a demand zero if attempt to read from swap.
  760                          * We currently don't handle vnode files correctly,
  761                          * and will reread stale contents unnecessarily.
  762                          */
  763                         if (object->type == OBJT_SWAP)
  764                                 swap_pager_dmzspace(tobject, m->pindex, 1);
  765                 }
  766         }       
  767 }
  768 
  769 /*
  770  *      vm_object_shadow:
  771  *
  772  *      Create a new object which is backed by the
  773  *      specified existing object range.  The source
  774  *      object reference is deallocated.
  775  *
  776  *      The new object and offset into that object
  777  *      are returned in the source parameters.
  778  */
  779 
  780 void
  781 vm_object_shadow(object, offset, length)
  782         vm_object_t *object;    /* IN/OUT */
  783         vm_ooffset_t *offset;   /* IN/OUT */
  784         vm_size_t length;
  785 {
  786         register vm_object_t source;
  787         register vm_object_t result;
  788 
  789         source = *object;
  790 
  791         /*
  792          * Allocate a new object with the given length
  793          */
  794 
  795         if ((result = vm_object_allocate(OBJT_DEFAULT, length)) == NULL)
  796                 panic("vm_object_shadow: no object for shadowing");
  797 
  798         /*
  799          * The new object shadows the source object, adding a reference to it.
  800          * Our caller changes his reference to point to the new object,
  801          * removing a reference to the source object.  Net result: no change
  802          * of reference count.
  803          */
  804         result->backing_object = source;
  805         if (source) {
  806                 TAILQ_INSERT_TAIL(&source->shadow_head, result, shadow_list);
  807                 ++source->shadow_count;
  808         }
  809 
  810         /*
  811          * Store the offset into the source object, and fix up the offset into
  812          * the new object.
  813          */
  814 
  815         result->backing_object_offset = *offset;
  816 
  817         /*
  818          * Return the new things
  819          */
  820 
  821         *offset = 0;
  822         *object = result;
  823 }
  824 
  825 
  826 /*
  827  * this version of collapse allows the operation to occur earlier and
  828  * when paging_in_progress is true for an object...  This is not a complete
  829  * operation, but should plug 99.9% of the rest of the leaks.
  830  */
  831 static void
  832 vm_object_qcollapse(object)
  833         register vm_object_t object;
  834 {
  835         register vm_object_t backing_object;
  836         register vm_pindex_t backing_offset_index, paging_offset_index;
  837         vm_pindex_t backing_object_paging_offset_index;
  838         vm_pindex_t new_pindex;
  839         register vm_page_t p, pp;
  840         register vm_size_t size;
  841 
  842         backing_object = object->backing_object;
  843         if (backing_object->ref_count != 1)
  844                 return;
  845 
  846         backing_object->ref_count += 2;
  847 
  848         backing_offset_index = OFF_TO_IDX(object->backing_object_offset);
  849         backing_object_paging_offset_index = OFF_TO_IDX(backing_object->paging_offset);
  850         paging_offset_index = OFF_TO_IDX(object->paging_offset);
  851         size = object->size;
  852         p = TAILQ_FIRST(&backing_object->memq);
  853         while (p) {
  854                 vm_page_t next;
  855 
  856                 next = TAILQ_NEXT(p, listq);
  857                 if ((p->flags & (PG_BUSY | PG_FICTITIOUS)) ||
  858                     ((p->queue - p->pc) == PQ_CACHE) ||
  859                     !p->valid || p->hold_count || p->wire_count || p->busy) {
  860                         p = next;
  861                         continue;
  862                 }
  863                 new_pindex = p->pindex - backing_offset_index;
  864                 if (p->pindex < backing_offset_index ||
  865                     new_pindex >= size) {
  866                         if (backing_object->type == OBJT_SWAP)
  867                                 swap_pager_freespace(backing_object,
  868                                     backing_object_paging_offset_index+p->pindex,
  869                                     1);
  870                         vm_page_protect(p, VM_PROT_NONE);
  871                         vm_page_free(p);
  872                 } else {
  873                         pp = vm_page_lookup(object, new_pindex);
  874                         if (pp != NULL || (object->type == OBJT_SWAP && vm_pager_has_page(object,
  875                                     paging_offset_index + new_pindex, NULL, NULL))) {
  876                                 if (backing_object->type == OBJT_SWAP)
  877                                         swap_pager_freespace(backing_object,
  878                                             backing_object_paging_offset_index + p->pindex, 1);
  879                                 vm_page_protect(p, VM_PROT_NONE);
  880                                 vm_page_free(p);
  881                         } else {
  882                                 if (backing_object->type == OBJT_SWAP)
  883                                         swap_pager_freespace(backing_object,
  884                                             backing_object_paging_offset_index + p->pindex, 1);
  885                                 vm_page_rename(p, object, new_pindex);
  886                                 vm_page_protect(p, VM_PROT_NONE);
  887                                 p->dirty = VM_PAGE_BITS_ALL;
  888                         }
  889                 }
  890                 p = next;
  891         }
  892         backing_object->ref_count -= 2;
  893 }
  894 
  895 /*
  896  *      vm_object_collapse:
  897  *
  898  *      Collapse an object with the object backing it.
  899  *      Pages in the backing object are moved into the
  900  *      parent, and the backing object is deallocated.
  901  */
  902 void
  903 vm_object_collapse(object)
  904         vm_object_t object;
  905 
  906 {
  907         vm_object_t backing_object;
  908         vm_ooffset_t backing_offset;
  909         vm_size_t size;
  910         vm_pindex_t new_pindex, backing_offset_index;
  911         vm_page_t p, pp;
  912 
  913         while (TRUE) {
  914                 /*
  915                  * Verify that the conditions are right for collapse:
  916                  *
  917                  * The object exists and no pages in it are currently being paged
  918                  * out.
  919                  */
  920                 if (object == NULL)
  921                         return;
  922 
  923                 /*
  924                  * Make sure there is a backing object.
  925                  */
  926                 if ((backing_object = object->backing_object) == NULL)
  927                         return;
  928 
  929                 /*
  930                  * we check the backing object first, because it is most likely
  931                  * not collapsable.
  932                  */
  933                 if (backing_object->handle != NULL ||
  934                     (backing_object->type != OBJT_DEFAULT &&
  935                      backing_object->type != OBJT_SWAP) ||
  936                     (backing_object->flags & OBJ_DEAD) ||
  937                     object->handle != NULL ||
  938                     (object->type != OBJT_DEFAULT &&
  939                      object->type != OBJT_SWAP) ||
  940                     (object->flags & OBJ_DEAD)) {
  941                         return;
  942                 }
  943 
  944                 if (object->paging_in_progress != 0 ||
  945                     backing_object->paging_in_progress != 0) {
  946                         vm_object_qcollapse(object);
  947                         return;
  948                 }
  949 
  950                 /*
  951                  * We know that we can either collapse the backing object (if
  952                  * the parent is the only reference to it) or (perhaps) remove
  953                  * the parent's reference to it.
  954                  */
  955 
  956                 backing_offset = object->backing_object_offset;
  957                 backing_offset_index = OFF_TO_IDX(backing_offset);
  958                 size = object->size;
  959 
  960                 /*
  961                  * If there is exactly one reference to the backing object, we
  962                  * can collapse it into the parent.
  963                  */
  964 
  965                 if (backing_object->ref_count == 1) {
  966 
  967                         backing_object->flags |= OBJ_DEAD;
  968                         /*
  969                          * We can collapse the backing object.
  970                          *
  971                          * Move all in-memory pages from backing_object to the
  972                          * parent.  Pages that have been paged out will be
  973                          * overwritten by any of the parent's pages that
  974                          * shadow them.
  975                          */
  976 
  977                         while ((p = TAILQ_FIRST(&backing_object->memq)) != 0) {
  978 
  979                                 new_pindex = p->pindex - backing_offset_index;
  980 
  981                                 /*
  982                                  * If the parent has a page here, or if this
  983                                  * page falls outside the parent, dispose of
  984                                  * it.
  985                                  *
  986                                  * Otherwise, move it as planned.
  987                                  */
  988 
  989                                 if (p->pindex < backing_offset_index ||
  990                                     new_pindex >= size) {
  991                                         vm_page_protect(p, VM_PROT_NONE);
  992                                         PAGE_WAKEUP(p);
  993                                         vm_page_free(p);
  994                                 } else {
  995                                         pp = vm_page_lookup(object, new_pindex);
  996                                         if (pp != NULL || (object->type == OBJT_SWAP && vm_pager_has_page(object,
  997                                             OFF_TO_IDX(object->paging_offset) + new_pindex, NULL, NULL))) {
  998                                                 vm_page_protect(p, VM_PROT_NONE);
  999                                                 PAGE_WAKEUP(p);
 1000                                                 vm_page_free(p);
 1001                                         } else {
 1002                                                 vm_page_protect(p, VM_PROT_NONE);
 1003                                                 vm_page_rename(p, object, new_pindex);
 1004                                                 p->dirty = VM_PAGE_BITS_ALL;
 1005                                         }
 1006                                 }
 1007                         }
 1008 
 1009                         /*
 1010                          * Move the pager from backing_object to object.
 1011                          */
 1012 
 1013                         if (backing_object->type == OBJT_SWAP) {
 1014                                 backing_object->paging_in_progress++;
 1015                                 if (object->type == OBJT_SWAP) {
 1016                                         object->paging_in_progress++;
 1017                                         /*
 1018                                          * copy shadow object pages into ours
 1019                                          * and destroy unneeded pages in
 1020                                          * shadow object.
 1021                                          */
 1022                                         swap_pager_copy(
 1023                                             backing_object,
 1024                                             OFF_TO_IDX(backing_object->paging_offset),
 1025                                             object,
 1026                                             OFF_TO_IDX(object->paging_offset),
 1027                                             OFF_TO_IDX(object->backing_object_offset));
 1028                                         vm_object_pip_wakeup(object);
 1029                                 } else {
 1030                                         object->paging_in_progress++;
 1031                                         /*
 1032                                          * move the shadow backing_object's pager data to
 1033                                          * "object" and convert "object" type to OBJT_SWAP.
 1034                                          */
 1035                                         object->type = OBJT_SWAP;
 1036                                         object->un_pager.swp.swp_nblocks =
 1037                                             backing_object->un_pager.swp.swp_nblocks;
 1038                                         object->un_pager.swp.swp_allocsize =
 1039                                             backing_object->un_pager.swp.swp_allocsize;
 1040                                         object->un_pager.swp.swp_blocks =
 1041                                             backing_object->un_pager.swp.swp_blocks;
 1042                                         object->un_pager.swp.swp_poip =         /* XXX */
 1043                                             backing_object->un_pager.swp.swp_poip;
 1044                                         object->paging_offset = backing_object->paging_offset + backing_offset;
 1045                                         TAILQ_INSERT_TAIL(&swap_pager_un_object_list, object, pager_object_list);
 1046 
 1047                                         /*
 1048                                          * Convert backing object from OBJT_SWAP to
 1049                                          * OBJT_DEFAULT. XXX - only the TAILQ_REMOVE is
 1050                                          * actually necessary.
 1051                                          */
 1052                                         backing_object->type = OBJT_DEFAULT;
 1053                                         TAILQ_REMOVE(&swap_pager_un_object_list, backing_object, pager_object_list);
 1054                                         /*
 1055                                          * free unnecessary blocks
 1056                                          */
 1057                                         swap_pager_freespace(object, 0,
 1058                                                 OFF_TO_IDX(object->paging_offset));
 1059                                         vm_object_pip_wakeup(object);
 1060                                 }
 1061 
 1062                                 vm_object_pip_wakeup(backing_object);
 1063                         }
 1064                         /*
 1065                          * Object now shadows whatever backing_object did.
 1066                          * Note that the reference to backing_object->backing_object
 1067                          * moves from within backing_object to within object.
 1068                          */
 1069 
 1070                         TAILQ_REMOVE(&object->backing_object->shadow_head, object,
 1071                             shadow_list);
 1072                         --object->backing_object->shadow_count;
 1073                         if (backing_object->backing_object) {
 1074                                 TAILQ_REMOVE(&backing_object->backing_object->shadow_head,
 1075                                     backing_object, shadow_list);
 1076                                 --backing_object->backing_object->shadow_count;
 1077                         }
 1078                         object->backing_object = backing_object->backing_object;
 1079                         if (object->backing_object) {
 1080                                 TAILQ_INSERT_TAIL(&object->backing_object->shadow_head,
 1081                                     object, shadow_list);
 1082                                 ++object->backing_object->shadow_count;
 1083                         }
 1084 
 1085                         object->backing_object_offset += backing_object->backing_object_offset;
 1086                         /*
 1087                          * Discard backing_object.
 1088                          *
 1089                          * Since the backing object has no pages, no pager left,
 1090                          * and no object references within it, all that is
 1091                          * necessary is to dispose of it.
 1092                          */
 1093 
 1094                         TAILQ_REMOVE(&vm_object_list, backing_object,
 1095                             object_list);
 1096                         vm_object_count--;
 1097 
 1098                         free((caddr_t) backing_object, M_VMOBJ);
 1099 
 1100                         object_collapses++;
 1101                 } else {
 1102                         /*
 1103                          * If all of the pages in the backing object are
 1104                          * shadowed by the parent object, the parent object no
 1105                          * longer has to shadow the backing object; it can
 1106                          * shadow the next one in the chain.
 1107                          *
 1108                          * The backing object must not be paged out - we'd have
 1109                          * to check all of the paged-out pages, as well.
 1110                          */
 1111 
 1112                         if (backing_object->type != OBJT_DEFAULT) {
 1113                                 return;
 1114                         }
 1115                         /*
 1116                          * Should have a check for a 'small' number of pages
 1117                          * here.
 1118                          */
 1119 
 1120                         for (p = TAILQ_FIRST(&backing_object->memq); p; p = TAILQ_NEXT(p, listq)) {
 1121                                 new_pindex = p->pindex - backing_offset_index;
 1122 
 1123                                 /*
 1124                                  * If the parent has a page here, or if this
 1125                                  * page falls outside the parent, keep going.
 1126                                  *
 1127                                  * Otherwise, the backing_object must be left in
 1128                                  * the chain.
 1129                                  */
 1130 
 1131                                 if (p->pindex >= backing_offset_index &&
 1132                                         new_pindex <= size) {
 1133 
 1134                                         pp = vm_page_lookup(object, new_pindex);
 1135 
 1136                                         if ((pp == NULL || pp->valid == 0) &&
 1137                                             !vm_pager_has_page(object, OFF_TO_IDX(object->paging_offset) + new_pindex, NULL, NULL)) {
 1138                                                 /*
 1139                                                  * Page still needed. Can't go any
 1140                                                  * further.
 1141                                                  */
 1142                                                 return;
 1143                                         }
 1144                                 }
 1145                         }
 1146 
 1147                         /*
 1148                          * Make the parent shadow the next object in the
 1149                          * chain.  Deallocating backing_object will not remove
 1150                          * it, since its reference count is at least 2.
 1151                          */
 1152 
 1153                         TAILQ_REMOVE(&object->backing_object->shadow_head,
 1154                             object, shadow_list);
 1155                         --object->backing_object->shadow_count;
 1156                         vm_object_reference(object->backing_object = backing_object->backing_object);
 1157                         if (object->backing_object) {
 1158                                 TAILQ_INSERT_TAIL(&object->backing_object->shadow_head,
 1159                                     object, shadow_list);
 1160                                 ++object->backing_object->shadow_count;
 1161                         }
 1162                         object->backing_object_offset += backing_object->backing_object_offset;
 1163 
 1164                         /*
 1165                          * Drop the reference count on backing_object. Since
 1166                          * its ref_count was at least 2, it will not vanish;
 1167                          * so we don't need to call vm_object_deallocate.
 1168                          */
 1169                         if (backing_object->ref_count == 1)
 1170                                 printf("should have called obj deallocate\n");
 1171                         backing_object->ref_count--;
 1172 
 1173                         object_bypasses++;
 1174 
 1175                 }
 1176 
 1177                 /*
 1178                  * Try again with this object's new backing object.
 1179                  */
 1180         }
 1181 }
 1182 
 1183 /*
 1184  *      vm_object_page_remove: [internal]
 1185  *
 1186  *      Removes all physical pages in the specified
 1187  *      object range from the object's list of pages.
 1188  *
 1189  *      The object must be locked.
 1190  */
 1191 void
 1192 vm_object_page_remove(object, start, end, clean_only)
 1193         register vm_object_t object;
 1194         register vm_pindex_t start;
 1195         register vm_pindex_t end;
 1196         boolean_t clean_only;
 1197 {
 1198         register vm_page_t p, next;
 1199         unsigned int size;
 1200         int s;
 1201 
 1202         if (object == NULL)
 1203                 return;
 1204 
 1205         object->paging_in_progress++;
 1206 again:
 1207         size = end - start;
 1208         if (size > 4 || size >= object->size / 4) {
 1209                 for (p = TAILQ_FIRST(&object->memq); p != NULL; p = next) {
 1210                         next = TAILQ_NEXT(p, listq);
 1211                         if ((start <= p->pindex) && (p->pindex < end)) {
 1212                                 if (p->wire_count != 0) {
 1213                                         vm_page_protect(p, VM_PROT_NONE);
 1214                                         p->valid = 0;
 1215                                         continue;
 1216                                 }
 1217 
 1218                                 /*
 1219                                  * The busy flags are only cleared at
 1220                                  * interrupt -- minimize the spl transitions
 1221                                  */
 1222                                 if ((p->flags & PG_BUSY) || p->busy) {
 1223                                         s = splvm();
 1224                                         if ((p->flags & PG_BUSY) || p->busy) {
 1225                                                 p->flags |= PG_WANTED;
 1226                                                 tsleep(p, PVM, "vmopar", 0);
 1227                                                 splx(s);
 1228                                                 goto again;
 1229                                         }
 1230                                         splx(s);
 1231                                 }
 1232 
 1233                                 if (clean_only) {
 1234                                         vm_page_test_dirty(p);
 1235                                         if (p->valid & p->dirty)
 1236                                                 continue;
 1237                                 }
 1238                                 vm_page_protect(p, VM_PROT_NONE);
 1239                                 PAGE_WAKEUP(p);
 1240                                 vm_page_free(p);
 1241                         }
 1242                 }
 1243         } else {
 1244                 while (size > 0) {
 1245                         if ((p = vm_page_lookup(object, start)) != 0) {
 1246                                 if (p->wire_count != 0) {
 1247                                         p->valid = 0;
 1248                                         vm_page_protect(p, VM_PROT_NONE);
 1249                                         start += 1;
 1250                                         size -= 1;
 1251                                         continue;
 1252                                 }
 1253                                 /*
 1254                                  * The busy flags are only cleared at
 1255                                  * interrupt -- minimize the spl transitions
 1256                                  */
 1257                                 if ((p->flags & PG_BUSY) || p->busy) {
 1258                                         s = splvm();
 1259                                         if ((p->flags & PG_BUSY) || p->busy) {
 1260                                                 p->flags |= PG_WANTED;
 1261                                                 tsleep(p, PVM, "vmopar", 0);
 1262                                                 splx(s);
 1263                                                 goto again;
 1264                                         }
 1265                                         splx(s);
 1266                                 }
 1267                                 if (clean_only) {
 1268                                         vm_page_test_dirty(p);
 1269                                         if (p->valid & p->dirty) {
 1270                                                 start += 1;
 1271                                                 size -= 1;
 1272                                                 continue;
 1273                                         }
 1274                                 }
 1275                                 vm_page_protect(p, VM_PROT_NONE);
 1276                                 PAGE_WAKEUP(p);
 1277                                 vm_page_free(p);
 1278                         }
 1279                         start += 1;
 1280                         size -= 1;
 1281                 }
 1282         }
 1283         vm_object_pip_wakeup(object);
 1284 }
 1285 
 1286 /*
 1287  *      Routine:        vm_object_coalesce
 1288  *      Function:       Coalesces two objects backing up adjoining
 1289  *                      regions of memory into a single object.
 1290  *
 1291  *      returns TRUE if objects were combined.
 1292  *
 1293  *      NOTE:   Only works at the moment if the second object is NULL -
 1294  *              if it's not, which object do we lock first?
 1295  *
 1296  *      Parameters:
 1297  *              prev_object     First object to coalesce
 1298  *              prev_offset     Offset into prev_object
 1299  *              next_object     Second object into coalesce
 1300  *              next_offset     Offset into next_object
 1301  *
 1302  *              prev_size       Size of reference to prev_object
 1303  *              next_size       Size of reference to next_object
 1304  *
 1305  *      Conditions:
 1306  *      The object must *not* be locked.
 1307  */
 1308 boolean_t
 1309 vm_object_coalesce(prev_object, prev_pindex, prev_size, next_size)
 1310         register vm_object_t prev_object;
 1311         vm_pindex_t prev_pindex;
 1312         vm_size_t prev_size, next_size;
 1313 {
 1314         vm_size_t newsize;
 1315 
 1316         if (prev_object == NULL) {
 1317                 return (TRUE);
 1318         }
 1319 
 1320         if (prev_object->type != OBJT_DEFAULT) {
 1321                 return (FALSE);
 1322         }
 1323 
 1324         /*
 1325          * Try to collapse the object first
 1326          */
 1327         vm_object_collapse(prev_object);
 1328 
 1329         /*
 1330          * Can't coalesce if: . more than one reference . paged out . shadows
 1331          * another object . has a copy elsewhere (any of which mean that the
 1332          * pages not mapped to prev_entry may be in use anyway)
 1333          */
 1334 
 1335         if (prev_object->backing_object != NULL) {
 1336                 return (FALSE);
 1337         }
 1338 
 1339         prev_size >>= PAGE_SHIFT;
 1340         next_size >>= PAGE_SHIFT;
 1341 
 1342         if ((prev_object->ref_count > 1) &&
 1343             (prev_object->size != prev_pindex + prev_size)) {
 1344                 return (FALSE);
 1345         }
 1346 
 1347         /*
 1348          * Remove any pages that may still be in the object from a previous
 1349          * deallocation.
 1350          */
 1351 
 1352         vm_object_page_remove(prev_object,
 1353             prev_pindex + prev_size,
 1354             prev_pindex + prev_size + next_size, FALSE);
 1355 
 1356         /*
 1357          * Extend the object if necessary.
 1358          */
 1359         newsize = prev_pindex + prev_size + next_size;
 1360         if (newsize > prev_object->size)
 1361                 prev_object->size = newsize;
 1362 
 1363         return (TRUE);
 1364 }
 1365 
 1366 #include "opt_ddb.h"
 1367 #ifdef DDB
 1368 #include <sys/kernel.h>
 1369 
 1370 #include <machine/cons.h>
 1371 
 1372 #include <ddb/ddb.h>
 1373 
 1374 static int      _vm_object_in_map __P((vm_map_t map, vm_object_t object,
 1375                                        vm_map_entry_t entry));
 1376 static int      vm_object_in_map __P((vm_object_t object));
 1377 
 1378 static int
 1379 _vm_object_in_map(map, object, entry)
 1380         vm_map_t map;
 1381         vm_object_t object;
 1382         vm_map_entry_t entry;
 1383 {
 1384         vm_map_t tmpm;
 1385         vm_map_entry_t tmpe;
 1386         vm_object_t obj;
 1387         int entcount;
 1388 
 1389         if (map == 0)
 1390                 return 0;
 1391 
 1392         if (entry == 0) {
 1393                 tmpe = map->header.next;
 1394                 entcount = map->nentries;
 1395                 while (entcount-- && (tmpe != &map->header)) {
 1396                         if( _vm_object_in_map(map, object, tmpe)) {
 1397                                 return 1;
 1398                         }
 1399                         tmpe = tmpe->next;
 1400                 }
 1401         } else if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
 1402                 tmpm = entry->object.share_map;
 1403                 tmpe = tmpm->header.next;
 1404                 entcount = tmpm->nentries;
 1405                 while (entcount-- && tmpe != &tmpm->header) {
 1406                         if( _vm_object_in_map(tmpm, object, tmpe)) {
 1407                                 return 1;
 1408                         }
 1409                         tmpe = tmpe->next;
 1410                 }
 1411         } else if (obj = entry->object.vm_object) {
 1412                 for(; obj; obj=obj->backing_object)
 1413                         if( obj == object) {
 1414                                 return 1;
 1415                         }
 1416         }
 1417         return 0;
 1418 }
 1419 
 1420 static int
 1421 vm_object_in_map( object)
 1422         vm_object_t object;
 1423 {
 1424         struct proc *p;
 1425         for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
 1426                 if( !p->p_vmspace /* || (p->p_flag & (P_SYSTEM|P_WEXIT)) */)
 1427                         continue;
 1428                 if( _vm_object_in_map(&p->p_vmspace->vm_map, object, 0))
 1429                         return 1;
 1430         }
 1431         if( _vm_object_in_map( kernel_map, object, 0))
 1432                 return 1;
 1433         if( _vm_object_in_map( kmem_map, object, 0))
 1434                 return 1;
 1435         if( _vm_object_in_map( pager_map, object, 0))
 1436                 return 1;
 1437         if( _vm_object_in_map( buffer_map, object, 0))
 1438                 return 1;
 1439         if( _vm_object_in_map( io_map, object, 0))
 1440                 return 1;
 1441         if( _vm_object_in_map( phys_map, object, 0))
 1442                 return 1;
 1443         if( _vm_object_in_map( mb_map, object, 0))
 1444                 return 1;
 1445         if( _vm_object_in_map( u_map, object, 0))
 1446                 return 1;
 1447         return 0;
 1448 }
 1449 
 1450 DB_SHOW_COMMAND(vmochk, vm_object_check)
 1451 {
 1452         vm_object_t object;
 1453 
 1454         /*
 1455          * make sure that internal objs are in a map somewhere
 1456          * and none have zero ref counts.
 1457          */
 1458         for (object = TAILQ_FIRST(&vm_object_list);
 1459                         object != NULL;
 1460                         object = TAILQ_NEXT(object, object_list)) {
 1461                 if (object->handle == NULL &&
 1462                     (object->type == OBJT_DEFAULT || object->type == OBJT_SWAP)) {
 1463                         if (object->ref_count == 0) {
 1464                                 db_printf("vmochk: internal obj has zero ref count: %d\n",
 1465                                         object->size);
 1466                         }
 1467                         if (!vm_object_in_map(object)) {
 1468                                 db_printf("vmochk: internal obj is not in a map: "
 1469                 "ref: %d, size: %d: 0x%x, backing_object: 0x%x\n",
 1470                                     object->ref_count, object->size, 
 1471                                     object->size, object->backing_object);
 1472                         }
 1473                 }
 1474         }
 1475 }
 1476 
 1477 /*
 1478  *      vm_object_print:        [ debug ]
 1479  */
 1480 DB_SHOW_COMMAND(object, vm_object_print_static)
 1481 {
 1482         /* XXX convert args. */
 1483         vm_object_t object = (vm_object_t)addr;
 1484         boolean_t full = have_addr;
 1485 
 1486         register vm_page_t p;
 1487 
 1488         /* XXX count is an (unused) arg.  Avoid shadowing it. */
 1489 #define count   was_count
 1490 
 1491         register int count;
 1492 
 1493         if (object == NULL)
 1494                 return;
 1495 
 1496         db_iprintf("Object 0x%x: size=0x%x, res=%d, ref=%d, ",
 1497             (int) object, (int) object->size,
 1498             object->resident_page_count, object->ref_count);
 1499         db_printf("offset=0x%x, backing_object=(0x%x)+0x%x\n",
 1500             (int) object->paging_offset,
 1501             (int) object->backing_object, (int) object->backing_object_offset);
 1502         db_printf("cache: next=%p, prev=%p\n",
 1503             TAILQ_NEXT(object, cached_list), TAILQ_PREV(object, object_q,
 1504                                                         cached_list));
 1505 
 1506         if (!full)
 1507                 return;
 1508 
 1509         db_indent += 2;
 1510         count = 0;
 1511         for (p = TAILQ_FIRST(&object->memq); p != NULL; p = TAILQ_NEXT(p, listq)) {
 1512                 if (count == 0)
 1513                         db_iprintf("memory:=");
 1514                 else if (count == 6) {
 1515                         db_printf("\n");
 1516                         db_iprintf(" ...");
 1517                         count = 0;
 1518                 } else
 1519                         db_printf(",");
 1520                 count++;
 1521 
 1522                 db_printf("(off=0x%lx,page=0x%lx)",
 1523                     (u_long) p->pindex, (u_long) VM_PAGE_TO_PHYS(p));
 1524         }
 1525         if (count != 0)
 1526                 db_printf("\n");
 1527         db_indent -= 2;
 1528 }
 1529 
 1530 /* XXX. */
 1531 #undef count
 1532 
 1533 /* XXX need this non-static entry for calling from vm_map_print. */
 1534 void
 1535 vm_object_print(addr, have_addr, count, modif)
 1536         db_expr_t addr;
 1537         boolean_t have_addr;
 1538         db_expr_t count;
 1539         char *modif;
 1540 {
 1541         vm_object_print_static(addr, have_addr, count, modif);
 1542 }
 1543 
 1544 DB_SHOW_COMMAND(vmopag, vm_object_print_pages)
 1545 {
 1546         vm_object_t object;
 1547         int nl = 0;
 1548         int c;
 1549         for (object = TAILQ_FIRST(&vm_object_list);
 1550                         object != NULL;
 1551                         object = TAILQ_NEXT(object, object_list)) {
 1552                 vm_pindex_t idx, fidx;
 1553                 vm_pindex_t osize;
 1554                 vm_offset_t pa = -1, padiff;
 1555                 int rcount;
 1556                 vm_page_t m;
 1557 
 1558                 db_printf("new object: 0x%x\n", object);
 1559                 if ( nl > 18) {
 1560                         c = cngetc();
 1561                         if (c != ' ')
 1562                                 return;
 1563                         nl = 0;
 1564                 }
 1565                 nl++;
 1566                 rcount = 0;
 1567                 fidx = 0;
 1568                 osize = object->size;
 1569                 if (osize > 128)
 1570                         osize = 128;
 1571                 for(idx=0;idx<osize;idx++) {
 1572                         m = vm_page_lookup(object, idx);
 1573                         if (m == NULL) {
 1574                                 if (rcount) {
 1575                                         db_printf(" index(%d)run(%d)pa(0x%x)\n",
 1576                                                 fidx, rcount, pa);
 1577                                         if ( nl > 18) {
 1578                                                 c = cngetc();
 1579                                                 if (c != ' ')
 1580                                                         return;
 1581                                                 nl = 0;
 1582                                         }
 1583                                         nl++;
 1584                                         rcount = 0;
 1585                                 }
 1586                                 continue;
 1587                         }
 1588 
 1589                                 
 1590                         if (rcount &&
 1591                                 (VM_PAGE_TO_PHYS(m) == pa + rcount * PAGE_SIZE)) {
 1592                                 ++rcount;
 1593                                 continue;
 1594                         }
 1595                         if (rcount) {
 1596                                 padiff = pa + rcount * PAGE_SIZE - VM_PAGE_TO_PHYS(m);
 1597                                 padiff >>= PAGE_SHIFT;
 1598                                 padiff &= PQ_L2_MASK;
 1599                                 if (padiff == 0) {
 1600                                         pa = VM_PAGE_TO_PHYS(m) - rcount * PAGE_SIZE;
 1601                                         ++rcount;
 1602                                         continue;
 1603                                 }
 1604                                 db_printf(" index(%d)run(%d)pa(0x%x)", fidx, rcount, pa);
 1605                                 db_printf("pd(%d)\n", padiff);
 1606                                 if ( nl > 18) {
 1607                                         c = cngetc();
 1608                                         if (c != ' ')
 1609                                                 return;
 1610                                         nl = 0;
 1611                                 }
 1612                                 nl++;
 1613                         }
 1614                         fidx = idx;
 1615                         pa = VM_PAGE_TO_PHYS(m);
 1616                         rcount = 1;
 1617                 }
 1618                 if (rcount) {
 1619                         db_printf(" index(%d)run(%d)pa(0x%x)\n", fidx, rcount, pa);
 1620                         if ( nl > 18) {
 1621                                 c = cngetc();
 1622                                 if (c != ' ')
 1623                                         return;
 1624                                 nl = 0;
 1625                         }
 1626                         nl++;
 1627                 }
 1628         }
 1629 }
 1630 #endif /* DDB */

Cache object: e8d7551bd22a8924de820593cb881652


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.