* static support functions
*/
-static swblk_t blst_leaf_alloc(blmeta_t *scan, swblk_t blk, int count);
-static swblk_t blst_meta_alloc(blmeta_t *scan, swblk_t blk,
- swblk_t count, int64_t radix, int skip);
+static swblk_t blst_leaf_alloc(blmeta_t *scan, swblk_t blkat,
+ swblk_t blk, int count);
+static swblk_t blst_meta_alloc(blmeta_t *scan, swblk_t blkat,
+ swblk_t blk, swblk_t count,
+ int64_t radix, int skip);
static void blst_leaf_free(blmeta_t *scan, swblk_t relblk, int count);
static void blst_meta_free(blmeta_t *scan, swblk_t freeBlk, swblk_t count,
int64_t radix, int skip, swblk_t blk);
if (bl) {
if (bl->bl_radix == BLIST_BMAP_RADIX)
- blk = blst_leaf_alloc(bl->bl_root, 0, count);
+ blk = blst_leaf_alloc(bl->bl_root, 0, 0, count);
else
- blk = blst_meta_alloc(bl->bl_root, 0, count, bl->bl_radix, bl->bl_skip);
+ blk = blst_meta_alloc(bl->bl_root, 0, 0, count,
+ bl->bl_radix, bl->bl_skip);
+ if (blk != SWAPBLK_NONE)
+ bl->bl_free -= count;
+ }
+ return(blk);
+}
+
+swblk_t
+blist_allocat(blist_t bl, swblk_t count, swblk_t blkat)
+{
+ swblk_t blk = SWAPBLK_NONE;
+
+ if (bl) {
+ if (bl->bl_radix == BLIST_BMAP_RADIX)
+ blk = blst_leaf_alloc(bl->bl_root, blkat, 0, count);
+ else
+ blk = blst_meta_alloc(bl->bl_root, blkat, 0, count,
+ bl->bl_radix, bl->bl_skip);
if (blk != SWAPBLK_NONE)
bl->bl_free -= count;
}
*/
static swblk_t
-blst_leaf_alloc(blmeta_t *scan, swblk_t blk, int count)
+blst_leaf_alloc(blmeta_t *scan, swblk_t blkat __unused, swblk_t blk, int count)
{
u_swblk_t orig = scan->u.bmu_bitmap;
* and we have a few optimizations strewn in as well.
*/
static swblk_t
-blst_meta_alloc(blmeta_t *scan, swblk_t blk, swblk_t count,
+blst_meta_alloc(blmeta_t *scan, swblk_t blkat,
+ swblk_t blk, swblk_t count,
int64_t radix, int skip)
{
int i;
int next_skip = ((u_int)skip / BLIST_META_RADIX);
+ int hintok = (blk >= blkat);
/*
* ALL-ALLOCATED special case
}
for (i = 1; i <= skip; i += next_skip) {
- if (count <= scan[i].bm_bighint) {
+ if (count <= scan[i].bm_bighint &&
+ blk + (swblk_t)radix > blkat) {
/*
* count fits in object
*/
swblk_t r;
if (next_skip == 1) {
- r = blst_leaf_alloc(&scan[i], blk, count);
+ r = blst_leaf_alloc(&scan[i], blkat,
+ blk, count);
} else {
- r = blst_meta_alloc(&scan[i], blk, count,
+ r = blst_meta_alloc(&scan[i], blkat,
+ blk, count,
radix, next_skip - 1);
}
if (r != SWAPBLK_NONE) {
/*
* We couldn't allocate count in this subtree, update bighint.
*/
- if (scan->bm_bighint >= count)
+ if (hintok && scan->bm_bighint >= count)
scan->bm_bighint = count - 1;
return(SWAPBLK_NONE);
}
char buf[1024];
swblk_t da = 0;
swblk_t count = 0;
+ swblk_t blkat;
kprintf("%d/%d/%lld> ",
blist_print(bl);
break;
case 'a':
- if (sscanf(buf + 1, "%d", &count) == 1) {
+ if (sscanf(buf + 1, "%d %d", &count, &blkat) == 1) {
swblk_t blk = blist_alloc(bl, count);
kprintf(" R=%04x\n", blk);
+ } else if (sscanf(buf + 1, "%d %d", &count, &blkat) == 2) {
+ swblk_t blk = blist_allocat(bl, count, blkat);
+ kprintf(" R=%04x\n", blk);
} else {
kprintf("?\n");
}
struct blist *swapblist;
static int swap_async_max = 4; /* maximum in-progress async I/O's */
static int swap_burst_read = 0; /* allow burst reading */
+static swblk_t swapiterator; /* linearize allocations */
/* from vm_swap.c */
extern struct vnode *swapdev_vp;
swblk_t blk;
lwkt_gettoken(&vm_token);
- if ((blk = blist_alloc(swapblist, npages)) == SWAPBLK_NONE) {
+ blk = blist_allocat(swapblist, npages, swapiterator);
+ if (blk == SWAPBLK_NONE)
+ blk = blist_allocat(swapblist, npages, 0);
+ if (blk == SWAPBLK_NONE) {
if (swap_pager_full != 2) {
kprintf("swap_pager_getswapspace: failed alloc=%d\n",
npages);
swap_pager_almost_full = 1;
}
} else {
+ swapiterator = blk;
swapacctspace(blk, -npages);
if (object->type == OBJT_SWAP)
vm_swap_anon_use += npages;
char *data;
struct bio *biox;
struct buf *bufx;
+#if 0
struct bio_track *track;
+#endif
+#if 0
/*
* tracking for swapdev vnode I/Os
*/
track = &swapdev_vp->v_track_read;
else
track = &swapdev_vp->v_track_write;
+#endif
if (bp->b_bcount & PAGE_MASK) {
bp->b_error = EINVAL;