|
|
@@ -132,6 +132,7 @@ static DEFINE_MUTEX(sd_ref_mutex);
|
|
|
|
|
|
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",
|
|
|
@@ -758,9 +759,10 @@ static int sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
|
|
|
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;
|
|
|
@@ -791,9 +793,10 @@ static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, bool unmap)
|
|
|
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;
|
|
|
@@ -821,9 +824,10 @@ static int sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd, bool unmap)
|
|
|
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;
|
|
|
@@ -1287,7 +1291,7 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
|
|
|
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;
|
|
|
@@ -3635,6 +3639,13 @@ static int __init init_sd(void)
|
|
|
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;
|
|
|
@@ -3642,6 +3653,9 @@ static int __init init_sd(void)
|
|
|
return 0;
|
|
|
|
|
|
err_out_driver:
|
|
|
+ mempool_destroy(sd_page_pool);
|
|
|
+
|
|
|
+err_out_ppool:
|
|
|
mempool_destroy(sd_cdb_pool);
|
|
|
|
|
|
err_out_cache:
|
|
|
@@ -3668,6 +3682,7 @@ static void __exit exit_sd(void)
|
|
|
|
|
|
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);
|