diff options
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3e136bfe4219..54a72f197487 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -306,6 +306,8 @@ struct scsi_io_context { | |||
306 | char sense[SCSI_SENSE_BUFFERSIZE]; | 306 | char sense[SCSI_SENSE_BUFFERSIZE]; |
307 | }; | 307 | }; |
308 | 308 | ||
309 | static kmem_cache_t *scsi_io_context_cache; | ||
310 | |||
309 | static void scsi_end_async(struct request *req) | 311 | static void scsi_end_async(struct request *req) |
310 | { | 312 | { |
311 | struct scsi_io_context *sioc = req->end_io_data; | 313 | struct scsi_io_context *sioc = req->end_io_data; |
@@ -313,7 +315,7 @@ static void scsi_end_async(struct request *req) | |||
313 | if (sioc->done) | 315 | if (sioc->done) |
314 | sioc->done(sioc->data, sioc->sense, req->errors, req->data_len); | 316 | sioc->done(sioc->data, sioc->sense, req->errors, req->data_len); |
315 | 317 | ||
316 | kfree(sioc); | 318 | kmem_cache_free(scsi_io_context_cache, sioc); |
317 | __blk_put_request(req->q, req); | 319 | __blk_put_request(req->q, req); |
318 | } | 320 | } |
319 | 321 | ||
@@ -452,9 +454,10 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, | |||
452 | int err = 0; | 454 | int err = 0; |
453 | int write = (data_direction == DMA_TO_DEVICE); | 455 | int write = (data_direction == DMA_TO_DEVICE); |
454 | 456 | ||
455 | sioc = kzalloc(sizeof(*sioc), gfp); | 457 | sioc = kmem_cache_alloc(scsi_io_context_cache, gfp); |
456 | if (!sioc) | 458 | if (!sioc) |
457 | return DRIVER_ERROR << 24; | 459 | return DRIVER_ERROR << 24; |
460 | memset(sioc, 0, sizeof(*sioc)); | ||
458 | 461 | ||
459 | req = blk_get_request(sdev->request_queue, write, gfp); | 462 | req = blk_get_request(sdev->request_queue, write, gfp); |
460 | if (!req) | 463 | if (!req) |
@@ -1765,6 +1768,14 @@ int __init scsi_init_queue(void) | |||
1765 | { | 1768 | { |
1766 | int i; | 1769 | int i; |
1767 | 1770 | ||
1771 | scsi_io_context_cache = kmem_cache_create("scsi_io_context", | ||
1772 | sizeof(struct scsi_io_context), | ||
1773 | 0, 0, NULL, NULL); | ||
1774 | if (!scsi_io_context_cache) { | ||
1775 | printk(KERN_ERR "SCSI: can't init scsi io context cache\n"); | ||
1776 | return -ENOMEM; | ||
1777 | } | ||
1778 | |||
1768 | for (i = 0; i < SG_MEMPOOL_NR; i++) { | 1779 | for (i = 0; i < SG_MEMPOOL_NR; i++) { |
1769 | struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; | 1780 | struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; |
1770 | int size = sgp->size * sizeof(struct scatterlist); | 1781 | int size = sgp->size * sizeof(struct scatterlist); |
@@ -1792,6 +1803,8 @@ void scsi_exit_queue(void) | |||
1792 | { | 1803 | { |
1793 | int i; | 1804 | int i; |
1794 | 1805 | ||
1806 | kmem_cache_destroy(scsi_io_context_cache); | ||
1807 | |||
1795 | for (i = 0; i < SG_MEMPOOL_NR; i++) { | 1808 | for (i = 0; i < SG_MEMPOOL_NR; i++) { |
1796 | struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; | 1809 | struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; |
1797 | mempool_destroy(sgp->pool); | 1810 | mempool_destroy(sgp->pool); |