vxlan_vni_alloc() allocates a struct vxlan_vni_node and a per-CPU stats
block for every VNI, both with plain GFP_KERNEL, so neither is charged
to the cgroup of the process that created the VNI. A netdevice's own
struct and its Tx/Rx queues are already GFP_KERNEL_ACCOUNT in
alloc_netdev_mqs() (commit c948f51c1654 ("memcg: enable accounting for
net_device and Tx/Rx queues")), so these per-VNI allocations are an
unaccounted part of a device that a cgroup can grow one VNI at a time.Charge both to the caller's cgroup with GFP_KERNEL_ACCOUNT in vxlan_vni_alloc(). __GFP_ACCOUNT only charges an allocation made from a task in a non-root memcg, so the sole caller, which already handles a NULL return, is unaffected outside a memcg. The charge lands in the caller's memcg: adding VNIs from inside one moves each node into the accounted slab and raises the cgroup's per-CPU memory. This covers the node and its stats only; a VNI carrying a group or remote also installs a default FDB entry, whose allocations are not charged here and are accounted by the next patch. Assisted-by: LLM Signed-off-by: Ali Firas <[email protected]> --- v4: reworded to cover the node and stats only; the c948f51c1654 reference narrowed to net_device and its Tx/Rx queues; rebased. drivers/net/vxlan/vxlan_vnifilter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_vnifilter.c index 2999dd536625..4a631fcdf23a 100644 --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -825,10 +825,11 @@ static struct vxlan_vni_node *vxlan_vni_alloc(struct vxlan_dev *vxlan, { struct vxlan_vni_node *vninode; - vninode = kzalloc_obj(*vninode); + vninode = kzalloc_obj(*vninode, GFP_KERNEL_ACCOUNT); if (!vninode) return NULL; - vninode->stats = netdev_alloc_pcpu_stats(struct vxlan_vni_stats_pcpu); + vninode->stats = __netdev_alloc_pcpu_stats(struct vxlan_vni_stats_pcpu, + GFP_KERNEL_ACCOUNT); if (!vninode->stats) { kfree(vninode); return NULL; -- 2.53.0

