static struct kmem_cache *sd_cdb_cache;
 static mempool_t *sd_cdb_pool;
+static mempool_t *sd_page_pool;
 
 static const char *sd_cache_types[] = {
        "write through", "none", "write back",
        unsigned int data_len = 24;
        char *buf;
 
-       rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
+       rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
        if (!rq->special_vec.bv_page)
                return BLKPREP_DEFER;
+       clear_highpage(rq->special_vec.bv_page);
        rq->special_vec.bv_offset = 0;
        rq->special_vec.bv_len = data_len;
        rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
        u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
        u32 data_len = sdp->sector_size;
 
-       rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
+       rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
        if (!rq->special_vec.bv_page)
                return BLKPREP_DEFER;
+       clear_highpage(rq->special_vec.bv_page);
        rq->special_vec.bv_offset = 0;
        rq->special_vec.bv_len = data_len;
        rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
        u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
        u32 data_len = sdp->sector_size;
 
-       rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
+       rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
        if (!rq->special_vec.bv_page)
                return BLKPREP_DEFER;
+       clear_highpage(rq->special_vec.bv_page);
        rq->special_vec.bv_offset = 0;
        rq->special_vec.bv_len = data_len;
        rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
        u8 *cmnd;
 
        if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
-               __free_page(rq->special_vec.bv_page);
+               mempool_free(rq->special_vec.bv_page, sd_page_pool);
 
        if (SCpnt->cmnd != scsi_req(rq)->cmd) {
                cmnd = SCpnt->cmnd;
                goto err_out_cache;
        }
 
+       sd_page_pool = mempool_create_page_pool(SD_MEMPOOL_SIZE, 0);
+       if (!sd_page_pool) {
+               printk(KERN_ERR "sd: can't init discard page pool\n");
+               err = -ENOMEM;
+               goto err_out_ppool;
+       }
+
        err = scsi_register_driver(&sd_template.gendrv);
        if (err)
                goto err_out_driver;
        return 0;
 
 err_out_driver:
+       mempool_destroy(sd_page_pool);
+
+err_out_ppool:
        mempool_destroy(sd_cdb_pool);
 
 err_out_cache:
 
        scsi_unregister_driver(&sd_template.gendrv);
        mempool_destroy(sd_cdb_pool);
+       mempool_destroy(sd_page_pool);
        kmem_cache_destroy(sd_cdb_cache);
 
        class_unregister(&sd_disk_class);