[Devel] [PATCH RHEL10 COMMIT] ve/net/neighbour: base forced-GC reclaim target on the per-VE counter

Konstantin Khorenko khorenko at virtuozzo.com
Mon Jun 15 19:26:13 MSK 2026


The commit is pushed to "branch-rh10-6.12.0-211.16.1.12.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh10-6.12.0-211.16.1.12.1.vz10
------>
commit 3679b64a3a2a679ae559ae5c4043a31a37fd9cea
Author: Konstantin Khorenko <khorenko at virtuozzo.com>
Date:   Mon Jun 15 17:44:24 2026 +0200

    ve/net/neighbour: base forced-GC reclaim target on the per-VE counter
    
    neigh_forced_gc() already counts only same-VE reclaims into "shrunk" and
    is reached from neigh_alloc() when a container hits its per-VE gc_thresh3
    limit, but its reclaim target was still derived from the global counter:
    
            max_clean = atomic_read(&tbl->gc_entries) - gc_thresh2;
    
    With several containers tbl->gc_entries is the sum across all of them, so
    max_clean balloons far beyond the number of entries the allocating
    container actually owns. The "shrunk >= max_clean" stop condition is then
    never reached and forced GC walks the entire global gc_list on every call
    (until the 16-iteration / 1 ms budget runs out), churning other VEs'
    entries instead of stopping once the offending VE is back under its limit.
    
    Derive max_clean from the per-VE counter so the trigger, the reclaim
    target and the counted reclaims are all per-VE; fall back to the global
    counter when there is no per-VE counter for the table family.
    
    Fixes: 5f0a2a6f78f7 ("ve/net/neighbour: per-ct limit for neighbour entries")
    https://virtuozzo.atlassian.net/browse/VSTOR-132310
    Feature: net: make the neighbor entries limit per-CT
    
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
    Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
    Reported-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 net/core/neighbour.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index cf1f11a596d8..f90deb17fb25 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -275,7 +275,9 @@ bool neigh_remove_one(struct neighbour *ndel, struct neigh_table *tbl)
 
 static int neigh_forced_gc(struct neigh_table *tbl, struct ve_struct *ve)
 {
-	int max_clean = atomic_read(&tbl->gc_entries) -
+	atomic_t *cnt = get_perve_tbl_entries_counter(tbl, ve);
+	int max_clean = (cnt ? atomic_read(cnt) :
+			       atomic_read(&tbl->gc_entries)) -
 			READ_ONCE(tbl->gc_thresh2);
 	u64 tmax = ktime_get_ns() + NSEC_PER_MSEC;
 	unsigned long tref = jiffies - 5 * HZ;


More information about the Devel mailing list