Re: mm: GPF in bdi_put

From: Jan Kara
Date: Thu Mar 02 2017 - 07:57:14 EST


On Thu 02-03-17 11:44:53, Al Viro wrote:
> On Wed, Mar 01, 2017 at 03:29:09PM +0100, Jan Kara wrote:
>
> > The problem is writeback code (from flusher work or through sync(2) -
> > generally inode_to_bdi() users) can be looking at bdev inode independently
> > from it being open. So if they start looking while the bdev is open but the
> > dereference happens after it is closed and device removed, we oops. We have
> > seen oopses due to this for quite a while. And all the stuff that is done
> > in __blkdev_put() is not enough to prevent writeback code from having a
> > look whether there is not something to write.
>
> Um. What's to prevent the queue/device/module itself from disappearing
> from under you? IOW, what are you doing that is safe to do in face of
> driver going rmmoded?

So BDI does not have direct relation to the device itself. It is an
abstraction for some of the device properties / functionality and thus it
can live even after the device itself went away and the module got removed.
The only thing users of bdi want is to tell them whether the device is
congested or various statistics and dirty inode tracking for writeback
purposes and that is all independent of the particular device or whether it
still exists.

Technically there may be pointers bdi->dev, bdi->owner to the device which
are properly refcounted (so the device structure or module cannot be
removed under us). These references get dropped & cleared in
bdi_unregister() generally called from blk_cleanup_queue() (will be moved
to del_gendisk() soon) when the device is going away. This can happen while
e.g. bdev still references the bdi so users of bdi->dev or bdi->owner have
to be careful to sychronize against device removal and bdi_unregister() but
there are only very few such users.

Honza
--
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR