mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
dax/fsdev: clear pgmap ops and owner on unbind
fsdev_dax_probe() sets pgmap->ops = &fsdev_pagemap_ops and
pgmap->owner = dev_dax, but nothing ever clears them. For a dynamic
device the pgmap is devm-allocated and freed on unbind, so this is
harmless. For a static device the pgmap is the shared, long-lived one
owned by the dax bus (kill_dev_dax() only NULLs dev_dax->pgmap for the
non-static case), and device.c's probe sets only pgmap->type, never
clearing ops/owner.
So after fsdev unbinds a static device the stale fsdev_pagemap_ops
survives on the shared pgmap. If the device is then rebound to
device_dax (MEMORY_DEVICE_GENERIC, which installs no ->memory_failure),
or the fsdev_dax module is unloaded, a subsequent memory_failure on that
pgmap dispatches through the stale -- and possibly freed -- handler.
Register a devm action that clears pgmap->ops and pgmap->owner on unbind,
symmetric with setting them at probe, so the pgmap carries no fsdev state
once fsdev is detached.
Suggested-by: Richard Cheng <icheng@nvidia.com>
Fixes: d5406bd458 ("dax: add fsdev.c driver for fs-dax on character dax")
Signed-off-by: John Groves <john@groves.net>
Reviewed-by: Richard Cheng <icheng@nvidia.com>
Link: https://patch.msgid.link/0100019ecc094b6e-fc163bde-0396-4a33-909f-fb88e740be27-000000@email.amazonses.com
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
This commit is contained in:
parent
caf906009d
commit
f48884ac31
|
|
@ -127,6 +127,23 @@ static void fsdev_clear_ops(void *data)
|
|||
dax_set_ops(dev_dax->dax_dev, NULL);
|
||||
}
|
||||
|
||||
static void fsdev_clear_pgmap_ops(void *data)
|
||||
{
|
||||
struct dev_pagemap *pgmap = data;
|
||||
|
||||
/*
|
||||
* fsdev installs pgmap->ops and ->owner at probe. For a static device
|
||||
* the pgmap is shared and long-lived (owned by the dax bus), so
|
||||
* leaving fsdev's ops behind on unbind would let a later
|
||||
* memory_failure -- after rebind to another driver, or after this
|
||||
* module is unloaded -- dispatch through a stale or freed
|
||||
* ->memory_failure handler. Clear them so the pgmap carries no fsdev
|
||||
* state once we are unbound.
|
||||
*/
|
||||
pgmap->ops = NULL;
|
||||
pgmap->owner = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Page map operations for FS-DAX mode
|
||||
* Similar to fsdax_pagemap_ops in drivers/nvdimm/pmem.c
|
||||
|
|
@ -306,6 +323,11 @@ static int fsdev_dax_probe(struct dev_dax *dev_dax)
|
|||
if (IS_ERR(addr))
|
||||
return PTR_ERR(addr);
|
||||
|
||||
/* Drop fsdev's pgmap->ops/owner on unbind so no stale ops survive. */
|
||||
rc = devm_add_action_or_reset(dev, fsdev_clear_pgmap_ops, pgmap);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* Clear any stale compound folio state left over from a previous
|
||||
* driver (e.g., device_dax with vmemmap_shift). Also register this
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user