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


Reply via email to