Skip to content

Commit

Permalink
nvdimm/pmem: stop using q_usage_count as external pgmap refcount
Browse files Browse the repository at this point in the history
Originally all DAX access when through block_device operations and thus
needed a queue reference.  But since commit cccbce6
("filesystem-dax: convert to dax_direct_access()") all this happens at
the DAX device level which uses its own refcounting.  Having the external
refcount thus wasn't needed but has otherwise been harmless for long
time.

But now that "block: drain file system I/O on del_gendisk" waits for
q_usage_count to reach 0 in del_gendisk this whole scheme can't work
anymore (and pmem is the only driver abusing q_usage_count like that).
So switch to the internal reference and remove the unbalanced
blk_freeze_queue_start that is taken care of by del_gendisk.

Fixes: 8e141f9 ("block: drain file system I/O on del_gendisk")
Reported-by: Yi Zhang <[email protected]>
Signed-off-by: Christoph Hellwig <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Dan Williams <[email protected]>
  • Loading branch information
Christoph Hellwig authored and djbw committed Oct 25, 2021
1 parent 3906fe9 commit 3dd60fb
Showing 1 changed file with 2 additions and 31 deletions.
33 changes: 2 additions & 31 deletions drivers/nvdimm/pmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,39 +333,16 @@ static const struct attribute_group *pmem_attribute_groups[] = {
NULL,
};

static void pmem_pagemap_cleanup(struct dev_pagemap *pgmap)
{
struct pmem_device *pmem = pgmap->owner;

blk_cleanup_disk(pmem->disk);
}

static void pmem_release_queue(void *pgmap)
{
pmem_pagemap_cleanup(pgmap);
}

static void pmem_pagemap_kill(struct dev_pagemap *pgmap)
{
struct request_queue *q =
container_of(pgmap->ref, struct request_queue, q_usage_counter);

blk_freeze_queue_start(q);
}

static void pmem_release_disk(void *__pmem)
{
struct pmem_device *pmem = __pmem;

kill_dax(pmem->dax_dev);
put_dax(pmem->dax_dev);
del_gendisk(pmem->disk);
}

static const struct dev_pagemap_ops fsdax_pagemap_ops = {
.kill = pmem_pagemap_kill,
.cleanup = pmem_pagemap_cleanup,
};
blk_cleanup_disk(pmem->disk);
}

static int pmem_attach_disk(struct device *dev,
struct nd_namespace_common *ndns)
Expand Down Expand Up @@ -427,10 +404,8 @@ static int pmem_attach_disk(struct device *dev,
pmem->disk = disk;
pmem->pgmap.owner = pmem;
pmem->pfn_flags = PFN_DEV;
pmem->pgmap.ref = &q->q_usage_counter;
if (is_nd_pfn(dev)) {
pmem->pgmap.type = MEMORY_DEVICE_FS_DAX;
pmem->pgmap.ops = &fsdax_pagemap_ops;
addr = devm_memremap_pages(dev, &pmem->pgmap);
pfn_sb = nd_pfn->pfn_sb;
pmem->data_offset = le64_to_cpu(pfn_sb->dataoff);
Expand All @@ -444,16 +419,12 @@ static int pmem_attach_disk(struct device *dev,
pmem->pgmap.range.end = res->end;
pmem->pgmap.nr_range = 1;
pmem->pgmap.type = MEMORY_DEVICE_FS_DAX;
pmem->pgmap.ops = &fsdax_pagemap_ops;
addr = devm_memremap_pages(dev, &pmem->pgmap);
pmem->pfn_flags |= PFN_MAP;
bb_range = pmem->pgmap.range;
} else {
addr = devm_memremap(dev, pmem->phys_addr,
pmem->size, ARCH_MEMREMAP_PMEM);
if (devm_add_action_or_reset(dev, pmem_release_queue,
&pmem->pgmap))
return -ENOMEM;
bb_range.start = res->start;
bb_range.end = res->end;
}
Expand Down

0 comments on commit 3dd60fb

Please sign in to comment.