vfio: Use GFP_KERNEL_ACCOUNT for userspace persistent allocations
authorJason Gunthorpe <jgg@nvidia.com>
Sun, 8 Jan 2023 15:44:24 +0000 (17:44 +0200)
committerAlex Williamson <alex.williamson@redhat.com>
Mon, 23 Jan 2023 18:26:29 +0000 (11:26 -0700)
Use GFP_KERNEL_ACCOUNT for userspace persistent allocations.

The GFP_KERNEL_ACCOUNT option lets the memory allocator know that this
is untrusted allocation triggered from userspace and should be a subject
of kmem accounting, and as such it is controlled by the cgroup
mechanism.

The way to find the relevant allocations was for example to look at the
close_device function and trace back all the kfrees to their
allocations.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/20230108154427.32609-4-yishaih@nvidia.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/container.c
drivers/vfio/pci/vfio_pci_config.c
drivers/vfio/pci/vfio_pci_core.c
drivers/vfio/pci/vfio_pci_igd.c
drivers/vfio/pci/vfio_pci_intrs.c
drivers/vfio/pci/vfio_pci_rdwr.c
drivers/vfio/virqfd.c

index b7a9560ab25e486ae88c4dfe9feab750972a22fb..5f398c493a1bfcd346a42b89cbf12feae71fd3f3 100644 (file)
@@ -367,7 +367,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
 {
        struct vfio_container *container;
 
-       container = kzalloc(sizeof(*container), GFP_KERNEL);
+       container = kzalloc(sizeof(*container), GFP_KERNEL_ACCOUNT);
        if (!container)
                return -ENOMEM;
 
index 4a350421c5f62a7a215b690d6b16d7a9dca7c83a..523e0144c86fab80bb619164bdfc0d9c38f15a21 100644 (file)
@@ -1244,7 +1244,7 @@ static int vfio_msi_cap_len(struct vfio_pci_core_device *vdev, u8 pos)
        if (vdev->msi_perm)
                return len;
 
-       vdev->msi_perm = kmalloc(sizeof(struct perm_bits), GFP_KERNEL);
+       vdev->msi_perm = kmalloc(sizeof(struct perm_bits), GFP_KERNEL_ACCOUNT);
        if (!vdev->msi_perm)
                return -ENOMEM;
 
@@ -1731,11 +1731,11 @@ int vfio_config_init(struct vfio_pci_core_device *vdev)
         * no requirements on the length of a capability, so the gap between
         * capabilities needs byte granularity.
         */
-       map = kmalloc(pdev->cfg_size, GFP_KERNEL);
+       map = kmalloc(pdev->cfg_size, GFP_KERNEL_ACCOUNT);
        if (!map)
                return -ENOMEM;
 
-       vconfig = kmalloc(pdev->cfg_size, GFP_KERNEL);
+       vconfig = kmalloc(pdev->cfg_size, GFP_KERNEL_ACCOUNT);
        if (!vconfig) {
                kfree(map);
                return -ENOMEM;
index 26a541cc64d114a22e4f9688c71f3a163683ebdc..a6492a25ff6a623b2e2b5980eff37041e9335427 100644 (file)
@@ -144,7 +144,8 @@ static void vfio_pci_probe_mmaps(struct vfio_pci_core_device *vdev)
                         * of the exclusive page in case that hot-add
                         * device's bar is assigned into it.
                         */
-                       dummy_res = kzalloc(sizeof(*dummy_res), GFP_KERNEL);
+                       dummy_res =
+                               kzalloc(sizeof(*dummy_res), GFP_KERNEL_ACCOUNT);
                        if (dummy_res == NULL)
                                goto no_mmap;
 
@@ -863,7 +864,7 @@ int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev,
 
        region = krealloc(vdev->region,
                          (vdev->num_regions + 1) * sizeof(*region),
-                         GFP_KERNEL);
+                         GFP_KERNEL_ACCOUNT);
        if (!region)
                return -ENOMEM;
 
@@ -1644,7 +1645,7 @@ static int __vfio_pci_add_vma(struct vfio_pci_core_device *vdev,
 {
        struct vfio_pci_mmap_vma *mmap_vma;
 
-       mmap_vma = kmalloc(sizeof(*mmap_vma), GFP_KERNEL);
+       mmap_vma = kmalloc(sizeof(*mmap_vma), GFP_KERNEL_ACCOUNT);
        if (!mmap_vma)
                return -ENOMEM;
 
index 5e6ca592695485c883e9a3402c21445dbd60bbdf..dd70e2431bd74271ae932a6509a60857af6c7da5 100644 (file)
@@ -180,7 +180,7 @@ static int vfio_pci_igd_opregion_init(struct vfio_pci_core_device *vdev)
        if (!addr || !(~addr))
                return -ENODEV;
 
-       opregionvbt = kzalloc(sizeof(*opregionvbt), GFP_KERNEL);
+       opregionvbt = kzalloc(sizeof(*opregionvbt), GFP_KERNEL_ACCOUNT);
        if (!opregionvbt)
                return -ENOMEM;
 
index 40c3d7cf163f69ce0a860e36d583db4b0ea1015b..bffb0741518b95b7041adba2afab35619e8bbc18 100644 (file)
@@ -177,7 +177,7 @@ static int vfio_intx_enable(struct vfio_pci_core_device *vdev)
        if (!vdev->pdev->irq)
                return -ENODEV;
 
-       vdev->ctx = kzalloc(sizeof(struct vfio_pci_irq_ctx), GFP_KERNEL);
+       vdev->ctx = kzalloc(sizeof(struct vfio_pci_irq_ctx), GFP_KERNEL_ACCOUNT);
        if (!vdev->ctx)
                return -ENOMEM;
 
@@ -216,7 +216,7 @@ static int vfio_intx_set_signal(struct vfio_pci_core_device *vdev, int fd)
        if (fd < 0) /* Disable only */
                return 0;
 
-       vdev->ctx[0].name = kasprintf(GFP_KERNEL, "vfio-intx(%s)",
+       vdev->ctx[0].name = kasprintf(GFP_KERNEL_ACCOUNT, "vfio-intx(%s)",
                                      pci_name(pdev));
        if (!vdev->ctx[0].name)
                return -ENOMEM;
@@ -284,7 +284,8 @@ static int vfio_msi_enable(struct vfio_pci_core_device *vdev, int nvec, bool msi
        if (!is_irq_none(vdev))
                return -EINVAL;
 
-       vdev->ctx = kcalloc(nvec, sizeof(struct vfio_pci_irq_ctx), GFP_KERNEL);
+       vdev->ctx = kcalloc(nvec, sizeof(struct vfio_pci_irq_ctx),
+                           GFP_KERNEL_ACCOUNT);
        if (!vdev->ctx)
                return -ENOMEM;
 
@@ -343,7 +344,8 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_core_device *vdev,
        if (fd < 0)
                return 0;
 
-       vdev->ctx[vector].name = kasprintf(GFP_KERNEL, "vfio-msi%s[%d](%s)",
+       vdev->ctx[vector].name = kasprintf(GFP_KERNEL_ACCOUNT,
+                                          "vfio-msi%s[%d](%s)",
                                           msix ? "x" : "", vector,
                                           pci_name(pdev));
        if (!vdev->ctx[vector].name)
index e352a033b4aef770e434a42ebbeece0fbf6eb7a3..e27de61ac9fe75f5818dc8d7386270c592c05a07 100644 (file)
@@ -470,7 +470,7 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
                goto out_unlock;
        }
 
-       ioeventfd = kzalloc(sizeof(*ioeventfd), GFP_KERNEL);
+       ioeventfd = kzalloc(sizeof(*ioeventfd), GFP_KERNEL_ACCOUNT);
        if (!ioeventfd) {
                ret = -ENOMEM;
                goto out_unlock;
index 497a17b378656888dcc1b27ef2e3fbfb61450e79..29c564b7a6e13e40c690ce3894f7873ca55bb240 100644 (file)
@@ -112,7 +112,7 @@ int vfio_virqfd_enable(void *opaque,
        int ret = 0;
        __poll_t events;
 
-       virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL);
+       virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL_ACCOUNT);
        if (!virqfd)
                return -ENOMEM;