net, neigh: introduce interval_probe_time_ms for periodic probe
authorYuwei Wang <wangyuweihx@gmail.com>
Wed, 29 Jun 2022 08:48:32 +0000 (08:48 +0000)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 30 Jun 2022 11:14:35 +0000 (13:14 +0200)
commit ed6cd6a17896 ("net, neigh: Set lower cap for neigh_managed_work rearming")
fixed a case when DELAY_PROBE_TIME is configured to 0, the processing of the
system work queue hog CPU to 100%, and further more we should introduce
a new option used by periodic probe

Signed-off-by: Yuwei Wang <wangyuweihx@gmail.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/networking/ip-sysctl.rst
include/net/neighbour.h
include/uapi/linux/neighbour.h
include/uapi/linux/sysctl.h
net/core/neighbour.c
net/decnet/dn_neigh.c
net/ipv4/arp.c
net/ipv6/ndisc.c

index 9f41961..4c8bbf5 100644 (file)
@@ -202,6 +202,12 @@ neigh/default/unres_qlen - INTEGER
 
        Default: 101
 
+neigh/default/interval_probe_time_ms - INTEGER
+       The probe interval for neighbor entries with NTF_MANAGED flag,
+       the min value is 1.
+
+       Default: 5000
+
 mtu_expires - INTEGER
        Time, in seconds, that cached PMTU information is kept.
 
index 87419f7..9f0bab0 100644 (file)
@@ -48,6 +48,7 @@ enum {
        NEIGH_VAR_RETRANS_TIME,
        NEIGH_VAR_BASE_REACHABLE_TIME,
        NEIGH_VAR_DELAY_PROBE_TIME,
+       NEIGH_VAR_INTERVAL_PROBE_TIME_MS,
        NEIGH_VAR_GC_STALETIME,
        NEIGH_VAR_QUEUE_LEN_BYTES,
        NEIGH_VAR_PROXY_QLEN,
index 39c565e..a998bf7 100644 (file)
@@ -154,6 +154,7 @@ enum {
        NDTPA_QUEUE_LENBYTES,           /* u32 */
        NDTPA_MCAST_REPROBES,           /* u32 */
        NDTPA_PAD,
+       NDTPA_INTERVAL_PROBE_TIME_MS,   /* u64, msecs */
        __NDTPA_MAX
 };
 #define NDTPA_MAX (__NDTPA_MAX - 1)
index 6a3b194..8981f00 100644 (file)
@@ -584,24 +584,25 @@ enum {
 
 /* /proc/sys/net/<protocol>/neigh/<dev> */
 enum {
-       NET_NEIGH_MCAST_SOLICIT=1,
-       NET_NEIGH_UCAST_SOLICIT=2,
-       NET_NEIGH_APP_SOLICIT=3,
-       NET_NEIGH_RETRANS_TIME=4,
-       NET_NEIGH_REACHABLE_TIME=5,
-       NET_NEIGH_DELAY_PROBE_TIME=6,
-       NET_NEIGH_GC_STALE_TIME=7,
-       NET_NEIGH_UNRES_QLEN=8,
-       NET_NEIGH_PROXY_QLEN=9,
-       NET_NEIGH_ANYCAST_DELAY=10,
-       NET_NEIGH_PROXY_DELAY=11,
-       NET_NEIGH_LOCKTIME=12,
-       NET_NEIGH_GC_INTERVAL=13,
-       NET_NEIGH_GC_THRESH1=14,
-       NET_NEIGH_GC_THRESH2=15,
-       NET_NEIGH_GC_THRESH3=16,
-       NET_NEIGH_RETRANS_TIME_MS=17,
-       NET_NEIGH_REACHABLE_TIME_MS=18,
+       NET_NEIGH_MCAST_SOLICIT = 1,
+       NET_NEIGH_UCAST_SOLICIT = 2,
+       NET_NEIGH_APP_SOLICIT = 3,
+       NET_NEIGH_RETRANS_TIME = 4,
+       NET_NEIGH_REACHABLE_TIME = 5,
+       NET_NEIGH_DELAY_PROBE_TIME = 6,
+       NET_NEIGH_GC_STALE_TIME = 7,
+       NET_NEIGH_UNRES_QLEN = 8,
+       NET_NEIGH_PROXY_QLEN = 9,
+       NET_NEIGH_ANYCAST_DELAY = 10,
+       NET_NEIGH_PROXY_DELAY = 11,
+       NET_NEIGH_LOCKTIME = 12,
+       NET_NEIGH_GC_INTERVAL = 13,
+       NET_NEIGH_GC_THRESH1 = 14,
+       NET_NEIGH_GC_THRESH2 = 15,
+       NET_NEIGH_GC_THRESH3 = 16,
+       NET_NEIGH_RETRANS_TIME_MS = 17,
+       NET_NEIGH_REACHABLE_TIME_MS = 18,
+       NET_NEIGH_INTERVAL_PROBE_TIME_MS = 19,
 };
 
 /* /proc/sys/net/dccp */
index d8ec706..6a8c259 100644 (file)
@@ -1579,7 +1579,7 @@ static void neigh_managed_work(struct work_struct *work)
        list_for_each_entry(neigh, &tbl->managed_list, managed_list)
                neigh_event_send_probe(neigh, NULL, false);
        queue_delayed_work(system_power_efficient_wq, &tbl->managed_work,
-                          max(NEIGH_VAR(&tbl->parms, DELAY_PROBE_TIME), HZ));
+                          NEIGH_VAR(&tbl->parms, INTERVAL_PROBE_TIME_MS));
        write_unlock_bh(&tbl->lock);
 }
 
@@ -2100,7 +2100,9 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
            nla_put_msecs(skb, NDTPA_PROXY_DELAY,
                          NEIGH_VAR(parms, PROXY_DELAY), NDTPA_PAD) ||
            nla_put_msecs(skb, NDTPA_LOCKTIME,
-                         NEIGH_VAR(parms, LOCKTIME), NDTPA_PAD))
+                         NEIGH_VAR(parms, LOCKTIME), NDTPA_PAD) ||
+           nla_put_msecs(skb, NDTPA_INTERVAL_PROBE_TIME_MS,
+                         NEIGH_VAR(parms, INTERVAL_PROBE_TIME_MS), NDTPA_PAD))
                goto nla_put_failure;
        return nla_nest_end(skb, nest);
 
@@ -2255,6 +2257,7 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
        [NDTPA_ANYCAST_DELAY]           = { .type = NLA_U64 },
        [NDTPA_PROXY_DELAY]             = { .type = NLA_U64 },
        [NDTPA_LOCKTIME]                = { .type = NLA_U64 },
+       [NDTPA_INTERVAL_PROBE_TIME_MS]  = { .type = NLA_U64, .min = 1 },
 };
 
 static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -2373,6 +2376,10 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh,
                                              nla_get_msecs(tbp[i]));
                                call_netevent_notifiers(NETEVENT_DELAY_PROBE_TIME_UPDATE, p);
                                break;
+                       case NDTPA_INTERVAL_PROBE_TIME_MS:
+                               NEIGH_VAR_SET(p, INTERVAL_PROBE_TIME_MS,
+                                             nla_get_msecs(tbp[i]));
+                               break;
                        case NDTPA_RETRANS_TIME:
                                NEIGH_VAR_SET(p, RETRANS_TIME,
                                              nla_get_msecs(tbp[i]));
@@ -3562,6 +3569,22 @@ static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write,
        return ret;
 }
 
+static int neigh_proc_dointvec_ms_jiffies_positive(struct ctl_table *ctl, int write,
+                                                  void *buffer, size_t *lenp, loff_t *ppos)
+{
+       struct ctl_table tmp = *ctl;
+       int ret;
+
+       int min = msecs_to_jiffies(1);
+
+       tmp.extra1 = &min;
+       tmp.extra2 = NULL;
+
+       ret = proc_dointvec_ms_jiffies_minmax(&tmp, write, buffer, lenp, ppos);
+       neigh_proc_update(ctl, write);
+       return ret;
+}
+
 int neigh_proc_dointvec(struct ctl_table *ctl, int write, void *buffer,
                        size_t *lenp, loff_t *ppos)
 {
@@ -3658,6 +3681,9 @@ static int neigh_proc_base_reachable_time(struct ctl_table *ctl, int write,
 #define NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(attr, name) \
        NEIGH_SYSCTL_ENTRY(attr, attr, name, 0644, neigh_proc_dointvec_userhz_jiffies)
 
+#define NEIGH_SYSCTL_MS_JIFFIES_POSITIVE_ENTRY(attr, name) \
+       NEIGH_SYSCTL_ENTRY(attr, attr, name, 0644, neigh_proc_dointvec_ms_jiffies_positive)
+
 #define NEIGH_SYSCTL_MS_JIFFIES_REUSED_ENTRY(attr, data_attr, name) \
        NEIGH_SYSCTL_ENTRY(attr, data_attr, name, 0644, neigh_proc_dointvec_ms_jiffies)
 
@@ -3676,6 +3702,8 @@ static struct neigh_sysctl_table {
                NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(RETRANS_TIME, "retrans_time"),
                NEIGH_SYSCTL_JIFFIES_ENTRY(BASE_REACHABLE_TIME, "base_reachable_time"),
                NEIGH_SYSCTL_JIFFIES_ENTRY(DELAY_PROBE_TIME, "delay_first_probe_time"),
+               NEIGH_SYSCTL_MS_JIFFIES_POSITIVE_ENTRY(INTERVAL_PROBE_TIME_MS,
+                                                      "interval_probe_time_ms"),
                NEIGH_SYSCTL_JIFFIES_ENTRY(GC_STALETIME, "gc_stale_time"),
                NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(QUEUE_LEN_BYTES, "unres_qlen_bytes"),
                NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(PROXY_QLEN, "proxy_qlen"),
index fbd98ac..7c569bc 100644 (file)
@@ -94,6 +94,7 @@ struct neigh_table dn_neigh_table = {
                        [NEIGH_VAR_RETRANS_TIME] = 1 * HZ,
                        [NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ,
                        [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
+                       [NEIGH_VAR_INTERVAL_PROBE_TIME_MS] = 5 * HZ,
                        [NEIGH_VAR_GC_STALETIME] = 60 * HZ,
                        [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX,
                        [NEIGH_VAR_PROXY_QLEN] = 0,
index ab4a560..af2f12f 100644 (file)
@@ -168,6 +168,7 @@ struct neigh_table arp_tbl = {
                        [NEIGH_VAR_RETRANS_TIME] = 1 * HZ,
                        [NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ,
                        [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
+                       [NEIGH_VAR_INTERVAL_PROBE_TIME_MS] = 5 * HZ,
                        [NEIGH_VAR_GC_STALETIME] = 60 * HZ,
                        [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX,
                        [NEIGH_VAR_PROXY_QLEN] = 64,
index b0dfe97..cd84cbd 100644 (file)
@@ -128,6 +128,7 @@ struct neigh_table nd_tbl = {
                        [NEIGH_VAR_RETRANS_TIME] = ND_RETRANS_TIMER,
                        [NEIGH_VAR_BASE_REACHABLE_TIME] = ND_REACHABLE_TIME,
                        [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
+                       [NEIGH_VAR_INTERVAL_PROBE_TIME_MS] = 5 * HZ,
                        [NEIGH_VAR_GC_STALETIME] = 60 * HZ,
                        [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX,
                        [NEIGH_VAR_PROXY_QLEN] = 64,