home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 15 / 15.iso / s / s053 / 9.ddi / usr / include / vm / page.h < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-08  |  9.3 KB  |  314 lines

  1. /*    Copyright (c) 1990 UNIX System Laboratories, Inc.    */
  2. /*    Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T    */
  3. /*      All Rights Reserved      */
  4.  
  5. /*    THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF         */
  6. /*    UNIX System Laboratories, Inc.                         */
  7. /*    The copyright notice above does not evidence any       */
  8. /*    actual or intended publication of such source code.    */
  9.  
  10. /*
  11.  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  12.  *         PROPRIETARY NOTICE (Combined)
  13.  * 
  14.  * This source code is unpublished proprietary information
  15.  * constituting, or derived under license from AT&T's UNIX(r) System V.
  16.  * In addition, portions of such source code were derived from Berkeley
  17.  * 4.3 BSD under license from the Regents of the University of
  18.  * California.
  19.  * 
  20.  * 
  21.  * 
  22.  *         Copyright Notice 
  23.  * 
  24.  * Notice of copyright on this source code product does not indicate 
  25.  * publication.
  26.  * 
  27.  *     (c) 1986,1987,1988,1989  Sun Microsystems, Inc
  28.  *     (c) 1983,1984,1985,1986,1987,1988,1989  AT&T.
  29.  *               All rights reserved.
  30.  *  
  31.  */
  32.  
  33. #ifndef _VM_PAGE_H
  34. #define _VM_PAGE_H
  35.  
  36. #ident    "@(#)/usr/include/vm/page.h.sl 1.1 4.0 12/08/90 47983 AT&T-USL"
  37.  
  38. #include "vm/vm_hat.h"
  39.  
  40. /*
  41.  * VM - Ram pages.
  42.  *
  43.  * Each physical page has a page structure, which is used to maintain
  44.  * these pages as a cache.  A page can be found via a hashed lookup
  45.  * based on the [vp, offset].  If a page has an [vp, offset] identity,
  46.  * then it is entered on a doubly linked circular list off the
  47.  * vnode using the vpnext/vpprev pointers.   If the p_free bit
  48.  * is on, then the page is also on a doubly linked circular free
  49.  * list using next/prev pointers.  If the p_intrans bit is on,
  50.  * then the page is currently being read in or written back.
  51.  * In this case, the next/prev pointers are used to link the
  52.  * pages together for a consecutive IO request.  If the page
  53.  * is in transit and the the page is coming in (pagein), then you
  54.  * must wait for the IO to complete before you can attach to the page.
  55.  * 
  56.  */
  57. typedef struct page {
  58.     u_int    p_lock: 1,        /* locked for name manipulation */
  59.         p_want: 1,        /* page wanted */
  60.         p_free: 1,        /* on free list */
  61.         p_intrans: 1,        /* data for [vp, offset] intransit */
  62.         p_gone: 1,        /* page has been released */
  63.         p_mod: 1,        /* software copy of modified bit */
  64.         p_ref: 1,        /* software copy of reference bit */
  65.         p_pagein: 1,        /* being paged in, data not valid */
  66.         p_nc: 1,        /* do not cache page */
  67.         p_age: 1;        /* on page_freelist */
  68.     u_int    p_nio : 6;        /* # of outstanding io reqs needed */
  69.     u_short    p_keepcnt;        /* number of page `keeps' */
  70.     struct    vnode *p_vnode;        /* logical vnode this page is from */
  71.     u_int    p_offset;        /* offset into vnode for this page */
  72.     struct page *p_hash;        /* hash by [vnode, offset] */
  73.     struct page *p_next;        /* next page in free/intrans lists */
  74.     struct page *p_prev;        /* prev page in free/intrans lists */
  75.     struct page *p_vpnext;        /* next page in vnode list */
  76.     struct page *p_vpprev;        /* prev page in vnode list */
  77.     struct phat p_hat;        /* One of two hat-specific structures.
  78.                        This structure is for those fields
  79.                        which cannot be overloaded; i.e.
  80.                        they must be valid for all pages.
  81.                        One field, in particular, must be
  82.                        part of this structure: mappings,
  83.                        whose exact semantics are hat-
  84.                        specific, but which must always,
  85.                        generically, be zero if the page
  86.                        has any translations mapped to it,
  87.                        and non-zero otherwise. */
  88.     u_short    p_lckcnt;        /* number of locks on page data */
  89.     u_short    p_cowcnt;        /* number of copy on write lock */
  90.     union {
  91.       daddr_t  _p_dblist[PAGESIZE/NBPSCTR]; /* disk storage for the page */
  92.       struct phat2  _p_hat2;    /* Another hat-specific structure.
  93.                        This one is for fields which can
  94.                        be overloaded on top of p_dblist,
  95.                        e.g., for special pages such as
  96.                        page tables. */
  97.     } _p_db;
  98. #ifdef DEBUG
  99.     struct proc *p_uown;        /* process owning it as u-page */
  100. #endif
  101. } page_t;
  102.  
  103. #define p_mapping    p_hat.mappings
  104. #define p_dblist    _p_db._p_dblist
  105. #define p_hat2        _p_db._p_hat2
  106.  
  107. /*
  108.  * Maximum of noncontiguous Memory Segments.
  109.  * XXX - We must change this to be a tuneable. page_init() must handle this.
  110.  */
  111. #define    MAX_MEM_SEG    10
  112.  
  113. struct pageac {            /* page pool accounting structure */
  114.     struct pageac *panext;    /* pointer to next contiguous
  115.                  * chunk in the ram pool.
  116.                  * It must be the first entry in
  117.                  * this structure for page_init() to work.
  118.                  */
  119.     uint    num;        /* number of logical pages in chunk */
  120.     uint    firstpfn;    /* page frame number of first page in chunk. */
  121.     uint    endpfn;        /* firstpfn + num*(PAGESIZE/MMU_PAGESIZE) */
  122.                 /* NOTE:This page frame number DOES NOT exits */
  123.     struct    page *firstpp;    /* pointer to first page structure */
  124.     struct    page *endpp;    /* firstpp + num */
  125. } ;
  126.  
  127. /* global mapping table for noncontiguous user free memory chunks.
  128. */
  129. extern struct pageac pageac_table[];
  130.  
  131. /* 1st page structure address for 1st free user page in the system.
  132. */
  133. extern page_t *pages;
  134.  
  135. /* Last page structure address for (Last free user page in system - 1). 
  136. /* Logically this structure does not exists.
  137. */
  138. extern page_t *epages;
  139.  
  140.  
  141.  
  142. #ifdef _KERNEL
  143. #define PAGE_HOLD(pp)    (pp)->p_keepcnt++
  144. #define PAGE_RELE(pp)    page_rele(pp)
  145.  
  146. /*
  147.  * page_get() request flags.
  148.  */
  149. #ifndef P_NOSLEEP
  150. #define    P_NOSLEEP    0x0000
  151. #define    P_CANWAIT    0x0001
  152. #define    P_PHYSCONTIG    0x0002
  153. #define    P_DMA        0x0004
  154. #define P_NORESOURCELIM    0x0008
  155. #endif
  156.  
  157. #define    PAGE_HASHSZ    page_hashsz
  158.  
  159. extern    int page_hashsz;
  160. extern    page_t **page_hash;
  161.  
  162. struct pageac *pageahead;
  163. uint pagepoolsize;
  164.  
  165. #ifdef sun386
  166. extern    page_t *epages2;        /* end of absolutely all pages */
  167. extern    u_int    pages_base2;        /* page # for compaq expanded mem */
  168. #endif
  169.  
  170. /*
  171.  * Variables controlling locking of physical memory.
  172.  */
  173. extern    u_int    pages_pp_locked;    /* physical pages actually locked */
  174. extern    u_int    pages_pp_claimed;    /* physical pages reserved */
  175. extern    u_int    pages_pp_kernel;    /* physical page locks by kernel */
  176. extern    u_int    pages_pp_maximum;    /* tuning: lock + claim <= max */
  177.  
  178. /*
  179.  * Page frame operations.
  180.  */
  181.  
  182. void    page_init(/* pap */);
  183. void    page_reclaim(/* pp */);
  184. page_t *page_exists(/* vp, off */);
  185. page_t *page_find(/* vp, off */);
  186. page_t *page_lookup(/* vp, off */);
  187. int    page_enter(/* pp, vp, off */);
  188. void    page_abort(/* pp */);
  189. void    page_free(/* pp */);
  190. page_t *page_get(/* bytes, flags */);
  191. page_t *page_get_aligned(/* bytes, align_mask, align_val, flags */);
  192. int    page_pp_lock(/* pp, claim, kernel */);
  193. void    page_pp_unlock(/* pp, claim, kernel */);
  194. void    page_pp_useclaim(/* opp, npp */);
  195. int    page_addclaim(/* claim */);
  196. void    page_subclaim(/* claim */);
  197. void    page_hashin(/* pp, vp, offset, lock */);
  198. void    page_hashout(/* pp */);
  199. void    page_sub(/* ppp, pp */);
  200. void    page_sortadd(/* ppp, pp */);
  201. void    page_wait(/* pp */);
  202. page_t *page_numtookpp(/* pfnum */);
  203.  
  204. #if defined(DEBUG) || defined(sun386) || defined(i386)
  205.  
  206.     /*
  207.      *    Since we now handle non-contiguous physical memory segments
  208.      *    on the 80386 we need these routines.
  209.      */
  210.  
  211. u_int    page_pptonum(/* pp */);
  212. page_t *page_numtopp(/* pfnum */);
  213.  
  214. extern    u_int    pages_base;    /* on 80386 this is pfn for pages */
  215. extern    uint    pages_end;    /* on 80386 this is pfn for epages */
  216.                 /* But this base and end may not be contiguous */
  217.  
  218. #else
  219.  
  220.     /*
  221.      *    Generalized simple case, e.g. on 3b2. Here we assume that
  222.      *    we have a single physically contiguous memory segment.
  223.      */
  224.  
  225. extern    u_int    pages_base;        /* page # for pages[0] */
  226. extern    uint    pages_end;
  227.  
  228. #define page_pptonum(pp) \
  229.     (((uint)((pp) - pages) * \
  230.         (PAGESIZE/MMU_PAGESIZE)) + pages_base)
  231.  
  232. #define page_numtopp(pfn) \
  233.     ((pfn) < pages_base || (pfn) >= pages_end) ? \
  234.         ((struct page *) NULL) : \
  235.         ((struct page *) (&pages[(uint) ((pfn) - pages_base) / \
  236.             (PAGESIZE/MMU_PAGESIZE)]))
  237.  
  238. #endif
  239.  
  240. #include "vm/mp.h"
  241.  
  242. #ifdef DEBUG
  243.  
  244. void    page_rele(/* pp */);
  245. void    page_lock(/* pp */);
  246. void    page_unlock(/* pp */);
  247.  
  248. #else
  249.  
  250. extern    mon_t    page_mplock;        /* lock for manipulating page links */
  251.  
  252. #define page_rele(pp) { \
  253.     mon_enter(&page_mplock); \
  254.     \
  255.     if (--((struct page *)(pp))->p_keepcnt == 0) { \
  256.         while (((struct page *)(pp))->p_want) { \
  257.             cv_broadcast(&page_mplock, (char *)(pp)); \
  258.             ((struct page *)(pp))->p_want = 0; \
  259.         } \
  260.     } \
  261.     \
  262.     mon_exit(&page_mplock); \
  263.     \
  264.     if (((struct page *)(pp))->p_keepcnt == 0 \
  265.         && (((struct page *)(pp))->p_gone \
  266.         || ((struct page *)(pp))->p_vnode == NULL)) \
  267.         page_abort(pp); \
  268. }
  269. #define page_lock(pp) { \
  270.     mon_enter(&page_mplock); \
  271.     while (pp->p_lock) \
  272.         page_cv_wait(pp); \
  273.     pp->p_lock = 1; \
  274.     mon_exit(&page_mplock); \
  275. }
  276. #define page_unlock(pp) { \
  277.     mon_enter(&page_mplock); \
  278.     ((struct page *)(pp))->p_lock = 0; \
  279.     while (((struct page *)(pp))->p_want) { \
  280.         ((struct page *)(pp))->p_want = 0; \
  281.         cv_broadcast(&page_mplock, (char *)(pp)); \
  282.     } \
  283.     mon_exit(&page_mplock); \
  284. }
  285.  
  286. #endif
  287.  
  288. #endif /* _KERNEL */
  289.  
  290. /*
  291.  * Page hash table is a power-of-two in size, externally chained
  292.  * through the hash field.  PAGE_HASHAVELEN is the average length
  293.  * desired for this chain, from which the size of the page_hash
  294.  * table is derived at boot time and stored in the kernel variable
  295.  * page_hashsz.  In the hash function it is given by PAGE_HASHSZ.
  296.  * PAGE_HASHVPSHIFT is defined so that 1 << PAGE_HASHVPSHIFT is
  297.  * the approximate size of a vnode struct.
  298.  */
  299. #define    PAGE_HASHAVELEN        4
  300. #define    PAGE_HASHVPSHIFT    6
  301. #define    PAGE_HASHFUNC(vp, off) \
  302.     ((((off) >> PAGESHIFT) + ((int)(vp) >> PAGE_HASHVPSHIFT)) & \
  303.         (PAGE_HASHSZ - 1))
  304.  
  305. #if defined(__STDC__)
  306. extern void page_cv_wait(page_t *);
  307. extern void ppcopy(page_t *, page_t *);
  308. #else
  309. extern void page_cv_wait();
  310. extern void ppcopy();
  311. #endif /* __STDC__ */
  312.  
  313. #endif    /* _VM_PAGE_H */
  314.