PCI/P2PDMA: use the dev_pagemap internal refcount
The functionality is identical to the one currently open coded in p2pdma.c. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Logan Gunthorpe <logang@deltatee.com> Tested-by: Logan Gunthorpe <logang@deltatee.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
ea31d5859f
commit
d0b3517dbc
|
@ -25,12 +25,6 @@ struct pci_p2pdma {
|
||||||
bool p2pmem_published;
|
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,
|
static ssize_t size_show(struct device *dev, struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
|
@ -79,32 +73,6 @@ static const struct attribute_group p2pmem_group = {
|
||||||
.name = "p2pmem",
|
.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)
|
static void pci_p2pdma_release(void *data)
|
||||||
{
|
{
|
||||||
struct pci_dev *pdev = data;
|
struct pci_dev *pdev = data;
|
||||||
|
@ -154,11 +122,6 @@ out:
|
||||||
return error;
|
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
|
* pci_p2pdma_add_resource - add memory for use as p2p memory
|
||||||
* @pdev: the device to add the memory to
|
* @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,
|
int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
|
||||||
u64 offset)
|
u64 offset)
|
||||||
{
|
{
|
||||||
struct p2pdma_pagemap *p2p_pgmap;
|
|
||||||
struct dev_pagemap *pgmap;
|
struct dev_pagemap *pgmap;
|
||||||
void *addr;
|
void *addr;
|
||||||
int error;
|
int error;
|
||||||
|
@ -195,26 +157,15 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
p2p_pgmap = devm_kzalloc(&pdev->dev, sizeof(*p2p_pgmap), GFP_KERNEL);
|
pgmap = devm_kzalloc(&pdev->dev, sizeof(*pgmap), GFP_KERNEL);
|
||||||
if (!p2p_pgmap)
|
if (!pgmap)
|
||||||
return -ENOMEM;
|
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.start = pci_resource_start(pdev, bar) + offset;
|
||||||
pgmap->res.end = pgmap->res.start + size - 1;
|
pgmap->res.end = pgmap->res.start + size - 1;
|
||||||
pgmap->res.flags = pci_resource_flags(pdev, bar);
|
pgmap->res.flags = pci_resource_flags(pdev, bar);
|
||||||
pgmap->ref = &p2p_pgmap->ref;
|
|
||||||
pgmap->type = MEMORY_DEVICE_PCI_P2PDMA;
|
pgmap->type = MEMORY_DEVICE_PCI_P2PDMA;
|
||||||
pgmap->pci_p2pdma_bus_offset = pci_bus_address(pdev, bar) -
|
pgmap->pci_p2pdma_bus_offset = pci_bus_address(pdev, bar) -
|
||||||
pci_resource_start(pdev, bar);
|
pci_resource_start(pdev, bar);
|
||||||
pgmap->ops = &pci_p2pdma_pagemap_ops;
|
|
||||||
|
|
||||||
addr = devm_memremap_pages(&pdev->dev, pgmap);
|
addr = devm_memremap_pages(&pdev->dev, pgmap);
|
||||||
if (IS_ERR(addr)) {
|
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,
|
error = gen_pool_add_owner(pdev->p2pdma->pool, (unsigned long)addr,
|
||||||
pci_bus_address(pdev, bar) + offset,
|
pci_bus_address(pdev, bar) + offset,
|
||||||
resource_size(&pgmap->res), dev_to_node(&pdev->dev),
|
resource_size(&pgmap->res), dev_to_node(&pdev->dev),
|
||||||
&p2p_pgmap->ref);
|
pgmap->ref);
|
||||||
if (error)
|
if (error)
|
||||||
goto pages_free;
|
goto pages_free;
|
||||||
|
|
||||||
|
@ -237,7 +188,7 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
|
||||||
pages_free:
|
pages_free:
|
||||||
devm_memunmap_pages(&pdev->dev, pgmap);
|
devm_memunmap_pages(&pdev->dev, pgmap);
|
||||||
pgmap_free:
|
pgmap_free:
|
||||||
devm_kfree(&pdev->dev, p2p_pgmap);
|
devm_kfree(&pdev->dev, pgmap);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pci_p2pdma_add_resource);
|
EXPORT_SYMBOL_GPL(pci_p2pdma_add_resource);
|
||||||
|
|
Loading…
Reference in New Issue