Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161460290
D20001.id56788.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D20001.id56788.diff
View Options
Index: sys/kern/subr_blist.c
===================================================================
--- sys/kern/subr_blist.c
+++ sys/kern/subr_blist.c
@@ -284,11 +284,11 @@
* not be allocated.
*/
daddr_t
-blist_alloc(blist_t bl, daddr_t count)
+blist_alloc(blist_t bl, int *count, int maxcount)
{
daddr_t blk;
- if (count > BLIST_MAX_ALLOC)
+ if (*count > BLIST_MAX_ALLOC)
panic("allocation too large");
/*
@@ -298,11 +298,11 @@
* stop further iterations.
*/
for (;;) {
- blk = blst_meta_alloc(bl->bl_root, bl->bl_cursor, count,
+ blk = blst_meta_alloc(bl->bl_root, bl->bl_cursor, *count,
bl->bl_radix);
if (blk != SWAPBLK_NONE) {
- bl->bl_avail -= count;
- bl->bl_cursor = blk + count;
+ bl->bl_avail -= *count;
+ bl->bl_cursor = blk + *count;
if (bl->bl_cursor == bl->bl_blocks)
bl->bl_cursor = 0;
return (blk);
Index: sys/sys/blist.h
===================================================================
--- sys/sys/blist.h
+++ sys/sys/blist.h
@@ -33,7 +33,7 @@
* Usage:
* blist = blist_create(blocks, flags)
* (void) blist_destroy(blist)
- * blkno = blist_alloc(blist, count)
+ * blkno = blist_alloc(blist, &count, maxcount)
* (void) blist_free(blist, blkno, count)
* nblks = blist_fill(blist, blkno, count)
* (void) blist_resize(&blist, count, freeextra, flags)
@@ -69,11 +69,11 @@
#define SWAPBLK_NONE ((daddr_t)((u_daddr_t)SWAPBLK_MASK + 1))/* flag */
/*
- * Both blmeta and bmu_bitmap MUST be a power of 2 in size.
+ * Both blmeta and bm_bitmap MUST be a power of 2 in size.
*/
typedef struct blmeta {
- u_daddr_t bm_bitmap; /* bitmap if we are a leaf */
+ u_daddr_t bm_bitmap; /* bitmap marking unfilled block sets*/
daddr_t bm_bighint; /* biggest contiguous block hint*/
} blmeta_t;
@@ -92,7 +92,7 @@
struct sbuf;
-daddr_t blist_alloc(blist_t blist, daddr_t count);
+daddr_t blist_alloc(blist_t blist, int *count, int maxcount);
daddr_t blist_avail(blist_t blist);
blist_t blist_create(daddr_t blocks, int flags);
void blist_destroy(blist_t blist);
Index: sys/vm/swap_pager.c
===================================================================
--- sys/vm/swap_pager.c
+++ sys/vm/swap_pager.c
@@ -407,7 +407,7 @@
* Swap bitmap functions
*/
static void swp_pager_freeswapspace(daddr_t blk, daddr_t npages);
-static daddr_t swp_pager_getswapspace(int npages);
+static daddr_t swp_pager_getswapspace(int *npages, int limit);
/*
* Metadata functions
@@ -708,9 +708,10 @@
/*
* SWP_PAGER_GETSWAPSPACE() - allocate raw swap space
*
- * Allocate swap for the requested number of pages. The starting
- * swap block number (a page index) is returned or SWAPBLK_NONE
- * if the allocation failed.
+ * Allocate swap for up to the requested number of pages, and at
+ * least a minimum number of pages. The starting swap block number
+ * (a page index) is returned or SWAPBLK_NONE if the allocation
+ * failed.
*
* Also has the side effect of advising that somebody made a mistake
* when they configured swap and didn't configure enough.
@@ -720,38 +721,49 @@
* We allocate in round-robin fashion from the configured devices.
*/
static daddr_t
-swp_pager_getswapspace(int npages)
+swp_pager_getswapspace(int *io_npages, int limit)
{
daddr_t blk;
struct swdevt *sp;
- int i;
+ int mpages, npages;
blk = SWAPBLK_NONE;
+ npages = mpages = *io_npages;
mtx_lock(&sw_dev_mtx);
+ if (TAILQ_EMPTY(&swtailq)) {
+ mtx_unlock(&sw_dev_mtx);
+ return (blk);
+ }
sp = swdevhd;
- for (i = 0; i < nswapdev; i++) {
+ while (mpages >= limit) {
if (sp == NULL)
sp = TAILQ_FIRST(&swtailq);
- if (!(sp->sw_flags & SW_CLOSING)) {
- blk = blist_alloc(sp->sw_blist, npages);
- if (blk != SWAPBLK_NONE) {
- blk += sp->sw_first;
- sp->sw_used += npages;
- swap_pager_avail -= npages;
- swp_sizecheck();
- swdevhd = TAILQ_NEXT(sp, sw_list);
- goto done;
- }
- }
+ if ((sp->sw_flags & SW_CLOSING) == 0)
+ blk = blist_alloc(sp->sw_blist, &npages, mpages);
+ if (blk != SWAPBLK_NONE)
+ break;
sp = TAILQ_NEXT(sp, sw_list);
+ if (swdevhd == sp) {
+ mpages = npages - 1;
+ npages >>= 1;
+ }
}
- if (swap_pager_full != 2) {
- printf("swap_pager_getswapspace(%d): failed\n", npages);
- swap_pager_full = 2;
- swap_pager_almost_full = 1;
+ if (blk != SWAPBLK_NONE) {
+ *io_npages = npages;
+ blk += sp->sw_first;
+ sp->sw_used += npages;
+ swap_pager_avail -= npages;
+ swp_sizecheck();
+ swdevhd = TAILQ_NEXT(sp, sw_list);
+ } else {
+ if (swap_pager_full != 2) {
+ printf("swp_pager_getswapspace(%d): failed\n",
+ *io_npages);
+ swap_pager_full = 2;
+ swap_pager_almost_full = 1;
+ }
+ swdevhd = NULL;
}
- swdevhd = NULL;
-done:
mtx_unlock(&sw_dev_mtx);
return (blk);
}
@@ -886,35 +898,30 @@
int
swap_pager_reserve(vm_object_t object, vm_pindex_t start, vm_size_t size)
{
- int n = 0;
- daddr_t blk = SWAPBLK_NONE;
+ int i, n;
+ daddr_t blk;
vm_pindex_t beg = start; /* save start index */
daddr_t addr, n_free, s_free;
swp_pager_init_freerange(&s_free, &n_free);
VM_OBJECT_WLOCK(object);
- while (size) {
- if (n == 0) {
- n = BLIST_MAX_ALLOC;
- while ((blk = swp_pager_getswapspace(n)) == SWAPBLK_NONE) {
- n >>= 1;
- if (n == 0) {
- swp_pager_meta_free(object, beg, start - beg);
- VM_OBJECT_WUNLOCK(object);
- return (-1);
- }
- }
+ while (beg + size > start) {
+ n = min(BLIST_MAX_ALLOC, beg + size - start);
+ blk = swp_pager_getswapspace(&n, 1);
+ if (blk == SWAPBLK_NONE) {
+ swp_pager_meta_free(object, beg, start - beg);
+ VM_OBJECT_WUNLOCK(object);
+ return (-1);
}
- addr = swp_pager_meta_build(object, start, blk);
- if (addr != SWAPBLK_NONE)
+ for (i = 0; i < n; ++i) {
+ addr = swp_pager_meta_build(object, start + i, blk + i);
+ if (addr == SWAPBLK_NONE)
+ continue;
swp_pager_update_freerange(&s_free, &n_free, addr);
- --size;
- ++start;
- ++blk;
- --n;
+ }
+ start += n;
}
swp_pager_freeswapspace(s_free, n_free);
- swp_pager_meta_free(object, start, n);
VM_OBJECT_WUNLOCK(object);
return (0);
}
@@ -1384,18 +1391,8 @@
n = min(BLIST_MAX_ALLOC, count - i);
n = min(n, nsw_cluster_max);
- /*
- * Get biggest block of swap we can. If we fail, fall
- * back and try to allocate a smaller block. Don't go
- * overboard trying to allocate space if it would overly
- * fragment swap.
- */
- while (
- (blk = swp_pager_getswapspace(n)) == SWAPBLK_NONE &&
- n > 4
- ) {
- n >>= 1;
- }
+ /* Get a block of swap of size up to size n. */
+ blk = swp_pager_getswapspace(&n, 4);
if (blk == SWAPBLK_NONE) {
for (j = 0; j < n; ++j)
rtvals[i+j] = VM_PAGER_FAIL;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jul 5, 12:38 AM (12 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34684859
Default Alt Text
D20001.id56788.diff (6 KB)
Attached To
Mode
D20001: Let swp_pager_getswapspace allocate bigger blocks
Attached
Detach File
Event Timeline
Log In to Comment