aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2009-12-06 03:54:19 -0500
committerJens Axboe <jens.axboe@oracle.com>2009-12-06 03:54:19 -0500
commitbb729bc98c0f3e6a898d8730df3e2830bf68751a (patch)
treef2170f8f688a7c7f813168a6c8c757087934c094 /block
parent846954b0a32f4ae953e082eabd178e7a98dd2efd (diff)
cfq-iosched: use call_rcu() instead of doing grace period stall on queue exit
After the merge of the IO controller patches, booting on my megaraid box ran much slower. Vivek Goyal traced it down to megaraid discovery creating tons of devices, each suffering a grace period when they later kill that queue (if no device is found). So lets use call_rcu() to batch these deferred frees, instead of taking the grace period hit for each one. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block')
-rw-r--r--block/cfq-iosched.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 78f4829895bd..3815f9789b6a 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -287,6 +287,7 @@ struct cfq_data {
287 287
288 /* List of cfq groups being managed on this device*/ 288 /* List of cfq groups being managed on this device*/
289 struct hlist_head cfqg_list; 289 struct hlist_head cfqg_list;
290 struct rcu_head rcu;
290}; 291};
291 292
292static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd); 293static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd);
@@ -3601,6 +3602,11 @@ static void cfq_put_async_queues(struct cfq_data *cfqd)
3601 cfq_put_queue(cfqd->async_idle_cfqq); 3602 cfq_put_queue(cfqd->async_idle_cfqq);
3602} 3603}
3603 3604
3605static void cfq_cfqd_free(struct rcu_head *head)
3606{
3607 kfree(container_of(head, struct cfq_data, rcu));
3608}
3609
3604static void cfq_exit_queue(struct elevator_queue *e) 3610static void cfq_exit_queue(struct elevator_queue *e)
3605{ 3611{
3606 struct cfq_data *cfqd = e->elevator_data; 3612 struct cfq_data *cfqd = e->elevator_data;
@@ -3630,8 +3636,7 @@ static void cfq_exit_queue(struct elevator_queue *e)
3630 cfq_shutdown_timer_wq(cfqd); 3636 cfq_shutdown_timer_wq(cfqd);
3631 3637
3632 /* Wait for cfqg->blkg->key accessors to exit their grace periods. */ 3638 /* Wait for cfqg->blkg->key accessors to exit their grace periods. */
3633 synchronize_rcu(); 3639 call_rcu(&cfqd->rcu, cfq_cfqd_free);
3634 kfree(cfqd);
3635} 3640}
3636 3641
3637static void *cfq_init_queue(struct request_queue *q) 3642static void *cfq_init_queue(struct request_queue *q)
@@ -3706,6 +3711,7 @@ static void *cfq_init_queue(struct request_queue *q)
3706 cfqd->cfq_group_isolation = 0; 3711 cfqd->cfq_group_isolation = 0;
3707 cfqd->hw_tag = -1; 3712 cfqd->hw_tag = -1;
3708 cfqd->last_end_sync_rq = jiffies; 3713 cfqd->last_end_sync_rq = jiffies;
3714 INIT_RCU_HEAD(&cfqd->rcu);
3709 return cfqd; 3715 return cfqd;
3710} 3716}
3711 3717