Print this page
XXXX give me a better summary


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1987, 2010, Oracle and/or its affiliates. All rights reserved.

  23  */
  24 
  25 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  26 /*        All Rights Reserved   */
  27 
  28 /*
  29  * University Copyright- Copyright (c) 1982, 1986, 1988
  30  * The Regents of the University of California
  31  * All Rights Reserved
  32  *
  33  * University Acknowledgment- Portions of this document are derived from
  34  * software developed by the University of California, Berkeley, and its
  35  * contributors.
  36  */
  37 
  38 /*
  39  * Each physical swap area has an associated bitmap representing
  40  * its physical storage. The bitmap records which swap slots are
  41  * currently allocated or freed.  Allocation is done by searching
  42  * through the bitmap for the first free slot. Thus, there's


 117  * swap device bitmap allocation macros
 118  */
 119 #define MAPSHIFT        5
 120 #define NBBW            (NBPW * NBBY)   /* number of bits per word */
 121 #define TESTBIT(map, i)         (((map)[(i) >> MAPSHIFT] & (1 << (i) % NBBW)))
 122 #define SETBIT(map, i)          (((map)[(i) >> MAPSHIFT] |= (1 << (i) % NBBW)))
 123 #define CLEARBIT(map, i)        (((map)[(i) >> MAPSHIFT] &= ~(1 << (i) % NBBW)))
 124 
 125 int swap_debug = 0;     /* set for debug printf's */
 126 int swap_verify = 0;    /* set to verify slots when freeing and allocating */
 127 
 128 uint_t swapalloc_maxcontig;
 129 
 130 /*
 131  * Allocate a range of up to *lenp contiguous slots (page) from a physical
 132  * swap device. Flags are one of:
 133  *      SA_NOT  Must have a slot from a physical swap device other than the
 134  *              the one containing input (*vpp, *offp).
 135  * Less slots than requested may be returned. *lenp allocated slots are
 136  * returned starting at *offp on *vpp.
 137  * Returns 1 for a successful allocation, 0 for couldn't allocate any slots.

 138  */
 139 int
 140 swap_phys_alloc(
 141         struct vnode **vpp,
 142         u_offset_t *offp,
 143         size_t *lenp,
 144         uint_t flags)
 145 {
 146         struct swapinfo *sip;
 147         offset_t soff, noff;
 148         size_t len;
 149 
 150         mutex_enter(&swapinfo_lock);





 151         sip = silast;
 152 
 153         /* Find a desirable physical device and allocate from it. */
 154         do {
 155                 if (sip == NULL)
 156                         break;
 157                 if (!(sip->si_flags & ST_INDEL) &&
 158                     (spgcnt_t)sip->si_nfpgs > 0) {
 159                         /* Caller wants other than specified swap device */
 160                         if (flags & SA_NOT) {
 161                                 if (*vpp != sip->si_vp ||
 162                                     *offp < sip->si_soff ||
 163                                     *offp >= sip->si_eoff)
 164                                         goto found;
 165                         /* Caller is loose, will take anything */
 166                         } else
 167                                 goto found;
 168                 } else if (sip->si_nfpgs == 0)
 169                         sip->si_allocs = 0;
 170                 if ((sip = sip->si_next) == NULL)


1641                 mutex_exit(ahm);
1642                 hat_setmod(pp);
1643         } else {
1644                 mutex_exit(ahm);
1645         }
1646         page_io_unlock(pp);
1647         page_unlock(pp);
1648         return (0);
1649 }
1650 
1651 
1652 /*
1653  * Get contig physical backing store for vp, in the range
1654  * [*offp, *offp + *lenp), May back a subrange of this, but must
1655  * always include the requested offset or fail. Returns the offsets
1656  * backed as [*offp, *offp + *lenp) and the physical offsets used to
1657  * back them from *pvpp in the range [*pstartp, *pstartp + *lenp).
1658  * Returns      0 for success
1659  *              SE_NOANON -- no anon slot for requested paged
1660  *              SE_NOSWAP -- no physical swap space available

1661  */
1662 int
1663 swap_newphysname(
1664         struct vnode *vp,
1665         u_offset_t offset,
1666         u_offset_t *offp,
1667         size_t *lenp,
1668         struct vnode **pvpp,
1669         u_offset_t *poffp)
1670 {
1671         struct anon *ap = NULL;         /* anon slot for vp, off */
1672         int error = 0;
1673         struct vnode *pvp;
1674         u_offset_t poff, pstart, prem;
1675         size_t plen;
1676         u_offset_t off, start;
1677         kmutex_t *ahm;
1678 
1679         ASSERT(*offp <= offset && offset < *offp + *lenp);
1680 
1681         /* Get new physical swap slots. */
1682         plen = *lenp;
1683         if (!swap_phys_alloc(&pvp, &pstart, &plen, 0)) {

1684                 /*
1685                  * No swap available so return error unless requested
1686                  * offset is already backed in which case return that.
1687                  */
1688                 ahm = AH_MUTEX(vp, offset);
1689                 mutex_enter(ahm);
1690                 if ((ap = swap_anon(vp, offset)) == NULL) {
1691                         error = SE_NOANON;
1692                         mutex_exit(ahm);
1693                         return (error);
1694                 }
1695                 error = (ap->an_pvp ? 0 : SE_NOSWAP);
1696                 *offp = offset;
1697                 *lenp = PAGESIZE;
1698                 *pvpp = ap->an_pvp;
1699                 *poffp = ap->an_poff;
1700                 mutex_exit(ahm);
1701                 return (error);
1702         }
1703 
1704         /*
1705          * We got plen (<= *lenp) contig slots. Use these to back a
1706          * subrange of [*offp, *offp + *lenp) which includes offset.
1707          * For now we just put offset at the end of the kluster.
1708          * Clearly there are other possible choices - which is best?
1709          */
1710         start = MAX(*offp,
1711             (offset + PAGESIZE > plen) ? (offset + PAGESIZE - plen) : 0);
1712         ASSERT(start + plen <= *offp + *lenp);
1713 
1714         for (off = start, poff = pstart; poff < pstart + plen;
1715             off += PAGESIZE, poff += PAGESIZE) {




   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1987, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*        All Rights Reserved   */
  28 
  29 /*
  30  * University Copyright- Copyright (c) 1982, 1986, 1988
  31  * The Regents of the University of California
  32  * All Rights Reserved
  33  *
  34  * University Acknowledgment- Portions of this document are derived from
  35  * software developed by the University of California, Berkeley, and its
  36  * contributors.
  37  */
  38 
  39 /*
  40  * Each physical swap area has an associated bitmap representing
  41  * its physical storage. The bitmap records which swap slots are
  42  * currently allocated or freed.  Allocation is done by searching
  43  * through the bitmap for the first free slot. Thus, there's


 118  * swap device bitmap allocation macros
 119  */
 120 #define MAPSHIFT        5
 121 #define NBBW            (NBPW * NBBY)   /* number of bits per word */
 122 #define TESTBIT(map, i)         (((map)[(i) >> MAPSHIFT] & (1 << (i) % NBBW)))
 123 #define SETBIT(map, i)          (((map)[(i) >> MAPSHIFT] |= (1 << (i) % NBBW)))
 124 #define CLEARBIT(map, i)        (((map)[(i) >> MAPSHIFT] &= ~(1 << (i) % NBBW)))
 125 
 126 int swap_debug = 0;     /* set for debug printf's */
 127 int swap_verify = 0;    /* set to verify slots when freeing and allocating */
 128 
 129 uint_t swapalloc_maxcontig;
 130 
 131 /*
 132  * Allocate a range of up to *lenp contiguous slots (page) from a physical
 133  * swap device. Flags are one of:
 134  *      SA_NOT  Must have a slot from a physical swap device other than the
 135  *              the one containing input (*vpp, *offp).
 136  * Less slots than requested may be returned. *lenp allocated slots are
 137  * returned starting at *offp on *vpp.
 138  * Returns 1 for a successful allocation, 0 for couldn't allocate any slots,
 139  * and -1 when there are no swap devices on this system.
 140  */
 141 int
 142 swap_phys_alloc(
 143         struct vnode **vpp,
 144         u_offset_t *offp,
 145         size_t *lenp,
 146         uint_t flags)
 147 {
 148         struct swapinfo *sip;
 149         offset_t soff, noff;
 150         size_t len;
 151 
 152         mutex_enter(&swapinfo_lock);
 153         if (swapinfo == NULL) {
 154                 /* NO SWAP DEVICES on this system currently. */
 155                 mutex_exit(&swapinfo_lock);
 156                 return (-1);
 157         }
 158         sip = silast;
 159 
 160         /* Find a desirable physical device and allocate from it. */
 161         do {
 162                 if (sip == NULL)
 163                         break;
 164                 if (!(sip->si_flags & ST_INDEL) &&
 165                     (spgcnt_t)sip->si_nfpgs > 0) {
 166                         /* Caller wants other than specified swap device */
 167                         if (flags & SA_NOT) {
 168                                 if (*vpp != sip->si_vp ||
 169                                     *offp < sip->si_soff ||
 170                                     *offp >= sip->si_eoff)
 171                                         goto found;
 172                         /* Caller is loose, will take anything */
 173                         } else
 174                                 goto found;
 175                 } else if (sip->si_nfpgs == 0)
 176                         sip->si_allocs = 0;
 177                 if ((sip = sip->si_next) == NULL)


1648                 mutex_exit(ahm);
1649                 hat_setmod(pp);
1650         } else {
1651                 mutex_exit(ahm);
1652         }
1653         page_io_unlock(pp);
1654         page_unlock(pp);
1655         return (0);
1656 }
1657 
1658 
1659 /*
1660  * Get contig physical backing store for vp, in the range
1661  * [*offp, *offp + *lenp), May back a subrange of this, but must
1662  * always include the requested offset or fail. Returns the offsets
1663  * backed as [*offp, *offp + *lenp) and the physical offsets used to
1664  * back them from *pvpp in the range [*pstartp, *pstartp + *lenp).
1665  * Returns      0 for success
1666  *              SE_NOANON -- no anon slot for requested paged
1667  *              SE_NOSWAP -- no physical swap space available
1668  *              SE_NODEV -- no swap devices on this system
1669  */
1670 int
1671 swap_newphysname(
1672         struct vnode *vp,
1673         u_offset_t offset,
1674         u_offset_t *offp,
1675         size_t *lenp,
1676         struct vnode **pvpp,
1677         u_offset_t *poffp)
1678 {
1679         struct anon *ap = NULL;         /* anon slot for vp, off */
1680         int error = 0;
1681         struct vnode *pvp;
1682         u_offset_t poff, pstart, prem;
1683         size_t plen;
1684         u_offset_t off, start;
1685         kmutex_t *ahm;
1686 
1687         ASSERT(*offp <= offset && offset < *offp + *lenp);
1688 
1689         /* Get new physical swap slots. */
1690         plen = *lenp;
1691         error = swap_phys_alloc(&pvp, &pstart, &plen, 0);
1692         if (error != 1) {
1693                 /*
1694                  * No swap available so return error unless requested
1695                  * offset is already backed in which case return that.
1696                  */
1697                 ahm = AH_MUTEX(vp, offset);
1698                 mutex_enter(ahm);
1699                 if ((ap = swap_anon(vp, offset)) == NULL) {
1700                         error = SE_NOANON;
1701                         mutex_exit(ahm);
1702                         return (error);
1703                 }
1704                 error = (ap->an_pvp ? 0 : (error == 0) ? SE_NOSWAP : SE_NODEV);
1705                 *offp = offset;
1706                 *lenp = PAGESIZE;
1707                 *pvpp = ap->an_pvp;
1708                 *poffp = ap->an_poff;
1709                 mutex_exit(ahm);
1710                 return (error);
1711         }
1712 
1713         /*
1714          * We got plen (<= *lenp) contig slots. Use these to back a
1715          * subrange of [*offp, *offp + *lenp) which includes offset.
1716          * For now we just put offset at the end of the kluster.
1717          * Clearly there are other possible choices - which is best?
1718          */
1719         start = MAX(*offp,
1720             (offset + PAGESIZE > plen) ? (offset + PAGESIZE - plen) : 0);
1721         ASSERT(start + plen <= *offp + *lenp);
1722 
1723         for (off = start, poff = pstart; poff < pstart + plen;
1724             off += PAGESIZE, poff += PAGESIZE) {