cfq-iosched: Fix a possible race with cfq cgroup removal code
authorVivek Goyal <vgoyal@redhat.com>
Thu, 19 May 2011 19:38:22 +0000 (15:38 -0400)
committerJens Axboe <jaxboe@fusionio.com>
Fri, 20 May 2011 18:34:52 +0000 (20:34 +0200)
commit56edf7d75db5b14d628b46623c414ffbeed68d7f
tree7d7ff46f03676154d0edf3da85c8e738d506ad92
parent3e59cf9d66a87763fef6c232a4a8dc664461ca50
cfq-iosched: Fix a possible race with cfq cgroup removal code

blkg->key = cfqd is an rcu protected pointer and hence we used to do
call_rcu(cfqd->rcu_head) to free up cfqd after one rcu grace period.

The problem here is that even though cfqd is around, there are no
gurantees that associated request queue (td->queue) or q->queue_lock
is still around. A driver might have called blk_cleanup_queue() and
release the lock.

It might happen that after freeing up the lock we call
blkg->key->queue->queue_ock and crash. This is possible in following
path.

blkiocg_destroy()
 blkio_unlink_group_fn()
  cfq_unlink_blkio_group()

Hence, wait for an rcu peirod if there are groups which have not
been unlinked from blkcg->blkg_list. That way, if there are any groups
which are taking cfq_unlink_blkio_group() path, can safely take queue
lock.

This is how we have taken care of race in throttling logic also.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
block/cfq-iosched.c