From 9b1d6c8950021ab007608d455fc9c398ecd25476 Mon Sep 17 00:00:00 2001 From: Ming Lin Date: Mon, 4 Apr 2016 14:48:11 -0700 Subject: lib: scatterlist: move SG pool code from SCSI driver to lib/sg_pool.c Now it's ready to move the mempool based SG chained allocator code from SCSI driver to lib/sg_pool.c, which will be compiled only based on a Kconfig symbol CONFIG_SG_POOL. SCSI selects CONFIG_SG_POOL. Reviewed-by: Christoph Hellwig Signed-off-by: Ming Lin Reviewed-by: Sagi Grimberg Signed-off-by: Martin K. Petersen --- drivers/scsi/Kconfig | 1 + drivers/scsi/scsi_lib.c | 137 ------------------------------------------------ 2 files changed, 1 insertion(+), 137 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 0950567e6269..98e5d51a3346 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -17,6 +17,7 @@ config SCSI tristate "SCSI device support" depends on BLOCK select SCSI_DMA if HAS_DMA + select SG_POOL ---help--- If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or any other SCSI device under Linux, say Y and make sure that you know diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 8f776f1e95ce..b920c5dabf60 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include @@ -40,39 +38,6 @@ #include "scsi_logging.h" -#define SG_MEMPOOL_NR ARRAY_SIZE(sg_pools) -#define SG_MEMPOOL_SIZE 2 - -struct sg_pool { - size_t size; - char *name; - struct kmem_cache *slab; - mempool_t *pool; -}; - -#define SP(x) { .size = x, "sgpool-" __stringify(x) } -#if (SG_CHUNK_SIZE < 32) -#error SG_CHUNK_SIZE is too small (must be 32 or greater) -#endif -static struct sg_pool sg_pools[] = { - SP(8), - SP(16), -#if (SG_CHUNK_SIZE > 32) - SP(32), -#if (SG_CHUNK_SIZE > 64) - SP(64), -#if (SG_CHUNK_SIZE > 128) - SP(128), -#if (SG_CHUNK_SIZE > 256) -#error SG_CHUNK_SIZE is too large (256 MAX) -#endif -#endif -#endif -#endif - SP(SG_CHUNK_SIZE) -}; -#undef SP - struct kmem_cache *scsi_sdb_cache; /* @@ -553,65 +518,6 @@ void scsi_run_host_queues(struct Scsi_Host *shost) scsi_run_queue(sdev->request_queue); } -static inline unsigned int sg_pool_index(unsigned short nents) -{ - unsigned int index; - - BUG_ON(nents > SG_CHUNK_SIZE); - - if (nents <= 8) - index = 0; - else - index = get_count_order(nents) - 3; - - return index; -} - -static void sg_pool_free(struct scatterlist *sgl, unsigned int nents) -{ - struct sg_pool *sgp; - - sgp = sg_pools + sg_pool_index(nents); - mempool_free(sgl, sgp->pool); -} - -static struct scatterlist *sg_pool_alloc(unsigned int nents, gfp_t gfp_mask) -{ - struct sg_pool *sgp; - - sgp = sg_pools + sg_pool_index(nents); - return mempool_alloc(sgp->pool, gfp_mask); -} - -static void sg_free_table_chained(struct sg_table *table, bool first_chunk) -{ - if (first_chunk && table->orig_nents <= SG_CHUNK_SIZE) - return; - __sg_free_table(table, SG_CHUNK_SIZE, first_chunk, sg_pool_free); -} - -static int sg_alloc_table_chained(struct sg_table *table, int nents, - struct scatterlist *first_chunk) -{ - int ret; - - BUG_ON(!nents); - - if (first_chunk) { - if (nents <= SG_CHUNK_SIZE) { - table->nents = table->orig_nents = nents; - sg_init_table(table->sgl, nents); - return 0; - } - } - - ret = __sg_alloc_table(table, nents, SG_CHUNK_SIZE, - first_chunk, GFP_ATOMIC, sg_pool_alloc); - if (unlikely(ret)) - sg_free_table_chained(table, (bool)first_chunk); - return ret; -} - static void scsi_uninit_cmd(struct scsi_cmnd *cmd) { if (cmd->request->cmd_type == REQ_TYPE_FS) { @@ -2269,8 +2175,6 @@ EXPORT_SYMBOL(scsi_unblock_requests); int __init scsi_init_queue(void) { - int i; - scsi_sdb_cache = kmem_cache_create("scsi_data_buffer", sizeof(struct scsi_data_buffer), 0, 0, NULL); @@ -2279,53 +2183,12 @@ int __init scsi_init_queue(void) return -ENOMEM; } - for (i = 0; i < SG_MEMPOOL_NR; i++) { - struct sg_pool *sgp = sg_pools + i; - int size = sgp->size * sizeof(struct scatterlist); - - sgp->slab = kmem_cache_create(sgp->name, size, 0, - SLAB_HWCACHE_ALIGN, NULL); - if (!sgp->slab) { - printk(KERN_ERR "SCSI: can't init sg slab %s\n", - sgp->name); - goto cleanup_sdb; - } - - sgp->pool = mempool_create_slab_pool(SG_MEMPOOL_SIZE, - sgp->slab); - if (!sgp->pool) { - printk(KERN_ERR "SCSI: can't init sg mempool %s\n", - sgp->name); - goto cleanup_sdb; - } - } - return 0; - -cleanup_sdb: - for (i = 0; i < SG_MEMPOOL_NR; i++) { - struct sg_pool *sgp = sg_pools + i; - if (sgp->pool) - mempool_destroy(sgp->pool); - if (sgp->slab) - kmem_cache_destroy(sgp->slab); - } - kmem_cache_destroy(scsi_sdb_cache); - - return -ENOMEM; } void scsi_exit_queue(void) { - int i; - kmem_cache_destroy(scsi_sdb_cache); - - for (i = 0; i < SG_MEMPOOL_NR; i++) { - struct sg_pool *sgp = sg_pools + i; - mempool_destroy(sgp->pool); - kmem_cache_destroy(sgp->slab); - } } /** -- cgit v1.2.3