diff options
| -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); |
