Use mask allocator first for bouncing This way for devices which have a bounce limit greater than the ISA DMA threshold but less than the max memory the 16MB zone is not used. There is no special mempool for this, but we just use __GFP_NOIO|__GFP_NOWARN and then fall back to the ISA mempool if that fails. Signed-off-by: Andi Kleen Signed-off-by: Andi Kleen --- mm/bounce.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) Index: linux/mm/bounce.c =================================================================== --- linux.orig/mm/bounce.c +++ linux/mm/bounce.c @@ -129,7 +129,10 @@ static void bounce_end_io(struct bio *bi continue; dec_zone_page_state(bvec->bv_page, NR_BOUNCE); - mempool_free(bvec->bv_page, pool); + if (page_to_pfn(bvec->bv_page) >= BLK_BOUNCE_ISA) + __free_page_mask(bvec->bv_page); + else + mempool_free(bvec->bv_page, pool); } bio_endio(bio_orig, err); @@ -192,7 +195,12 @@ static void __blk_queue_bounce(struct re to = bio->bi_io_vec + i; - to->bv_page = mempool_alloc(pool, GFP_NOIO); + to->bv_page = NULL; + if (pool != page_pool) + to->bv_page = alloc_pages_mask(GFP_NOIO|__GFP_NOWARN, PAGE_SIZE, + blk_q_mask(q)); + if (!to->bv_page) + to->bv_page = mempool_alloc(pool, GFP_NOIO); to->bv_len = from->bv_len; to->bv_offset = from->bv_offset; inc_zone_page_state(to->bv_page, NR_BOUNCE);