block: loop: don't hold lo_ctl_mutex in lo_open
authorMing Lei <ming.lei@canonical.com>
Wed, 6 May 2015 04:26:23 +0000 (12:26 +0800)
committerJens Axboe <axboe@fb.com>
Wed, 20 May 2015 15:06:09 +0000 (09:06 -0600)
commitf8933667953e8e61bb6104f5ca88e32e85656a93
tree25f3b20d8c1d27ac856a43f6655d9604c524fa9e
parentb816d45fd56c57180b63a03412b9f898d5736c58
block: loop: don't hold lo_ctl_mutex in lo_open

The lo_ctl_mutex is held for running all ioctl handlers, and
in some ioctl handlers, ioctl_by_bdev(BLKRRPART) is called for
rereading partitions, which requires bd_mutex.

So it is easy to cause failure because trylock(bd_mutex) may
fail inside blkdev_reread_part(), and follows the lock context:

blkid or other application:
->open()
->mutex_lock(bd_mutex)
->lo_open()
->mutex_lock(lo_ctl_mutex)

losetup(set fd ioctl):
->mutex_lock(lo_ctl_mutex)
->ioctl_by_bdev(BLKRRPART)
->trylock(bd_mutex)

This patch trys to eliminate the ABBA lock dependency by removing
lo_ctl_mutext in lo_open() with the following approach:

1) make lo_refcnt as atomic_t and avoid acquiring lo_ctl_mutex in lo_open():
- for open vs. add/del loop, no any problem because of loop_index_mutex
- freeze request queue during clr_fd, so I/O can't come until
  clearing fd is completed, like the effect of holding lo_ctl_mutex
  in lo_open
- both open() and release() have been serialized by bd_mutex already

2) don't hold lo_ctl_mutex for decreasing/checking lo_refcnt in
lo_release(), then lo_ctl_mutex is only required for the last release.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Tested-by: Jarod Wilson <jarod@redhat.com>
Acked-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/block/loop.c
drivers/block/loop.h