Commit d0b3517d authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jason Gunthorpe
Browse files

PCI/P2PDMA: use the dev_pagemap internal refcount



The functionality is identical to the one currently open coded in
p2pdma.c.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarIra Weiny <ira.weiny@intel.com>
Reviewed-by: default avatarLogan Gunthorpe <logang@deltatee.com>
Tested-by: default avatarLogan Gunthorpe <logang@deltatee.com>
Reviewed-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent ea31d585
Loading
Loading
Loading
Loading
+4 −53
Original line number Diff line number Diff line
@@ -25,12 +25,6 @@ struct pci_p2pdma {
	bool p2pmem_published;
};

struct p2pdma_pagemap {
	struct dev_pagemap pgmap;
	struct percpu_ref ref;
	struct completion ref_done;
};

static ssize_t size_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
@@ -79,32 +73,6 @@ static const struct attribute_group p2pmem_group = {
	.name = "p2pmem",
};

static struct p2pdma_pagemap *to_p2p_pgmap(struct percpu_ref *ref)
{
	return container_of(ref, struct p2pdma_pagemap, ref);
}

static void pci_p2pdma_percpu_release(struct percpu_ref *ref)
{
	struct p2pdma_pagemap *p2p_pgmap = to_p2p_pgmap(ref);

	complete(&p2p_pgmap->ref_done);
}

static void pci_p2pdma_percpu_kill(struct dev_pagemap *pgmap)
{
	percpu_ref_kill(pgmap->ref);
}

static void pci_p2pdma_percpu_cleanup(struct dev_pagemap *pgmap)
{
	struct p2pdma_pagemap *p2p_pgmap =
		container_of(pgmap, struct p2pdma_pagemap, pgmap);

	wait_for_completion(&p2p_pgmap->ref_done);
	percpu_ref_exit(&p2p_pgmap->ref);
}

static void pci_p2pdma_release(void *data)
{
	struct pci_dev *pdev = data;
@@ -154,11 +122,6 @@ out:
	return error;
}

static const struct dev_pagemap_ops pci_p2pdma_pagemap_ops = {
	.kill		= pci_p2pdma_percpu_kill,
	.cleanup	= pci_p2pdma_percpu_cleanup,
};

/**
 * pci_p2pdma_add_resource - add memory for use as p2p memory
 * @pdev: the device to add the memory to
@@ -172,7 +135,6 @@ static const struct dev_pagemap_ops pci_p2pdma_pagemap_ops = {
int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
			    u64 offset)
{
	struct p2pdma_pagemap *p2p_pgmap;
	struct dev_pagemap *pgmap;
	void *addr;
	int error;
@@ -195,26 +157,15 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
			return error;
	}

	p2p_pgmap = devm_kzalloc(&pdev->dev, sizeof(*p2p_pgmap), GFP_KERNEL);
	if (!p2p_pgmap)
	pgmap = devm_kzalloc(&pdev->dev, sizeof(*pgmap), GFP_KERNEL);
	if (!pgmap)
		return -ENOMEM;

	init_completion(&p2p_pgmap->ref_done);
	error = percpu_ref_init(&p2p_pgmap->ref,
			pci_p2pdma_percpu_release, 0, GFP_KERNEL);
	if (error)
		goto pgmap_free;

	pgmap = &p2p_pgmap->pgmap;

	pgmap->res.start = pci_resource_start(pdev, bar) + offset;
	pgmap->res.end = pgmap->res.start + size - 1;
	pgmap->res.flags = pci_resource_flags(pdev, bar);
	pgmap->ref = &p2p_pgmap->ref;
	pgmap->type = MEMORY_DEVICE_PCI_P2PDMA;
	pgmap->pci_p2pdma_bus_offset = pci_bus_address(pdev, bar) -
		pci_resource_start(pdev, bar);
	pgmap->ops = &pci_p2pdma_pagemap_ops;

	addr = devm_memremap_pages(&pdev->dev, pgmap);
	if (IS_ERR(addr)) {
@@ -225,7 +176,7 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
	error = gen_pool_add_owner(pdev->p2pdma->pool, (unsigned long)addr,
			pci_bus_address(pdev, bar) + offset,
			resource_size(&pgmap->res), dev_to_node(&pdev->dev),
			&p2p_pgmap->ref);
			pgmap->ref);
	if (error)
		goto pages_free;

@@ -237,7 +188,7 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
pages_free:
	devm_memunmap_pages(&pdev->dev, pgmap);
pgmap_free:
	devm_kfree(&pdev->dev, p2p_pgmap);
	devm_kfree(&pdev->dev, pgmap);
	return error;
}
EXPORT_SYMBOL_GPL(pci_p2pdma_add_resource);