From: Tao Cui <[email protected]>

Everything except the worker struct is allocated with plain GFP_KERNEL:
the per-vq iovec and log arrays at VHOST_SET_OWNER, the memory table at
VHOST_SET_MEM_TABLE whose size follows the user supplied region count,
the pending message nodes, and the vhost_net/vhost_vsock device structs
with their fallback to vmalloc.  The worker has been accounted since the
vhost_task conversion.

A container that can open /dev/vhost-net or /dev/vhost-vsock, which
device plugins hand out with passthrough, holds roughly 150KB of
resident kernel memory per device after SET_OWNER.  Charge the rest the
same way the worker already is.

Signed-off-by: Tao Cui <[email protected]>
---
 drivers/vhost/net.c   | 14 ++++++++------
 drivers/vhost/vhost.c | 16 ++++++++++------
 drivers/vhost/vsock.c |  5 +++--
 3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 4570a4ffbab2..bab6597c696d 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -249,7 +249,7 @@ vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy)
        /* No zero copy backend? Nothing to count. */
        if (!zcopy)
                return NULL;
-       ubufs = kmalloc_obj(*ubufs);
+       ubufs = kmalloc_obj(*ubufs, GFP_KERNEL_ACCOUNT);
        if (!ubufs)
                return ERR_PTR(-ENOMEM);
        atomic_set(&ubufs->refcount, 1);
@@ -302,7 +302,8 @@ static int vhost_net_set_ubuf_info(struct vhost_net *n)
                if (!zcopy)
                        continue;
                n->vqs[i].ubuf_info =
-                       kmalloc_objs(*n->vqs[i].ubuf_info, UIO_MAXIOV);
+                       kmalloc_objs(*n->vqs[i].ubuf_info, UIO_MAXIOV,
+                                    GFP_KERNEL_ACCOUNT);
                if  (!n->vqs[i].ubuf_info)
                        goto err;
        }
@@ -1344,17 +1345,18 @@ static int vhost_net_open(struct inode *inode, struct 
file *f)
        struct xdp_buff *xdp;
        int i;
 
-       n = kvmalloc_obj(*n, GFP_KERNEL | __GFP_RETRY_MAYFAIL);
+       n = kvmalloc_obj(*n, GFP_KERNEL | __GFP_RETRY_MAYFAIL |
+                        __GFP_ACCOUNT);
        if (!n)
                return -ENOMEM;
-       vqs = kmalloc_objs(*vqs, VHOST_NET_VQ_MAX);
+       vqs = kmalloc_objs(*vqs, VHOST_NET_VQ_MAX, GFP_KERNEL_ACCOUNT);
        if (!vqs) {
                kvfree(n);
                return -ENOMEM;
        }
 
        queue = kmalloc_array(VHOST_NET_BATCH, sizeof(void *),
-                             GFP_KERNEL);
+                             GFP_KERNEL_ACCOUNT);
        if (!queue) {
                kfree(vqs);
                kvfree(n);
@@ -1362,7 +1364,7 @@ static int vhost_net_open(struct inode *inode, struct 
file *f)
        }
        n->vqs[VHOST_NET_VQ_RX].rxq.queue = queue;
 
-       xdp = kmalloc_objs(*xdp, VHOST_NET_BATCH);
+       xdp = kmalloc_objs(*xdp, VHOST_NET_BATCH, GFP_KERNEL_ACCOUNT);
        if (!xdp) {
                kfree(vqs);
                kvfree(n);
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index ea127af58ada..d1274106ad5d 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -526,11 +526,14 @@ static long vhost_dev_alloc_iovecs(struct vhost_dev *dev)
 
        for (i = 0; i < dev->nvqs; ++i) {
                vq = dev->vqs[i];
-               vq->indirect = kmalloc_objs(*vq->indirect, UIO_MAXIOV);
-               vq->log = kmalloc_objs(*vq->log, dev->iov_limit);
-               vq->heads = kmalloc_objs(*vq->heads, dev->iov_limit);
+               vq->indirect = kmalloc_objs(*vq->indirect, UIO_MAXIOV,
+                                           GFP_KERNEL_ACCOUNT);
+               vq->log = kmalloc_objs(*vq->log, dev->iov_limit,
+                                      GFP_KERNEL_ACCOUNT);
+               vq->heads = kmalloc_objs(*vq->heads, dev->iov_limit,
+                                        GFP_KERNEL_ACCOUNT);
                vq->nheads = kmalloc_array(dev->iov_limit, sizeof(*vq->nheads),
-                                          GFP_KERNEL);
+                                          GFP_KERNEL_ACCOUNT);
                if (!vq->indirect || !vq->log || !vq->heads || !vq->nheads)
                        goto err_nomem;
        }
@@ -2053,7 +2056,8 @@ static long vhost_set_memory(struct vhost_dev *d, struct 
vhost_memory __user *m)
                return -E2BIG;
        if (max_iotlb_entries <= 0)
                return -EINVAL;
-       newmem = kvzalloc_flex(*newmem, regions, mem.nregions);
+       newmem = kvzalloc_flex(*newmem, regions, mem.nregions,
+                              GFP_KERNEL_ACCOUNT);
        if (!newmem)
                return -ENOMEM;
 
@@ -3405,7 +3409,7 @@ EXPORT_SYMBOL_GPL(vhost_disable_notify);
 struct vhost_msg_node *vhost_new_msg(struct vhost_virtqueue *vq, int type)
 {
        /* Make sure all padding within the structure is initialized. */
-       struct vhost_msg_node *node = kzalloc_obj(*node);
+       struct vhost_msg_node *node = kzalloc_obj(*node, GFP_KERNEL_ACCOUNT);
        if (!node)
                return NULL;
 
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 0cb87971d749..600daeb05e7b 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -721,11 +721,12 @@ static int vhost_vsock_dev_open(struct inode *inode, 
struct file *file)
        /* This struct is large and allocation could fail, fall back to vmalloc
         * if there is no other way.
         */
-       vsock = kvmalloc_obj(*vsock, GFP_KERNEL | __GFP_RETRY_MAYFAIL);
+       vsock = kvmalloc_obj(*vsock, GFP_KERNEL | __GFP_RETRY_MAYFAIL |
+                            __GFP_ACCOUNT);
        if (!vsock)
                return -ENOMEM;
 
-       vqs = kmalloc_objs(*vqs, ARRAY_SIZE(vsock->vqs));
+       vqs = kmalloc_objs(*vqs, ARRAY_SIZE(vsock->vqs), GFP_KERNEL_ACCOUNT);
        if (!vqs) {
                ret = -ENOMEM;
                goto out;
-- 
2.43.0


Reply via email to