Commit cbb8ca69 authored by Logan Gunthorpe's avatar Logan Gunthorpe Committed by Bjorn Helgaas
Browse files

PCI/P2PDMA: Add sysfs group to display p2pmem stats



Add a sysfs group to display statistics about P2P memory that is registered
in each PCI device.

Attributes in the group display the total amount of P2P memory, the amount
available and whether it is published or not.

Signed-off-by: default avatarLogan Gunthorpe <logang@deltatee.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 52916982
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -323,3 +323,27 @@ Description:

		This is similar to /sys/bus/pci/drivers_autoprobe, but
		affects only the VFs associated with a specific PF.

What:		/sys/bus/pci/devices/.../p2pmem/size
Date:		November 2017
Contact:	Logan Gunthorpe <logang@deltatee.com>
Description:
		If the device has any Peer-to-Peer memory registered, this
	        file contains the total amount of memory that the device
		provides (in decimal).

What:		/sys/bus/pci/devices/.../p2pmem/available
Date:		November 2017
Contact:	Logan Gunthorpe <logang@deltatee.com>
Description:
		If the device has any Peer-to-Peer memory registered, this
	        file contains the amount of memory that has not been
		allocated (in decimal).

What:		/sys/bus/pci/devices/.../p2pmem/published
Date:		November 2017
Contact:	Logan Gunthorpe <logang@deltatee.com>
Description:
		If the device has any Peer-to-Peer memory registered, this
	        file contains a '1' if the memory has been published for
		use outside the driver that owns the device.
+54 −0
Original line number Diff line number Diff line
@@ -24,6 +24,54 @@ struct pci_p2pdma {
	bool p2pmem_published;
};

static ssize_t size_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	size_t size = 0;

	if (pdev->p2pdma->pool)
		size = gen_pool_size(pdev->p2pdma->pool);

	return snprintf(buf, PAGE_SIZE, "%zd\n", size);
}
static DEVICE_ATTR_RO(size);

static ssize_t available_show(struct device *dev, struct device_attribute *attr,
			      char *buf)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	size_t avail = 0;

	if (pdev->p2pdma->pool)
		avail = gen_pool_avail(pdev->p2pdma->pool);

	return snprintf(buf, PAGE_SIZE, "%zd\n", avail);
}
static DEVICE_ATTR_RO(available);

static ssize_t published_show(struct device *dev, struct device_attribute *attr,
			      char *buf)
{
	struct pci_dev *pdev = to_pci_dev(dev);

	return snprintf(buf, PAGE_SIZE, "%d\n",
			pdev->p2pdma->p2pmem_published);
}
static DEVICE_ATTR_RO(published);

static struct attribute *p2pmem_attrs[] = {
	&dev_attr_size.attr,
	&dev_attr_available.attr,
	&dev_attr_published.attr,
	NULL,
};

static const struct attribute_group p2pmem_group = {
	.attrs = p2pmem_attrs,
	.name = "p2pmem",
};

static void pci_p2pdma_percpu_release(struct percpu_ref *ref)
{
	struct pci_p2pdma *p2p =
@@ -59,6 +107,7 @@ static void pci_p2pdma_release(void *data)
	percpu_ref_exit(&pdev->p2pdma->devmap_ref);

	gen_pool_destroy(pdev->p2pdma->pool);
	sysfs_remove_group(&pdev->dev.kobj, &p2pmem_group);
	pdev->p2pdma = NULL;
}

@@ -87,9 +136,14 @@ static int pci_p2pdma_setup(struct pci_dev *pdev)

	pdev->p2pdma = p2p;

	error = sysfs_create_group(&pdev->dev.kobj, &p2pmem_group);
	if (error)
		goto out_pool_destroy;

	return 0;

out_pool_destroy:
	pdev->p2pdma = NULL;
	gen_pool_destroy(p2p->pool);
out:
	devm_kfree(&pdev->dev, p2p);