aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
Commit message (Collapse)AuthorAge
* cfq-iosched: fix RCU problem in cfq_cic_lookup()Jens Axboe2008-05-28
| | | | | | | | | | | | | cfq_cic_lookup() needs to properly protect ioc->ioc_data before dereferencing it and also exclude updaters of ioc->ioc_data as well. Also add a number of comments documenting why the existing RCU usage is OK. Thanks a lot to "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> for review and comments! Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* block: reorder cfq_queue to save space on 64bit buildsRichard Kennedy2008-05-28
| | | | | | | | saves 8 bytes of padding & increases objects/slab from 30 to 32 on my AMD64 config Signed-off-by: Richard Kennedy <richard@rsk.demon.co.uk> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: make io priorities inherit CPU scheduling class as well as niceJens Axboe2008-05-07
| | | | | | | | We currently set all processes to the best-effort scheduling class, regardless of what CPU scheduling class they belong to. Improve that so that we correctly track idle and rt scheduling classes as well. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: fix RCU race in the cfq io_context destructor handlingJens Axboe2008-05-07
| | | | | | | | | | | | | | put_io_context() drops the RCU read lock before calling into cfq_dtor(), however we need to hold off freeing there before grabbing and dereferencing the first object on the list. So extend the rcu_read_lock() scope to cover the calling of cfq_dtor(), and optimize cfq_free_io_context() to use a new variant for call_for_each_cic() that assumes the RCU read lock is already held. Hit in the wild by Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: do not leak ioc_data across iosched switchesFabio Checconi2008-04-10
| | | | | | | | | | | | | | | | | | | | | When switching scheduler from cfq, cfq_exit_queue() does not clear ioc->ioc_data, leaving a dangling pointer that can deceive the following lookups when the iosched is switched back to cfq. The pattern that can trigger that is the following: - elevator switch from cfq to something else; - module unloading, with elv_unregister() that calls cfq_free_io_context() on ioc freeing the cic (via the .trim op); - module gets reloaded and the elevator switches back to cfq; - reallocation of a cic at the same address as before (with a valid key). To fix it just assign NULL to ioc_data in __cfq_exit_single_io_context(), that is called from the regular exit path and from the elevator switching code. The only path that frees a cic and is not covered is the error handling one, but cic's freed in this way are never cached in ioc_data. Signed-off-by: Fabio Checconi <fabio@gandalf.sssup.it> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: fix rcu freeing of cfq io contextsFabio Checconi2008-04-02
| | | | | | | | | | SLAB_DESTROY_BY_RCU is not a direct substitute for normal call_rcu() freeing, since it'll page freeing but NOT object freeing. So change cfq to do the freeing on its own. Signed-off-by: Fabio Checconi <fabio@gandalf.sssup.it> Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: add hlist for browsing parallel to the radix treeJens Axboe2008-02-19
| | | | | | | | | | | It's cumbersome to browse a radix tree from start to finish, especially since we modify keys when a process exits. So add a hlist for the single purpose of browsing over all known cfq_io_contexts, used for exit, io prio change, etc. This fixes http://bugzilla.kernel.org/show_bug.cgi?id=9948 Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: make checkpatch compliantJens Axboe2008-02-01
| | | | Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: kill some big inlinesJens Axboe2008-01-28
| | | | | | Use of inlines were a bit over the top, trim them down a bit. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: relax IOPRIO_CLASS_IDLE restrictionsJens Axboe2008-01-28
| | | | | | | | | | | | | | | | | Currently you must be root to set idle io prio class on a process. This is due to the fact that the idle class is implemented as a true idle class, meaning that it will not make progress if someone else is requesting disk access. Unfortunately this means that it opens DOS opportunities by locking down file system resources, hence it is root only at the moment. This patch relaxes the idle class a little, by removing the truly idle part (which entals a grace period with associated timer). The modifications make the idle class as close to zero impact as can be done while still guarenteeing progress. This means we can relax the root only criteria as well. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* block: cfq: make the io contect sharing locklessJens Axboe2008-01-28
| | | | | | | | | | | | | | | | | The io context sharing introduced a per-ioc spinlock, that would protect the cfq io context lookup. That is a regression from the original, since we never needed any locking there because the ioc/cic were process private. The cic lookup is changed from an rbtree construct to a radix tree, which we can then use RCU to make the reader side lockless. That is the performance critical path, modifying the radix tree is only done on process creation (when that process first does IO, actually) and on process exit (if that process has done IO). As it so happens, radix trees are also much faster for this type of lookup where the key is a pointer. It's a very sparse tree. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* io_context sharing - cfq changesNikanth Karthikesan2008-01-28
| | | | | | changes in the cfq for io_context sharing Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* ioprio: move io priority from task_struct to io_contextJens Axboe2008-01-28
| | | | | | | This is where it belongs and then it doesn't take up space for a process that doesn't do IO. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* block: let elv_register() return voidAdrian Bunk2007-12-18
| | | | | | | | | elv_register() always returns 0, and there isn't anything it does where it should return an error (the only error condition is so grave that it's handled with a BUG_ON). Signed-off-by: Adrian Bunk <bunk@kernel.org> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq_idle_class_timer: add paranoid checks for jiffies overflowOleg Nesterov2007-11-07
| | | | | | | | | In theory, if the queue was idle long enough, cfq_idle_class_timer may have a false (and very long) timeout because jiffies can wrap into the past wrt ->last_end_request. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq: fix IOPRIO_CLASS_IDLE delaysOleg Nesterov2007-11-07
| | | | | | | | | | | | | | | | | After the fresh boot: ionice -c3 -p $$ echo cfq >> /sys/block/XXX/queue/scheduler dd if=/dev/XXX of=/dev/null bs=512 count=1 Now dd hangs in D state and the queue is completely stalled for approximately INITIAL_JIFFIES + CFQ_IDLE_GRACE jiffies. This is because cfq_init_queue() forgets to initialize cfq_data->last_end_request. (I guess this patch is not complete, overflow is still possible) Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq: fix IOPRIO_CLASS_IDLE accountingOleg Nesterov2007-11-07
| | | | | | | | | | | Spotted by Nick <gentuu@gmail.com>, hopefully can explain the second trace in http://bugzilla.kernel.org/show_bug.cgi?id=9180. If ->async_idle_cfqq != NULL cfq_put_async_queues() puts it IOPRIO_BE_NR times in a loop. Fix this. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq_get_queue: fix possible NULL pointer accessOleg Nesterov2007-10-29
| | | | | | | | | | | | cfq_get_queue()->cfq_find_alloc_queue() can fail, check the returned value. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Note that this isn't a bug at the moment, since the regular IO path does not call this path without __GFP_WAIT set. However, it could be a future bug, so I've applied it. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq_exit_queue() should cancel cfq_data->unplug_workOleg Nesterov2007-10-29
| | | | | | | | | | | | | Spotted by Nick <gentuu@gmail.com>, perhaps explains the first trace in http://bugzilla.kernel.org/show_bug.cgi?id=9180. cfq_exit_queue() should cancel cfqd->unplug_work before freeing cfqd. blk_sync_queue() seems unneeded, removed. Q: why cfq_exit_queue() calls cfq_shutdown_timer_wq() twice? Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* [BLOCK] Get rid of request_queue_t typedefJens Axboe2007-07-24
| | | | | | | | | Some of the code has been gradually transitioned to using the proper struct request_queue, but there's lots left. So do a full sweet of the kernel and get rid of this typedef and replace its uses with the proper type. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq: Write-only stuff in CFQ data structuresAlexey Dobriyan2007-07-20
| | | | | | | | There are some leftover bits from the task cooperator patch, that was yanked out again. While it will get reintroduced, no point in having this write-only stuff in the tree. So yank it. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq: async queue allocation per priorityVasily Tarasov2007-07-20
| | | | | | | | | | | | If we have two processes with different ioprio_class, but the same ioprio_data, their async requests will fall into the same queue. I guess such behavior is not expected, because it's not right to put real-time requests and best-effort requests in the same queue. The attached patch fixes the problem by introducing additional *cfqq fields on cfqd, pointing to per-(class,priority) async queues. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* Slab allocators: Replace explicit zeroing with __GFP_ZEROChristoph Lameter2007-07-17
| | | | | | | | | | | | | kmalloc_node() and kmem_cache_alloc_node() were not available in a zeroing variant in the past. But with __GFP_ZERO it is possible now to do zeroing while allocating. Use __GFP_ZERO to remove the explicit clearing of memory via memset whereever we can. Signed-off-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* cfq-iosched: fix async queue behaviourJens Axboe2007-07-10
| | | | | | | | | | | With the cfq_queue hash removal, we inadvertently got rid of the async queue sharing. This was not intentional, in fact CFQ purposely shares the async queue per priority level to get good merging for async writes. So put some logic in cfq_get_queue() to track the shared queues. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* KMEM_CACHE(): simplify slab cache creationChristoph Lameter2007-05-07
| | | | | | | | | | | | | | | | | | | | | | | | | | | This patch provides a new macro KMEM_CACHE(<struct>, <flags>) to simplify slab creation. KMEM_CACHE creates a slab with the name of the struct, with the size of the struct and with the alignment of the struct. Additional slab flags may be specified if necessary. Example struct test_slab { int a,b,c; struct list_head; } __cacheline_aligned_in_smp; test_slab_cache = KMEM_CACHE(test_slab, SLAB_PANIC) will create a new slab named "test_slab" of the size sizeof(struct test_slab) and aligned to the alignment of test slab. If it fails then we panic. Signed-off-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* cfq-iosched: speedup cic rb lookupJens Axboe2007-04-30
| | | | | | | We often lookup the same queue many times in succession, so cache the last looked up queue to avoid browsing the rbtree. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: get rid of cfqq hashVasily Tarasov2007-04-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | cfq hash is no more necessary. We always can get cfqq from io context. cfq_get_io_context_noalloc() function is introduced, because we don't want to allocate cic on merging and checking may_queue. In order to identify sync queue we've used hash key = CFQ_KEY_ASYNC. Since hash is eliminated we need to use other criterion: sync flag for queue is added. In all places where we dig in rb_tree we're in current context, so no additional locking is required. Advantages of this patch: no additional memory for hash, no seeking in hash, code is cleaner. But it is necessary now to seek cic in per-ioc rbtree, but it is faster: - most processes work only with few devices - most systems have only few block devices - it is a rb-tree Signed-off-by: Vasily Tarasov <vtaras@openvz.org> Changes by me: - Merge into CFQ devel branch - Get rid of cfq_get_io_context_noalloc() - Fix various bugs with dereferencing cic->cfqq[] with offset other than 0 or 1. - Fix bug in cfqq setup, is_sync condition was reversed. - Fix bug where only bio_sync() is used, we need to check for a READ too Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: tighten queue request overlap conditionJens Axboe2007-04-30
| | | | | | | For tagged devices, allow overlap of requests if the idle window isn't enabled on the current active queue. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: improve sync vs async workloadsJens Axboe2007-04-30
| | | | Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: never allow an async queue idlingJens Axboe2007-04-30
| | | | | | | We don't enable it by default, don't let it get enabled during runtime. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: get rid of ->dispatch_sliceJens Axboe2007-04-30
| | | | | | | We can track it fairly accurately locally, let the slice handling take care of the rest. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: don't pass unused preemption variable aroundJens Axboe2007-04-30
| | | | | | We don't use it anymore in the slice expiry handling. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: get rid of ->cur_rr and ->cfq_listJens Axboe2007-04-30
| | | | | | | | | It's only used for preemption now that the IDLE and RT queues also use the rbtree. If we pass an 'add_front' variable to cfq_service_tree_add(), we can set ->rb_key to 0 to force insertion at the front of the tree. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: slice offset should take ioprio into accountJens Axboe2007-04-30
| | | | | | Use the max_slice-cur_slice as the multipler for the insertion offset. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* [PATCH] cfq-iosched: style cleanups and commentsJens Axboe2007-04-30
| | | | Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: sort IDLE queues into the rbtreeJens Axboe2007-04-30
| | | | | | | Same treatment as the RT conversion, just put the sorted idle branch at the end of the tree. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: sort RT queues into the rbtreeJens Axboe2007-04-30
| | | | | | | | | Currently CFQ does a linked insert into the current list for RT queues. We can just factor the class into the rb insertion, and then we don't have to treat RT queues in a special way. It's faster, too. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* [PATCH] cfq-iosched: speed up rbtree handlingJens Axboe2007-04-30
| | | | | | | | | | | | | | For cases where the rbtree is mainly used for sorting and min retrieval, a nice speedup of the rbtree code is to maintain a cache of the leftmost node in the tree. Also spotted in the CFS CPU scheduler code. Improved by Alan D. Brunelle <Alan.Brunelle@hp.com> by updating the leftmost hint in cfq_rb_first() if it isn't set, instead of only updating it on insert. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: rework the whole round-robin list conceptJens Axboe2007-04-30
| | | | | | | | | | | | | | | | | | | | | Drawing on some inspiration from the CFS CPU scheduler design, overhaul the pending cfq_queue concept list management. Currently CFQ uses a doubly linked list per priority level for sorting and service uses. Kill those lists and maintain an rbtree of cfq_queue's, sorted by when to service them. This unfortunately means that the ionice levels aren't as strong anymore, will work on improving those later. We only scale the slice time now, not the number of times we service. This means that latency is better (for all priority levels), but that the distinction between the highest and lower levels aren't as big. The diffstat speaks for itself. cfq-iosched.c | 363 +++++++++++++++++--------------------------------- 1 file changed, 125 insertions(+), 238 deletions(-) Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: minor updatesJens Axboe2007-04-30
| | | | | | | | | | | - Move the queue_new flag clear to when the queue is selected - Only select the non-first queue in cfq_get_best_queue(), if there's a substantial difference between the best and first. - Get rid of ->busy_rr - Only select a close cooperator, if the current queue is known to take a while to "think". Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: development updateJens Axboe2007-04-30
| | | | | | | | | | | | | | | | | | | | | | | - Implement logic for detecting cooperating processes, so we choose the best available queue whenever possible. - Improve residual slice time accounting. - Remove dead code: we no longer see async requests coming in on sync queues. That part was removed a long time ago. That means that we can also remove the difference between cfq_cfqq_sync() and cfq_cfqq_class_sync(), they are now indentical. And we can kill the on_dispatch array, just make it a counter. - Allow a process to go into the current list, if it hasn't been serviced in this scheduler tick yet. Possible future improvements including caching the cfqq lookup in cfq_close_cooperator(), so we don't have to look it up twice. cfq_get_best_queue() should just use that last decision instead of doing it again. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: improve preemption for cooperating tasksJens Axboe2007-04-30
| | | | | | | | | | When testing the syslet async io approach, I discovered that CFQ sometimes didn't perform as well as expected. cfq_should_preempt() needs to better check for cooperating tasks, so fix that by allowing preemption of an equal priority queue if the recently queued request is as good a candidate for IO as the one we are currently waiting for. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: fix alias + front merge bugJens Axboe2007-04-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | There's a really rare and obscure bug in CFQ, that causes a crash in cfq_dispatch_insert() due to rq == NULL. One example of the resulting oops is seen here: http://lkml.org/lkml/2007/4/15/41 Neil correctly diagnosed the situation for how this can happen: if two concurrent requests with the exact same sector number (due to direct IO or aliasing between MD and the raw device access), the alias handling will add the request to the sortlist, but next_rq remains NULL. Read the more complete analysis at: http://lkml.org/lkml/2007/4/25/57 This looks like it requires md to trigger, even though it should potentially be possible to due with O_DIRECT (at least if you edit the kernel and doctor some of the unplug calls). The fix is to move the ->next_rq update to when we add a request to the rbtree. Then we remove the possibility for a request to exist in the rbtree code, but not have ->next_rq correctly updated. Signed-off-by: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* cfq-iosched: fix sequential write regressionJens Axboe2007-04-21
| | | | | | | | | | | | | | | We have a 10-15% performance regression for sequential writes on TCQ/NCQ enabled drives in 2.6.21-rcX after the CFQ update went in. It has been reported by Valerie Clement <valerie.clement@bull.net> and the Intel testing folks. The regression is because of CFQ's now more aggressive queue control, limiting the depth available to the device. This patches fixes that regression by allowing a greater depth when only one queue is busy. It has been tested to not impact sync-vs-async workloads too much - we still do a lot better than 2.6.20. Signed-off-by: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* cfq-iosched: improve continue or break logic in cfq_dispatchJens Axboe2007-02-11
| | | | | | | This improves performance considerably for sync requests when you have command queuing enabled. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: remove the implicit queue kicking in slice expireJens Axboe2007-02-11
| | | | | | | We only really need it for a process going away, so move it to those locations. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: check whether a queue timed out in accountingJens Axboe2007-02-11
| | | | | | Makes it more fair for the residual slice count. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: tweak the FIFO checkingJens Axboe2007-02-11
| | | | | | | | We currently check the FIFO once per slice. Optimize that a bit and only do it as the first thing for a new slice, so we don't end up doing a single request and then seek to the FIFO requests. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: don't pass in queue for cfq_arm_slice_timer()Jens Axboe2007-02-11
| | | | | | | It must always be the active queue, otherwise it's a bug. So just use the active_queue, don't pass it in explicitly. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
* cfq-iosched: account for slice over/under timeJens Axboe2007-02-11
| | | | | | | | If a slice uses less than it is entitled to (or perhaps more), include that in the decision on how much time to give it the next time it gets serviced. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>