PCI/P2PDMA: Add sysfs group to display p2pmem stats
authorLogan Gunthorpe <logang@deltatee.com>
Thu, 4 Oct 2018 21:27:36 +0000 (15:27 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 17 Oct 2018 17:18:15 +0000 (12:18 -0500)
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: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Documentation/ABI/testing/sysfs-bus-pci
drivers/pci/p2pdma.c

index 44d4b2be92fd4a56ab2420944f76669a2466a304..8bfee557e50eab1fc66cbd3bc790731f1719bd04 100644 (file)
@@ -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.
index 24d0dbb36ba6ff9a4f65c54ee8ddae2aee1e2701..a8d484ddc5ad56da4273bdd670f5dfb8a4cb175a 100644 (file)
@@ -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);