• Tejun Heo's avatar
    blkcg: use double locking instead of RCU for blkg synchronization · 9f13ef67
    Tejun Heo authored
    blkgs are chained from both blkcgs and request_queues and thus
    subjected to two locks - blkcg->lock and q->queue_lock.  As both blkcg
    and q can go away anytime, locking during removal is tricky.  It's
    currently solved by wrapping removal inside RCU, which makes the
    synchronization complex.  There are three locks to worry about - the
    outer RCU, q lock and blkcg lock, and it leads to nasty subtle
    complications like conditional synchronize_rcu() on queue exit paths.
    
    For all other paths, blkcg lock is naturally nested inside q lock and
    the only exception is blkcg removal path, which is a very cold path
    and can be implemented as clumsy but conceptually-simple reverse
    double lock dancing.
    
    This patch updates blkg removal path such that blkgs are removed while
    holding both q and blkcg locks, which is trivial for request queue
    exit path - blkg_destroy_all().  The blkcg removal path,
    blkiocg_pre_destroy(), implements reverse double lock dancing
    essentially identical to ioc_release_fn().
    
    This simplifies blkg locking - no half-dead blkgs to worry about.  Now
    unnecessary RCU annotations will be removed by the next patch.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Cc: Vivek Goyal <vgoyal@redhat.com>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    9f13ef67
blk-cgroup.c 46.5 KB