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 */ 105a0e3ad6STejun Heo #include <linux/slab.h> 1186db1e29SJens Axboe 1286db1e29SJens Axboe #include "blk.h" 1386db1e29SJens Axboe 1486db1e29SJens Axboe /* 1586db1e29SJens Axboe * For io context allocations 1686db1e29SJens Axboe */ 1786db1e29SJens Axboe static struct kmem_cache *iocontext_cachep; 1886db1e29SJens Axboe 196e736be7STejun Heo /** 206e736be7STejun Heo * get_io_context - increment reference count to io_context 216e736be7STejun Heo * @ioc: io_context to get 226e736be7STejun Heo * 236e736be7STejun Heo * Increment reference count to @ioc. 246e736be7STejun Heo */ 256e736be7STejun Heo void get_io_context(struct io_context *ioc) 266e736be7STejun Heo { 276e736be7STejun Heo BUG_ON(atomic_long_read(&ioc->refcount) <= 0); 286e736be7STejun Heo atomic_long_inc(&ioc->refcount); 296e736be7STejun Heo } 306e736be7STejun Heo EXPORT_SYMBOL(get_io_context); 316e736be7STejun Heo 3286db1e29SJens Axboe static void cfq_dtor(struct io_context *ioc) 3386db1e29SJens Axboe { 34ffc4e759SJens Axboe if (!hlist_empty(&ioc->cic_list)) { 35ffc4e759SJens Axboe struct cfq_io_context *cic; 3686db1e29SJens Axboe 37e2bd9678SPaul Bolle cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context, 38ffc4e759SJens Axboe cic_list); 39ffc4e759SJens Axboe cic->dtor(ioc); 40ffc4e759SJens Axboe } 4186db1e29SJens Axboe } 4286db1e29SJens Axboe 4342ec57a8STejun Heo /** 4442ec57a8STejun Heo * put_io_context - put a reference of io_context 4542ec57a8STejun Heo * @ioc: io_context to put 4642ec57a8STejun Heo * 4742ec57a8STejun Heo * Decrement reference count of @ioc and release it if the count reaches 4842ec57a8STejun Heo * zero. 4986db1e29SJens Axboe */ 5042ec57a8STejun Heo void put_io_context(struct io_context *ioc) 5186db1e29SJens Axboe { 5286db1e29SJens Axboe if (ioc == NULL) 5342ec57a8STejun Heo return; 5486db1e29SJens Axboe 5542ec57a8STejun Heo BUG_ON(atomic_long_read(&ioc->refcount) <= 0); 5686db1e29SJens Axboe 5742ec57a8STejun Heo if (!atomic_long_dec_and_test(&ioc->refcount)) 5842ec57a8STejun Heo return; 5942ec57a8STejun Heo 6086db1e29SJens Axboe rcu_read_lock(); 6186db1e29SJens Axboe cfq_dtor(ioc); 6207416d29SJens Axboe rcu_read_unlock(); 6386db1e29SJens Axboe 6486db1e29SJens Axboe kmem_cache_free(iocontext_cachep, ioc); 6586db1e29SJens Axboe } 6686db1e29SJens Axboe EXPORT_SYMBOL(put_io_context); 6786db1e29SJens Axboe 6886db1e29SJens Axboe static void cfq_exit(struct io_context *ioc) 6986db1e29SJens Axboe { 7086db1e29SJens Axboe rcu_read_lock(); 7186db1e29SJens Axboe 72ffc4e759SJens Axboe if (!hlist_empty(&ioc->cic_list)) { 73ffc4e759SJens Axboe struct cfq_io_context *cic; 74ffc4e759SJens Axboe 75e2bd9678SPaul Bolle cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context, 76ffc4e759SJens Axboe cic_list); 77ffc4e759SJens Axboe cic->exit(ioc); 78ffc4e759SJens Axboe } 79ffc4e759SJens Axboe rcu_read_unlock(); 8086db1e29SJens Axboe } 8186db1e29SJens Axboe 8227667c99SBart Van Assche /* Called by the exiting task */ 83b69f2292SLouis Rilling void exit_io_context(struct task_struct *task) 8486db1e29SJens Axboe { 8586db1e29SJens Axboe struct io_context *ioc; 8686db1e29SJens Axboe 876e736be7STejun Heo /* PF_EXITING prevents new io_context from being attached to @task */ 886e736be7STejun Heo WARN_ON_ONCE(!(current->flags & PF_EXITING)); 896e736be7STejun Heo 90b69f2292SLouis Rilling task_lock(task); 91b69f2292SLouis Rilling ioc = task->io_context; 92b69f2292SLouis Rilling task->io_context = NULL; 93b69f2292SLouis Rilling task_unlock(task); 9486db1e29SJens Axboe 9527667c99SBart Van Assche if (atomic_dec_and_test(&ioc->nr_tasks)) 9686db1e29SJens Axboe cfq_exit(ioc); 9786db1e29SJens Axboe 9861cc74fbSLouis Rilling put_io_context(ioc); 9986db1e29SJens Axboe } 10086db1e29SJens Axboe 1016e736be7STejun Heo static struct io_context *create_task_io_context(struct task_struct *task, 1026e736be7STejun Heo gfp_t gfp_flags, int node, 1036e736be7STejun Heo bool take_ref) 10486db1e29SJens Axboe { 105df415656SPaul Bolle struct io_context *ioc; 10686db1e29SJens Axboe 10742ec57a8STejun Heo ioc = kmem_cache_alloc_node(iocontext_cachep, gfp_flags | __GFP_ZERO, 10842ec57a8STejun Heo node); 10942ec57a8STejun Heo if (unlikely(!ioc)) 11042ec57a8STejun Heo return NULL; 11142ec57a8STejun Heo 11242ec57a8STejun Heo /* initialize */ 113df415656SPaul Bolle atomic_long_set(&ioc->refcount, 1); 114df415656SPaul Bolle atomic_set(&ioc->nr_tasks, 1); 115df415656SPaul Bolle spin_lock_init(&ioc->lock); 116df415656SPaul Bolle INIT_RADIX_TREE(&ioc->radix_root, GFP_ATOMIC | __GFP_HIGH); 117df415656SPaul Bolle INIT_HLIST_HEAD(&ioc->cic_list); 11886db1e29SJens Axboe 1196e736be7STejun Heo /* try to install, somebody might already have beaten us to it */ 1206e736be7STejun Heo task_lock(task); 1216e736be7STejun Heo 1226e736be7STejun Heo if (!task->io_context && !(task->flags & PF_EXITING)) { 1236e736be7STejun Heo task->io_context = ioc; 1246e736be7STejun Heo } else { 1256e736be7STejun Heo kmem_cache_free(iocontext_cachep, ioc); 1266e736be7STejun Heo ioc = task->io_context; 1276e736be7STejun Heo } 1286e736be7STejun Heo 1296e736be7STejun Heo if (ioc && take_ref) 1306e736be7STejun Heo get_io_context(ioc); 1316e736be7STejun Heo 1326e736be7STejun Heo task_unlock(task); 133df415656SPaul Bolle return ioc; 13486db1e29SJens Axboe } 13586db1e29SJens Axboe 13642ec57a8STejun Heo /** 13742ec57a8STejun Heo * current_io_context - get io_context of %current 13842ec57a8STejun Heo * @gfp_flags: allocation flags, used if allocation is necessary 13942ec57a8STejun Heo * @node: allocation node, used if allocation is necessary 14086db1e29SJens Axboe * 14142ec57a8STejun Heo * Return io_context of %current. If it doesn't exist, it is created with 14242ec57a8STejun Heo * @gfp_flags and @node. The returned io_context does NOT have its 14342ec57a8STejun Heo * reference count incremented. Because io_context is exited only on task 14442ec57a8STejun Heo * exit, %current can be sure that the returned io_context is valid and 14542ec57a8STejun Heo * alive as long as it is executing. 14686db1e29SJens Axboe */ 14786db1e29SJens Axboe struct io_context *current_io_context(gfp_t gfp_flags, int node) 14886db1e29SJens Axboe { 1496e736be7STejun Heo might_sleep_if(gfp_flags & __GFP_WAIT); 15086db1e29SJens Axboe 1516e736be7STejun Heo if (current->io_context) 1526e736be7STejun Heo return current->io_context; 15386db1e29SJens Axboe 1546e736be7STejun Heo return create_task_io_context(current, gfp_flags, node, false); 15586db1e29SJens Axboe } 1566e736be7STejun Heo EXPORT_SYMBOL(current_io_context); 15786db1e29SJens Axboe 1586e736be7STejun Heo /** 1596e736be7STejun Heo * get_task_io_context - get io_context of a task 1606e736be7STejun Heo * @task: task of interest 1616e736be7STejun Heo * @gfp_flags: allocation flags, used if allocation is necessary 1626e736be7STejun Heo * @node: allocation node, used if allocation is necessary 16386db1e29SJens Axboe * 1646e736be7STejun Heo * Return io_context of @task. If it doesn't exist, it is created with 1656e736be7STejun Heo * @gfp_flags and @node. The returned io_context has its reference count 1666e736be7STejun Heo * incremented. 1676e736be7STejun Heo * 1686e736be7STejun Heo * This function always goes through task_lock() and it's better to use 1696e736be7STejun Heo * current_io_context() + get_io_context() for %current. 17086db1e29SJens Axboe */ 1716e736be7STejun Heo struct io_context *get_task_io_context(struct task_struct *task, 1726e736be7STejun Heo gfp_t gfp_flags, int node) 17386db1e29SJens Axboe { 1746e736be7STejun Heo struct io_context *ioc; 17586db1e29SJens Axboe 1766e736be7STejun Heo might_sleep_if(gfp_flags & __GFP_WAIT); 17786db1e29SJens Axboe 1786e736be7STejun Heo task_lock(task); 1796e736be7STejun Heo ioc = task->io_context; 1806e736be7STejun Heo if (likely(ioc)) { 1816e736be7STejun Heo get_io_context(ioc); 1826e736be7STejun Heo task_unlock(task); 183df415656SPaul Bolle return ioc; 18486db1e29SJens Axboe } 1856e736be7STejun Heo task_unlock(task); 1866e736be7STejun Heo 1876e736be7STejun Heo return create_task_io_context(task, gfp_flags, node, true); 1886e736be7STejun Heo } 1896e736be7STejun Heo EXPORT_SYMBOL(get_task_io_context); 19086db1e29SJens Axboe 191dc86900eSTejun Heo void ioc_set_changed(struct io_context *ioc, int which) 192dc86900eSTejun Heo { 193dc86900eSTejun Heo struct cfq_io_context *cic; 194dc86900eSTejun Heo struct hlist_node *n; 195dc86900eSTejun Heo 196dc86900eSTejun Heo hlist_for_each_entry(cic, n, &ioc->cic_list, cic_list) 197dc86900eSTejun Heo set_bit(which, &cic->changed); 198dc86900eSTejun Heo } 199dc86900eSTejun Heo 200dc86900eSTejun Heo /** 201dc86900eSTejun Heo * ioc_ioprio_changed - notify ioprio change 202dc86900eSTejun Heo * @ioc: io_context of interest 203dc86900eSTejun Heo * @ioprio: new ioprio 204dc86900eSTejun Heo * 205dc86900eSTejun Heo * @ioc's ioprio has changed to @ioprio. Set %CIC_IOPRIO_CHANGED for all 206dc86900eSTejun Heo * cic's. iosched is responsible for checking the bit and applying it on 207dc86900eSTejun Heo * request issue path. 208dc86900eSTejun Heo */ 209dc86900eSTejun Heo void ioc_ioprio_changed(struct io_context *ioc, int ioprio) 210dc86900eSTejun Heo { 211dc86900eSTejun Heo unsigned long flags; 212dc86900eSTejun Heo 213dc86900eSTejun Heo spin_lock_irqsave(&ioc->lock, flags); 214dc86900eSTejun Heo ioc->ioprio = ioprio; 215dc86900eSTejun Heo ioc_set_changed(ioc, CIC_IOPRIO_CHANGED); 216dc86900eSTejun Heo spin_unlock_irqrestore(&ioc->lock, flags); 217dc86900eSTejun Heo } 218dc86900eSTejun Heo 219dc86900eSTejun Heo /** 220dc86900eSTejun Heo * ioc_cgroup_changed - notify cgroup change 221dc86900eSTejun Heo * @ioc: io_context of interest 222dc86900eSTejun Heo * 223dc86900eSTejun Heo * @ioc's cgroup has changed. Set %CIC_CGROUP_CHANGED for all cic's. 224dc86900eSTejun Heo * iosched is responsible for checking the bit and applying it on request 225dc86900eSTejun Heo * issue path. 226dc86900eSTejun Heo */ 227dc86900eSTejun Heo void ioc_cgroup_changed(struct io_context *ioc) 228dc86900eSTejun Heo { 229dc86900eSTejun Heo unsigned long flags; 230dc86900eSTejun Heo 231dc86900eSTejun Heo spin_lock_irqsave(&ioc->lock, flags); 232dc86900eSTejun Heo ioc_set_changed(ioc, CIC_CGROUP_CHANGED); 233dc86900eSTejun Heo spin_unlock_irqrestore(&ioc->lock, flags); 234dc86900eSTejun Heo } 235dc86900eSTejun Heo 23613341598SAdrian Bunk static int __init blk_ioc_init(void) 23786db1e29SJens Axboe { 23886db1e29SJens Axboe iocontext_cachep = kmem_cache_create("blkdev_ioc", 23986db1e29SJens Axboe sizeof(struct io_context), 0, SLAB_PANIC, NULL); 24086db1e29SJens Axboe return 0; 24186db1e29SJens Axboe } 24286db1e29SJens Axboe subsys_initcall(blk_ioc_init); 243