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) {
|