186db1e29SJens Axboe /* 286db1e29SJens Axboe * Functions related to io context handling 386db1e29SJens Axboe */ 486db1e29SJens Axboe #include <linux/kernel.h> 586db1e29SJens Axboe #include <linux/module.h> 686db1e29SJens Axboe #include <linux/init.h> 786db1e29SJens Axboe #include <linux/bio.h> 886db1e29SJens Axboe #include <linux/blkdev.h> 986db1e29SJens Axboe #include <linux/bootmem.h> /* for max_pfn/max_low_pfn */ 1086db1e29SJens Axboe 1186db1e29SJens Axboe #include "blk.h" 1286db1e29SJens Axboe 1386db1e29SJens Axboe /* 1486db1e29SJens Axboe * For io context allocations 1586db1e29SJens Axboe */ 1686db1e29SJens Axboe static struct kmem_cache *iocontext_cachep; 1786db1e29SJens Axboe 1886db1e29SJens Axboe static void cfq_dtor(struct io_context *ioc) 1986db1e29SJens Axboe { 20ffc4e759SJens Axboe if (!hlist_empty(&ioc->cic_list)) { 21ffc4e759SJens Axboe struct cfq_io_context *cic; 2286db1e29SJens Axboe 23ffc4e759SJens Axboe cic = list_entry(ioc->cic_list.first, struct cfq_io_context, 24ffc4e759SJens Axboe cic_list); 25ffc4e759SJens Axboe cic->dtor(ioc); 26ffc4e759SJens Axboe } 2786db1e29SJens Axboe } 2886db1e29SJens Axboe 2986db1e29SJens Axboe /* 3086db1e29SJens Axboe * IO Context helper functions. put_io_context() returns 1 if there are no 3186db1e29SJens Axboe * more users of this io context, 0 otherwise. 3286db1e29SJens Axboe */ 3386db1e29SJens Axboe int put_io_context(struct io_context *ioc) 3486db1e29SJens Axboe { 3586db1e29SJens Axboe if (ioc == NULL) 3686db1e29SJens Axboe return 1; 3786db1e29SJens Axboe 38d9c7d394SNikanth Karthikesan BUG_ON(atomic_long_read(&ioc->refcount) == 0); 3986db1e29SJens Axboe 40d9c7d394SNikanth Karthikesan if (atomic_long_dec_and_test(&ioc->refcount)) { 4186db1e29SJens Axboe rcu_read_lock(); 4286db1e29SJens Axboe if (ioc->aic && ioc->aic->dtor) 4386db1e29SJens Axboe ioc->aic->dtor(ioc->aic); 4486db1e29SJens Axboe cfq_dtor(ioc); 4507416d29SJens Axboe rcu_read_unlock(); 4686db1e29SJens Axboe 4786db1e29SJens Axboe kmem_cache_free(iocontext_cachep, ioc); 4886db1e29SJens Axboe return 1; 4986db1e29SJens Axboe } 5086db1e29SJens Axboe return 0; 5186db1e29SJens Axboe } 5286db1e29SJens Axboe EXPORT_SYMBOL(put_io_context); 5386db1e29SJens Axboe 5486db1e29SJens Axboe static void cfq_exit(struct io_context *ioc) 5586db1e29SJens Axboe { 5686db1e29SJens Axboe rcu_read_lock(); 5786db1e29SJens Axboe 58ffc4e759SJens Axboe if (!hlist_empty(&ioc->cic_list)) { 59ffc4e759SJens Axboe struct cfq_io_context *cic; 60ffc4e759SJens Axboe 61ffc4e759SJens Axboe cic = list_entry(ioc->cic_list.first, struct cfq_io_context, 62ffc4e759SJens Axboe cic_list); 63ffc4e759SJens Axboe cic->exit(ioc); 64ffc4e759SJens Axboe } 65ffc4e759SJens Axboe rcu_read_unlock(); 6686db1e29SJens Axboe } 6786db1e29SJens Axboe 6886db1e29SJens Axboe /* Called by the exitting task */ 6986db1e29SJens Axboe void exit_io_context(void) 7086db1e29SJens Axboe { 7186db1e29SJens Axboe struct io_context *ioc; 7286db1e29SJens Axboe 7386db1e29SJens Axboe task_lock(current); 7486db1e29SJens Axboe ioc = current->io_context; 7586db1e29SJens Axboe current->io_context = NULL; 7686db1e29SJens Axboe task_unlock(current); 7786db1e29SJens Axboe 7886db1e29SJens Axboe if (atomic_dec_and_test(&ioc->nr_tasks)) { 7986db1e29SJens Axboe if (ioc->aic && ioc->aic->exit) 8086db1e29SJens Axboe ioc->aic->exit(ioc->aic); 8186db1e29SJens Axboe cfq_exit(ioc); 8286db1e29SJens Axboe 8386db1e29SJens Axboe put_io_context(ioc); 8486db1e29SJens Axboe } 8586db1e29SJens Axboe } 8686db1e29SJens Axboe 8786db1e29SJens Axboe struct io_context *alloc_io_context(gfp_t gfp_flags, int node) 8886db1e29SJens Axboe { 8986db1e29SJens Axboe struct io_context *ret; 9086db1e29SJens Axboe 9186db1e29SJens Axboe ret = kmem_cache_alloc_node(iocontext_cachep, gfp_flags, node); 9286db1e29SJens Axboe if (ret) { 93d9c7d394SNikanth Karthikesan atomic_long_set(&ret->refcount, 1); 9486db1e29SJens Axboe atomic_set(&ret->nr_tasks, 1); 9586db1e29SJens Axboe spin_lock_init(&ret->lock); 9686db1e29SJens Axboe ret->ioprio_changed = 0; 9786db1e29SJens Axboe ret->ioprio = 0; 9886db1e29SJens Axboe ret->last_waited = jiffies; /* doesn't matter... */ 9986db1e29SJens Axboe ret->nr_batch_requests = 0; /* because this is 0 */ 10086db1e29SJens Axboe ret->aic = NULL; 10186db1e29SJens Axboe INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH); 102ffc4e759SJens Axboe INIT_HLIST_HEAD(&ret->cic_list); 10386db1e29SJens Axboe ret->ioc_data = NULL; 10486db1e29SJens Axboe } 10586db1e29SJens Axboe 10686db1e29SJens Axboe return ret; 10786db1e29SJens Axboe } 10886db1e29SJens Axboe 10986db1e29SJens Axboe /* 11086db1e29SJens Axboe * If the current task has no IO context then create one and initialise it. 11186db1e29SJens Axboe * Otherwise, return its existing IO context. 11286db1e29SJens Axboe * 11386db1e29SJens Axboe * This returned IO context doesn't have a specifically elevated refcount, 11486db1e29SJens Axboe * but since the current task itself holds a reference, the context can be 11586db1e29SJens Axboe * used in general code, so long as it stays within `current` context. 11686db1e29SJens Axboe */ 11786db1e29SJens Axboe struct io_context *current_io_context(gfp_t gfp_flags, int node) 11886db1e29SJens Axboe { 11986db1e29SJens Axboe struct task_struct *tsk = current; 12086db1e29SJens Axboe struct io_context *ret; 12186db1e29SJens Axboe 12286db1e29SJens Axboe ret = tsk->io_context; 12386db1e29SJens Axboe if (likely(ret)) 12486db1e29SJens Axboe return ret; 12586db1e29SJens Axboe 12686db1e29SJens Axboe ret = alloc_io_context(gfp_flags, node); 12786db1e29SJens Axboe if (ret) { 12886db1e29SJens Axboe /* make sure set_task_ioprio() sees the settings above */ 12986db1e29SJens Axboe smp_wmb(); 13086db1e29SJens Axboe tsk->io_context = ret; 13186db1e29SJens Axboe } 13286db1e29SJens Axboe 13386db1e29SJens Axboe return ret; 13486db1e29SJens Axboe } 13586db1e29SJens Axboe 13686db1e29SJens Axboe /* 13786db1e29SJens Axboe * If the current task has no IO context then create one and initialise it. 13886db1e29SJens Axboe * If it does have a context, take a ref on it. 13986db1e29SJens Axboe * 14086db1e29SJens Axboe * This is always called in the context of the task which submitted the I/O. 14186db1e29SJens Axboe */ 14286db1e29SJens Axboe struct io_context *get_io_context(gfp_t gfp_flags, int node) 14386db1e29SJens Axboe { 14486db1e29SJens Axboe struct io_context *ret = NULL; 14586db1e29SJens Axboe 14686db1e29SJens Axboe /* 14786db1e29SJens Axboe * Check for unlikely race with exiting task. ioc ref count is 14886db1e29SJens Axboe * zero when ioc is being detached. 14986db1e29SJens Axboe */ 15086db1e29SJens Axboe do { 15186db1e29SJens Axboe ret = current_io_context(gfp_flags, node); 15286db1e29SJens Axboe if (unlikely(!ret)) 15386db1e29SJens Axboe break; 154d9c7d394SNikanth Karthikesan } while (!atomic_long_inc_not_zero(&ret->refcount)); 15586db1e29SJens Axboe 15686db1e29SJens Axboe return ret; 15786db1e29SJens Axboe } 15886db1e29SJens Axboe EXPORT_SYMBOL(get_io_context); 15986db1e29SJens Axboe 16086db1e29SJens Axboe void copy_io_context(struct io_context **pdst, struct io_context **psrc) 16186db1e29SJens Axboe { 16286db1e29SJens Axboe struct io_context *src = *psrc; 16386db1e29SJens Axboe struct io_context *dst = *pdst; 16486db1e29SJens Axboe 16586db1e29SJens Axboe if (src) { 166d9c7d394SNikanth Karthikesan BUG_ON(atomic_long_read(&src->refcount) == 0); 167d9c7d394SNikanth Karthikesan atomic_long_inc(&src->refcount); 16886db1e29SJens Axboe put_io_context(dst); 16986db1e29SJens Axboe *pdst = src; 17086db1e29SJens Axboe } 17186db1e29SJens Axboe } 17286db1e29SJens Axboe EXPORT_SYMBOL(copy_io_context); 17386db1e29SJens Axboe 17413341598SAdrian Bunk static int __init blk_ioc_init(void) 17586db1e29SJens Axboe { 17686db1e29SJens Axboe iocontext_cachep = kmem_cache_create("blkdev_ioc", 17786db1e29SJens Axboe sizeof(struct io_context), 0, SLAB_PANIC, NULL); 17886db1e29SJens Axboe return 0; 17986db1e29SJens Axboe } 18086db1e29SJens Axboe subsys_initcall(blk_ioc_init); 181