The branch main has been updated by melifaro:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=f3a3b061216936b6233d1624dfdba03240d7c045

commit f3a3b061216936b6233d1624dfdba03240d7c045
Author:     Alexander V. Chernikov <melif...@freebsd.org>
AuthorDate: 2021-08-02 22:39:00 +0000
Commit:     Alexander V. Chernikov <melif...@freebsd.org>
CommitDate: 2021-08-04 22:52:43 +0000

    [lltable] Unify datapath feedback mechamism.
    
    Use newly-create llentry_request_feedback(),
     llentry_mark_used() and llentry_get_hittime() to
     request datapatch usage check and fetch the results
     in the same fashion both in IPv4 and IPv6.
    
    While here, simplify llentry_provide_feedback() wrapper
     by eliminating 1 condition check.
    
    MFC after:      2 weeks
    Differential Revision: https://reviews.freebsd.org/D31390
---
 sys/net/if_ethersubr.c  |  2 +-
 sys/net/if_infiniband.c |  2 +-
 sys/net/if_llatbl.c     | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 sys/net/if_llatbl.h     | 11 +++++++----
 sys/netinet/if_ether.c  | 25 +++++++------------------
 sys/netinet/in.c        | 15 +--------------
 sys/netinet6/in6.c      | 21 +--------------------
 sys/netinet6/nd6.c      | 32 ++++++++------------------------
 8 files changed, 72 insertions(+), 82 deletions(-)

diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 7eb46df8281a..718de9625044 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -315,7 +315,7 @@ ether_output(struct ifnet *ifp, struct mbuf *m,
                                         * the entry was used
                                         * by datapath.
                                         */
-                                       llentry_mark_used(lle);
+                                       llentry_provide_feedback(lle);
                        }
                        if (lle != NULL) {
                                phdr = lle->r_linkdata;
diff --git a/sys/net/if_infiniband.c b/sys/net/if_infiniband.c
index 3e7daeed4da3..528f20b7c98d 100644
--- a/sys/net/if_infiniband.c
+++ b/sys/net/if_infiniband.c
@@ -329,7 +329,7 @@ infiniband_output(struct ifnet *ifp, struct mbuf *m,
                                         * the entry was used
                                         * by datapath.
                                         */
-                                       llentry_mark_used(lle);
+                                       llentry_provide_feedback(lle);
                        }
                        if (lle != NULL) {
                                phdr = lle->r_linkdata;
diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
index 7225869a07d0..70baf58c2778 100644
--- a/sys/net/if_llatbl.c
+++ b/sys/net/if_llatbl.c
@@ -386,6 +386,52 @@ lltable_calc_llheader(struct ifnet *ifp, int family, char 
*lladdr,
        return (error);
 }
 
+/*
+ * Requests feedback from the datapath.
+ * First packet using @lle should result in
+ * setting r_skip_req back to 0 and updating
+ * lle_hittime to the current time_uptime.
+ */
+void
+llentry_request_feedback(struct llentry *lle)
+{
+       LLE_REQ_LOCK(lle);
+       lle->r_skip_req = 1;
+       LLE_REQ_UNLOCK(lle);
+}
+
+/*
+ * Updates the lle state to mark it has been used
+ * and record the time.
+ * Used by the llentry_provide_feedback() wrapper.
+ */
+void
+llentry_mark_used(struct llentry *lle)
+{
+       LLE_REQ_LOCK(lle);
+       lle->r_skip_req = 0;
+       lle->lle_hittime = time_uptime;
+       LLE_REQ_UNLOCK(lle);
+}
+
+/*
+ * Fetches the time when lle was used.
+ * Return 0 if the entry was not used, relevant time_uptime
+ *  otherwise.
+ */
+time_t
+llentry_get_hittime(struct llentry *lle)
+{
+       time_t lle_hittime = 0;
+
+       LLE_REQ_LOCK(lle);
+       if ((lle->r_skip_req == 0) && (lle_hittime < lle->lle_hittime))
+               lle_hittime = lle->lle_hittime;
+       LLE_REQ_UNLOCK(lle);
+
+       return (lle_hittime);
+}
+
 /*
  * Update link-layer header for given @lle after
  * interface lladdr was changed.
diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h
index 1081b7cdf2cd..488f8b006315 100644
--- a/sys/net/if_llatbl.h
+++ b/sys/net/if_llatbl.h
@@ -250,17 +250,20 @@ lla_lookup(struct lltable *llt, u_int flags, const struct 
sockaddr *l3addr)
        return (llt->llt_lookup(llt, flags, l3addr));
 }
 
+void llentry_request_feedback(struct llentry *lle);
+void llentry_mark_used(struct llentry *lle);
+time_t llentry_get_hittime(struct llentry *lle);
+
 /*
  * Notify the LLE code that the entry was used by datapath.
  */
 static __inline void
-llentry_mark_used(struct llentry *lle)
+llentry_provide_feedback(struct llentry *lle)
 {
 
-       if (lle->r_skip_req == 0)
+       if (__predict_true(lle->r_skip_req == 0))
                return;
-       if ((lle->r_flags & RLLE_VALID) != 0)
-               lle->lle_tbl->llt_mark_used(lle);
+       llentry_mark_used(lle);
 }
 
 int            lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *);
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index ef50ec9ca964..3eb9d7210afb 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -207,7 +207,6 @@ arptimer(void *arg)
 {
        struct llentry *lle = (struct llentry *)arg;
        struct ifnet *ifp;
-       int r_skip_req;
 
        if (lle->la_flags & LLE_STATIC) {
                return;
@@ -240,27 +239,17 @@ arptimer(void *arg)
 
                /*
                 * Expiration time is approaching.
-                * Let's try to refresh entry if it is still
-                * in use.
-                *
-                * Set r_skip_req to get feedback from
-                * fast path. Change state and re-schedule
-                * ourselves.
+                * Request usage feedback from the datapath.
+                * Change state and re-schedule ourselves.
                 */
-               LLE_REQ_LOCK(lle);
-               lle->r_skip_req = 1;
-               LLE_REQ_UNLOCK(lle);
+               llentry_request_feedback(lle);
                lle->ln_state = ARP_LLINFO_VERIFY;
                callout_schedule(&lle->lle_timer, hz * V_arpt_rexmit);
                LLE_WUNLOCK(lle);
                CURVNET_RESTORE();
                return;
        case ARP_LLINFO_VERIFY:
-               LLE_REQ_LOCK(lle);
-               r_skip_req = lle->r_skip_req;
-               LLE_REQ_UNLOCK(lle);
-
-               if (r_skip_req == 0 && lle->la_preempt > 0) {
+               if (llentry_get_hittime(lle) > 0 && lle->la_preempt > 0) {
                        /* Entry was used, issue refresh request */
                        struct epoch_tracker et;
                        struct in_addr dst;
@@ -532,7 +521,7 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int flags, 
struct mbuf *m,
                bcopy(lladdr, desten, ll_len);
 
                /* Notify LLE code that the entry was used by datapath */
-               llentry_mark_used(la);
+               llentry_provide_feedback(la);
                if (pflags != NULL)
                        *pflags = la->la_flags & (LLE_VALID|LLE_IFADDR);
                if (plle) {
@@ -656,7 +645,7 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
                if (pflags != NULL)
                        *pflags = LLE_VALID | (la->r_flags & RLLE_IFADDR);
                /* Notify the LLE handling code that the entry was used. */
-               llentry_mark_used(la);
+               llentry_provide_feedback(la);
                if (plle) {
                        LLE_ADDREF(la);
                        *plle = la;
@@ -1225,7 +1214,7 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr 
isaddr, struct ifnet *ifp
                        return;
 
                /* Clear fast path feedback request if set */
-               la->r_skip_req = 0;
+               llentry_mark_used(la);
        }
 
        arp_mark_lle_reachable(la);
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index bcf071a81e0e..d1dd2b31b6ef 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1264,19 +1264,6 @@ in_lltable_destroy_lle_unlocked(epoch_context_t ctx)
        free(lle, M_LLTABLE);
 }
 
-/*
- * Called by the datapath to indicate that
- * the entry was used.
- */
-static void
-in_lltable_mark_used(struct llentry *lle)
-{
-
-       LLE_REQ_LOCK(lle);
-       lle->r_skip_req = 0;
-       LLE_REQ_UNLOCK(lle);
-}
-
 /*
  * Called by LLE_FREE_LOCKED when number of references
  * drops to zero.
@@ -1681,7 +1668,7 @@ in_lltattach(struct ifnet *ifp)
        llt->llt_fill_sa_entry = in_lltable_fill_sa_entry;
        llt->llt_free_entry = in_lltable_free_entry;
        llt->llt_match_prefix = in_lltable_match_prefix;
-       llt->llt_mark_used = in_lltable_mark_used;
+       llt->llt_mark_used = llentry_mark_used;
        lltable_link(llt);
 
        return (llt);
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 02cb9df7da3a..d5b3452c0b06 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -2214,25 +2214,6 @@ in6_lltable_rtcheck(struct ifnet *ifp,
        return 0;
 }
 
-/*
- * Called by the datapath to indicate that the entry was used.
- */
-static void
-in6_lltable_mark_used(struct llentry *lle)
-{
-
-       LLE_REQ_LOCK(lle);
-       lle->r_skip_req = 0;
-
-       /*
-        * Set the hit time so the callback function
-        * can determine the remaining time before
-        * transiting to the DELAY state.
-        */
-       lle->lle_hittime = time_uptime;
-       LLE_REQ_UNLOCK(lle);
-}
-
 static inline uint32_t
 in6_lltable_hash_dst(const struct in6_addr *dst, uint32_t hsize)
 {
@@ -2469,7 +2450,7 @@ in6_lltattach(struct ifnet *ifp)
        llt->llt_fill_sa_entry = in6_lltable_fill_sa_entry;
        llt->llt_free_entry = in6_lltable_free_entry;
        llt->llt_match_prefix = in6_lltable_match_prefix;
-       llt->llt_mark_used = in6_lltable_mark_used;
+       llt->llt_mark_used = llentry_mark_used;
        lltable_link(llt);
 
        return (llt);
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 62f0ac733a23..60610462f4d7 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -617,7 +617,7 @@ nd6_llinfo_get_holdsrc(struct llentry *ln, struct in6_addr 
*src)
 static int
 nd6_is_stale(struct llentry *lle, long *pdelay, int *do_switch)
 {
-       int nd_delay, nd_gctimer, r_skip_req;
+       int nd_delay, nd_gctimer;
        time_t lle_hittime;
        long delay;
 
@@ -625,17 +625,13 @@ nd6_is_stale(struct llentry *lle, long *pdelay, int 
*do_switch)
        nd_gctimer = V_nd6_gctimer;
        nd_delay = V_nd6_delay;
 
-       LLE_REQ_LOCK(lle);
-       r_skip_req = lle->r_skip_req;
-       lle_hittime = lle->lle_hittime;
-       LLE_REQ_UNLOCK(lle);
+       lle_hittime = llentry_get_hittime(lle);
 
-       if (r_skip_req > 0) {
+       if (lle_hittime == 0) {
                /*
-                * Nonzero r_skip_req value was set upon entering
-                * STALE state. Since value was not changed, no
-                * packets were passed using this lle. Ask for
-                * timer reschedule and keep STALE state.
+                * Datapath feedback has been requested upon entering
+                * STALE state. No packets has been passed using this lle.
+                * Ask for the timer reschedule and keep STALE state.
                 */
                delay = (long)(MIN(nd_gctimer, nd_delay));
                delay *= hz;
@@ -705,13 +701,7 @@ nd6_llinfo_setstate(struct llentry *lle, int newstate)
                break;
        case ND6_LLINFO_STALE:
 
-               /*
-                * Notify fast path that we want to know if any packet
-                * is transmitted by setting r_skip_req.
-                */
-               LLE_REQ_LOCK(lle);
-               lle->r_skip_req = 1;
-               LLE_REQ_UNLOCK(lle);
+               llentry_request_feedback(lle);
                nd_delay = V_nd6_delay;
                nd_gctimer = V_nd6_gctimer;
 
@@ -2254,13 +2244,7 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
                bcopy(ln->r_linkdata, desten, ln->r_hdrlen);
                if (pflags != NULL)
                        *pflags = LLE_VALID | (ln->r_flags & RLLE_IFADDR);
-               /* Check if we have feedback request from nd6 timer */
-               if (ln->r_skip_req != 0) {
-                       LLE_REQ_LOCK(ln);
-                       ln->r_skip_req = 0; /* Notify that entry was used */
-                       ln->lle_hittime = time_uptime;
-                       LLE_REQ_UNLOCK(ln);
-               }
+               llentry_provide_feedback(ln);
                if (plle) {
                        LLE_ADDREF(ln);
                        *plle = ln;
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to