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
