aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sd.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3bb2b3351e35..bd0a5c694a97 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -133,6 +133,7 @@ static DEFINE_MUTEX(sd_ref_mutex);
133 133
134static struct kmem_cache *sd_cdb_cache; 134static struct kmem_cache *sd_cdb_cache;
135static mempool_t *sd_cdb_pool; 135static mempool_t *sd_cdb_pool;
136static mempool_t *sd_page_pool;
136 137
137static const char *sd_cache_types[] = { 138static const char *sd_cache_types[] = {
138 "write through", "none", "write back", 139 "write through", "none", "write back",
@@ -759,9 +760,10 @@ static int sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
759 unsigned int data_len = 24; 760 unsigned int data_len = 24;
760 char *buf; 761 char *buf;
761 762
762 rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO); 763 rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
763 if (!rq->special_vec.bv_page) 764 if (!rq->special_vec.bv_page)
764 return BLKPREP_DEFER; 765 return BLKPREP_DEFER;
766 clear_highpage(rq->special_vec.bv_page);
765 rq->special_vec.bv_offset = 0; 767 rq->special_vec.bv_offset = 0;
766 rq->special_vec.bv_len = data_len; 768 rq->special_vec.bv_len = data_len;
767 rq->rq_flags |= RQF_SPECIAL_PAYLOAD; 769 rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
@@ -792,9 +794,10 @@ static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, bool unmap)
792 u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9); 794 u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
793 u32 data_len = sdp->sector_size; 795 u32 data_len = sdp->sector_size;
794 796
795 rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO); 797 rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
796 if (!rq->special_vec.bv_page) 798 if (!rq->special_vec.bv_page)
797 return BLKPREP_DEFER; 799 return BLKPREP_DEFER;
800 clear_highpage(rq->special_vec.bv_page);
798 rq->special_vec.bv_offset = 0; 801 rq->special_vec.bv_offset = 0;
799 rq->special_vec.bv_len = data_len; 802 rq->special_vec.bv_len = data_len;
800 rq->rq_flags |= RQF_SPECIAL_PAYLOAD; 803 rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
@@ -822,9 +825,10 @@ static int sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd, bool unmap)
822 u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9); 825 u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
823 u32 data_len = sdp->sector_size; 826 u32 data_len = sdp->sector_size;
824 827
825 rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO); 828 rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
826 if (!rq->special_vec.bv_page) 829 if (!rq->special_vec.bv_page)
827 return BLKPREP_DEFER; 830 return BLKPREP_DEFER;
831 clear_highpage(rq->special_vec.bv_page);
828 rq->special_vec.bv_offset = 0; 832 rq->special_vec.bv_offset = 0;
829 rq->special_vec.bv_len = data_len; 833 rq->special_vec.bv_len = data_len;
830 rq->rq_flags |= RQF_SPECIAL_PAYLOAD; 834 rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
@@ -1286,7 +1290,7 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
1286 u8 *cmnd; 1290 u8 *cmnd;
1287 1291
1288 if (rq->rq_flags & RQF_SPECIAL_PAYLOAD) 1292 if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
1289 __free_page(rq->special_vec.bv_page); 1293 mempool_free(rq->special_vec.bv_page, sd_page_pool);
1290 1294
1291 if (SCpnt->cmnd != scsi_req(rq)->cmd) { 1295 if (SCpnt->cmnd != scsi_req(rq)->cmd) {
1292 cmnd = SCpnt->cmnd; 1296 cmnd = SCpnt->cmnd;
@@ -3623,6 +3627,13 @@ static int __init init_sd(void)
3623 goto err_out_cache; 3627 goto err_out_cache;
3624 } 3628 }
3625 3629
3630 sd_page_pool = mempool_create_page_pool(SD_MEMPOOL_SIZE, 0);
3631 if (!sd_page_pool) {
3632 printk(KERN_ERR "sd: can't init discard page pool\n");
3633 err = -ENOMEM;
3634 goto err_out_ppool;
3635 }
3636
3626 err = scsi_register_driver(&sd_template.gendrv); 3637 err = scsi_register_driver(&sd_template.gendrv);
3627 if (err) 3638 if (err)
3628 goto err_out_driver; 3639 goto err_out_driver;
@@ -3630,6 +3641,9 @@ static int __init init_sd(void)
3630 return 0; 3641 return 0;
3631 3642
3632err_out_driver: 3643err_out_driver:
3644 mempool_destroy(sd_page_pool);
3645
3646err_out_ppool:
3633 mempool_destroy(sd_cdb_pool); 3647 mempool_destroy(sd_cdb_pool);
3634 3648
3635err_out_cache: 3649err_out_cache:
@@ -3656,6 +3670,7 @@ static void __exit exit_sd(void)
3656 3670
3657 scsi_unregister_driver(&sd_template.gendrv); 3671 scsi_unregister_driver(&sd_template.gendrv);
3658 mempool_destroy(sd_cdb_pool); 3672 mempool_destroy(sd_cdb_pool);
3673 mempool_destroy(sd_page_pool);
3659 kmem_cache_destroy(sd_cdb_cache); 3674 kmem_cache_destroy(sd_cdb_cache);
3660 3675
3661 class_unregister(&sd_disk_class); 3676 class_unregister(&sd_disk_class);