[PATCH 1/2] ipmr: Make cache queue length configurable
From: Brodie Greenfield <hidden>
Date: 2019-07-25 20:42:49
Also in:
lkml
Subsystem:
documentation, networking [general], networking [ipv4/ipv6], the rest · Maintainers:
Jonathan Corbet, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds
We want to be able to keep more spaces available in our queue for processing incoming multicast traffic (adding (S,G) entries) - this lets us learn more groups faster, rather than dropping them at this stage. Signed-off-by: Brodie Greenfield <redacted> --- Documentation/networking/ip-sysctl.txt | 8 ++++++++ include/net/netns/ipv4.h | 1 + net/ipv4/af_inet.c | 1 + net/ipv4/ipmr.c | 4 +++- net/ipv4/sysctl_net_ipv4.c | 7 +++++++ 5 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index acdfb5d2bcaa..02f77e932adf 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt@@ -887,6 +887,14 @@ ip_local_reserved_ports - list of comma separated ranges Default: Empty +ip_mr_cache_queue_length - INTEGER + Limit the number of multicast packets we can have in the queue to be + resolved. + Bear in mind that when an unresolved multicast packet is received, + there is an O(n) traversal of the queue. This should be considered + if increasing. + Default: 10 + ip_unprivileged_port_start - INTEGER This is a per-namespace sysctl. It defines the first unprivileged port in the network namespace. Privileged ports
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 104a6669e344..3411d3f18d51 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h@@ -187,6 +187,7 @@ struct netns_ipv4 { int sysctl_igmp_max_msf; int sysctl_igmp_llm_reports; int sysctl_igmp_qrv; + unsigned int sysctl_ip_mr_cache_queue_length; struct ping_group_range ping_group_range;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 0dfb72c46671..8e25538bdb1e 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c@@ -1827,6 +1827,7 @@ static __net_init int inet_init_net(struct net *net) net->ipv4.sysctl_igmp_llm_reports = 1; net->ipv4.sysctl_igmp_qrv = 2; + net->ipv4.sysctl_ip_mr_cache_queue_length = 10; return 0; }
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index ddbf8c9a1abb..c6a6c3e453a9 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c@@ -1127,6 +1127,7 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb, struct net_device *dev) { const struct iphdr *iph = ip_hdr(skb); + struct net *net = dev_net(dev); struct mfc_cache *c; bool found = false; int err;
@@ -1142,7 +1143,8 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, if (!found) { /* Create a new entry if allowable */ - if (atomic_read(&mrt->cache_resolve_queue_len) >= 10 || + if (atomic_read(&mrt->cache_resolve_queue_len) >= + net->ipv4.sysctl_ip_mr_cache_queue_length || (c = ipmr_cache_alloc_unres()) == NULL) { spin_unlock_bh(&mfc_unres_lock);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index ba0fc4b18465..78ae86e8c6cb 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c@@ -784,6 +784,13 @@ static struct ctl_table ipv4_net_table[] = { .proc_handler = proc_dointvec }, #ifdef CONFIG_IP_MULTICAST + { + .procname = "ip_mr_cache_queue_length", + .data = &init_net.ipv4.sysctl_ip_mr_cache_queue_length, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, { .procname = "igmp_qrv", .data = &init_net.ipv4.sysctl_igmp_qrv,
--
2.21.0