ipvs: add conn_lfactor and svc_lfactor sysctl vars

Allow the default load factor for the connection and service tables
to be configured.

Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Florian Westphal <fw@strlen.de>
This commit is contained in:
Julian Anastasov
2026-04-04 18:34:39 +03:00
committed by Florian Westphal
parent 9a9ccef907
commit 8d7de5477e
2 changed files with 113 additions and 0 deletions

View File

@@ -29,6 +29,33 @@ backup_only - BOOLEAN
If set, disable the director function while the server is
in backup mode to avoid packet loops for DR/TUN methods.
conn_lfactor - INTEGER
Possible values: -8 (larger table) .. 8 (smaller table)
Default: -4
Controls the sizing of the connection hash table based on the
load factor (number of connections per table buckets):
2^conn_lfactor = nodes / buckets
As result, the table grows if load increases and shrinks when
load decreases in the range of 2^8 - 2^conn_tab_bits (module
parameter).
The value is a shift count where negative values select
buckets = (connection hash nodes << -value) while positive
values select buckets = (connection hash nodes >> value). The
negative values reduce the collisions and reduce the time for
lookups but increase the table size. Positive values will
tolerate load above 100% when using smaller table is
preferred with the cost of more collisions. If using NAT
connections consider decreasing the value with one because
they add two nodes in the hash table.
Example:
-4: grow if load goes above 6% (buckets = nodes * 16)
2: grow if load goes above 400% (buckets = nodes / 4)
conn_reuse_mode - INTEGER
1 - default
@@ -219,6 +246,16 @@ secure_tcp - INTEGER
The value definition is the same as that of drop_entry and
drop_packet.
svc_lfactor - INTEGER
Possible values: -8 (larger table) .. 8 (smaller table)
Default: -3
Controls the sizing of the service hash table based on the
load factor (number of services per table buckets). The table
will grow and shrink in the range of 2^4 - 2^20.
See conn_lfactor for explanation.
sync_threshold - vector of 2 INTEGERs: sync_threshold, sync_period
default 3 50

View File

@@ -2445,6 +2445,60 @@ static int ipvs_proc_run_estimation(const struct ctl_table *table, int write,
return ret;
}
static int ipvs_proc_conn_lfactor(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
struct netns_ipvs *ipvs = table->extra2;
int *valp = table->data;
int val = *valp;
int ret;
struct ctl_table tmp_table = {
.data = &val,
.maxlen = sizeof(int),
};
ret = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
if (write && ret >= 0) {
if (val < -8 || val > 8) {
ret = -EINVAL;
} else {
*valp = val;
if (rcu_access_pointer(ipvs->conn_tab))
mod_delayed_work(system_unbound_wq,
&ipvs->conn_resize_work, 0);
}
}
return ret;
}
static int ipvs_proc_svc_lfactor(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
struct netns_ipvs *ipvs = table->extra2;
int *valp = table->data;
int val = *valp;
int ret;
struct ctl_table tmp_table = {
.data = &val,
.maxlen = sizeof(int),
};
ret = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
if (write && ret >= 0) {
if (val < -8 || val > 8) {
ret = -EINVAL;
} else {
*valp = val;
if (rcu_access_pointer(ipvs->svc_table))
mod_delayed_work(system_unbound_wq,
&ipvs->svc_resize_work, 0);
}
}
return ret;
}
/*
* IPVS sysctl table (under the /proc/sys/net/ipv4/vs/)
* Do not change order or insert new entries without
@@ -2633,6 +2687,18 @@ static struct ctl_table vs_vars[] = {
.mode = 0644,
.proc_handler = ipvs_proc_est_nice,
},
{
.procname = "conn_lfactor",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = ipvs_proc_conn_lfactor,
},
{
.procname = "svc_lfactor",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = ipvs_proc_svc_lfactor,
},
#ifdef CONFIG_IP_VS_DEBUG
{
.procname = "debug_level",
@@ -4853,6 +4919,16 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
tbl[idx].extra2 = ipvs;
tbl[idx++].data = &ipvs->sysctl_est_nice;
if (unpriv)
tbl[idx].mode = 0444;
tbl[idx].extra2 = ipvs;
tbl[idx++].data = &ipvs->sysctl_conn_lfactor;
if (unpriv)
tbl[idx].mode = 0444;
tbl[idx].extra2 = ipvs;
tbl[idx++].data = &ipvs->sysctl_svc_lfactor;
#ifdef CONFIG_IP_VS_DEBUG
/* Global sysctls must be ro in non-init netns */
if (!net_eq(net, &init_net))