On Wed, Sep 23, 2015 at 2:04 AM, Dave Chinner <david(a)fromorbit.com> wrote:
On Tue, Sep 22, 2015 at 08:00:29PM -0700, Dan Williams wrote:
> The kaddr is coming from the devm_memremap() in the pmem driver that
> gets unmapped after the device is released by the driver.
Perhaps the better solution is to not tear down the block device
until all active references have gone away? i.e. unbind puts the
device into a persistent error state and forces all active mappings
to refault. Hence all future accesses error out and then when the
user unmounts the unhappy filesystem the last reference to the
blockdev goes away and the mappings can be torn down safely...
In fact this is how it already works in the block layer, it's just
that the pmem driver was not participating in that mechanism. The
filesystem prevents the gendisk and hosting driver module from going
away via the heavyweight get_disk(). The gendisk keeps the
request_queue from being de-allocated, but the queue can go "dead" to
new requests at any time. Single-queue based drivers take the
queue_lock and check blk_queue_dying() before allowing new requests.
Multi-queue drivers take a lighter-weight approach and try to get a
new "live" reference from a percpu_refcount.
When the backing device is unplugged or otherwise unbound from its
driver it calls blk_cleanup_queue() in its shutdown path. That marks
the queue dead and flushes any outstanding requests. From that point
forward all requests end in error until the final put_disk().
This is what I came up with for pmem: