vfio: Use GFP_KERNEL_ACCOUNT for userspace persistent allocations

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>
This commit is contained in:
Jason Gunthorpe 2023-01-08 17:44:24 +02:00 committed by Alex Williamson
parent 83ff6095ec
commit 0886196ca8
7 changed files with 17 additions and 14 deletions

View File

@ -367,7 +367,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
{ {
struct vfio_container *container; struct vfio_container *container;
container = kzalloc(sizeof(*container), GFP_KERNEL); container = kzalloc(sizeof(*container), GFP_KERNEL_ACCOUNT);
if (!container) if (!container)
return -ENOMEM; return -ENOMEM;

View File

@ -1244,7 +1244,7 @@ static int vfio_msi_cap_len(struct vfio_pci_core_device *vdev, u8 pos)
if (vdev->msi_perm) if (vdev->msi_perm)
return len; 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) if (!vdev->msi_perm)
return -ENOMEM; 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 * no requirements on the length of a capability, so the gap between
* capabilities needs byte granularity. * capabilities needs byte granularity.
*/ */
map = kmalloc(pdev->cfg_size, GFP_KERNEL); map = kmalloc(pdev->cfg_size, GFP_KERNEL_ACCOUNT);
if (!map) if (!map)
return -ENOMEM; return -ENOMEM;
vconfig = kmalloc(pdev->cfg_size, GFP_KERNEL); vconfig = kmalloc(pdev->cfg_size, GFP_KERNEL_ACCOUNT);
if (!vconfig) { if (!vconfig) {
kfree(map); kfree(map);
return -ENOMEM; return -ENOMEM;

View 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 * of the exclusive page in case that hot-add
* device's bar is assigned into it. * 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) if (dummy_res == NULL)
goto no_mmap; goto no_mmap;
@ -863,7 +864,7 @@ int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev,
region = krealloc(vdev->region, region = krealloc(vdev->region,
(vdev->num_regions + 1) * sizeof(*region), (vdev->num_regions + 1) * sizeof(*region),
GFP_KERNEL); GFP_KERNEL_ACCOUNT);
if (!region) if (!region)
return -ENOMEM; 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; 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) if (!mmap_vma)
return -ENOMEM; return -ENOMEM;

View File

@ -180,7 +180,7 @@ static int vfio_pci_igd_opregion_init(struct vfio_pci_core_device *vdev)
if (!addr || !(~addr)) if (!addr || !(~addr))
return -ENODEV; return -ENODEV;
opregionvbt = kzalloc(sizeof(*opregionvbt), GFP_KERNEL); opregionvbt = kzalloc(sizeof(*opregionvbt), GFP_KERNEL_ACCOUNT);
if (!opregionvbt) if (!opregionvbt)
return -ENOMEM; return -ENOMEM;

View File

@ -177,7 +177,7 @@ static int vfio_intx_enable(struct vfio_pci_core_device *vdev)
if (!vdev->pdev->irq) if (!vdev->pdev->irq)
return -ENODEV; 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) if (!vdev->ctx)
return -ENOMEM; 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 */ if (fd < 0) /* Disable only */
return 0; 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)); pci_name(pdev));
if (!vdev->ctx[0].name) if (!vdev->ctx[0].name)
return -ENOMEM; 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)) if (!is_irq_none(vdev))
return -EINVAL; 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) if (!vdev->ctx)
return -ENOMEM; return -ENOMEM;
@ -343,7 +344,8 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_core_device *vdev,
if (fd < 0) if (fd < 0)
return 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, msix ? "x" : "", vector,
pci_name(pdev)); pci_name(pdev));
if (!vdev->ctx[vector].name) if (!vdev->ctx[vector].name)

View File

@ -470,7 +470,7 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
goto out_unlock; goto out_unlock;
} }
ioeventfd = kzalloc(sizeof(*ioeventfd), GFP_KERNEL); ioeventfd = kzalloc(sizeof(*ioeventfd), GFP_KERNEL_ACCOUNT);
if (!ioeventfd) { if (!ioeventfd) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_unlock; goto out_unlock;

View File

@ -112,7 +112,7 @@ int vfio_virqfd_enable(void *opaque,
int ret = 0; int ret = 0;
__poll_t events; __poll_t events;
virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL); virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL_ACCOUNT);
if (!virqfd) if (!virqfd)
return -ENOMEM; return -ENOMEM;