svn commit: r364099 - in head/sys: net/route netinet6

Alexander V. Chernikov melifaro at FreeBSD.org
Tue Aug 11 07:05:31 UTC 2020


Author: melifaro
Date: Tue Aug 11 07:05:30 2020
New Revision: 364099
URL: https://svnweb.freebsd.org/changeset/base/364099

Log:
  Fix rib_subscribe() waitok flag by performing allocation outside epoch.
  Make in6_inithead() use rib_subscribe with waitok to achieve reliable
   subscription allocation.
  
  Reviewed by:	glebius

Modified:
  head/sys/net/route/route_ctl.c
  head/sys/net/route/route_ctl.h
  head/sys/netinet6/in6_rmx.c

Modified: head/sys/net/route/route_ctl.c
==============================================================================
--- head/sys/net/route/route_ctl.c	Tue Aug 11 05:17:10 2020	(r364098)
+++ head/sys/net/route/route_ctl.c	Tue Aug 11 07:05:30 2020	(r364099)
@@ -743,26 +743,26 @@ rib_notify(struct rib_head *rnh, enum rib_subscription
 /*
  * Subscribe for the changes in the routing table specified by @fibnum and
  *  @family.
- * Needs to be run in network epoch.
  *
  * Returns pointer to the subscription structure on success.
  */
 struct rib_subscription *
 rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg,
-    enum rib_subscription_type type, int waitok)
+    enum rib_subscription_type type, bool waitok)
 {
 	struct rib_head *rnh;
 	struct rib_subscription *rs;
+	struct epoch_tracker et;
 	int flags = M_ZERO | (waitok ? M_WAITOK : 0);
 
-	NET_EPOCH_ASSERT();
-	KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
-	rnh = rt_tables_get_rnh(fibnum, family);
-
 	rs = malloc(sizeof(struct rib_subscription), M_RTABLE, flags);
 	if (rs == NULL)
 		return (NULL);
 
+	NET_EPOCH_ENTER(et);
+	KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
+	rnh = rt_tables_get_rnh(fibnum, family);
+
 	rs->func = f;
 	rs->arg = arg;
 	rs->type = type;
@@ -770,6 +770,7 @@ rib_subscribe(uint32_t fibnum, int family, rib_subscri
 	RIB_WLOCK(rnh);
 	CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next);
 	RIB_WUNLOCK(rnh);
+	NET_EPOCH_EXIT(et);
 
 	return (rs);
 }

Modified: head/sys/net/route/route_ctl.h
==============================================================================
--- head/sys/net/route/route_ctl.h	Tue Aug 11 05:17:10 2020	(r364098)
+++ head/sys/net/route/route_ctl.h	Tue Aug 11 07:05:30 2020	(r364099)
@@ -78,7 +78,7 @@ typedef void rib_subscription_cb_t(struct rib_head *rn
 
 struct rib_subscription *rib_subscribe(uint32_t fibnum, int family,
     rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type,
-    int waitok);
+    bool waitok);
 int rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs);
 
 #endif

Modified: head/sys/netinet6/in6_rmx.c
==============================================================================
--- head/sys/netinet6/in6_rmx.c	Tue Aug 11 05:17:10 2020	(r364098)
+++ head/sys/netinet6/in6_rmx.c	Tue Aug 11 07:05:30 2020	(r364099)
@@ -150,8 +150,8 @@ rib6_preadd(u_int fibnum, const struct sockaddr *addr,
 int
 in6_inithead(void **head, int off, u_int fibnum)
 {
-	struct epoch_tracker et;
 	struct rib_head *rh;
+	struct rib_subscription *rs;
 
 	rh = rt_table_init(offsetof(struct sockaddr_in6, sin6_addr) << 3,
 	    AF_INET6, fibnum);
@@ -164,12 +164,9 @@ in6_inithead(void **head, int off, u_int fibnum)
 #endif
 	*head = (void *)rh;
 
-	NET_EPOCH_ENTER(et);
-	if (rib_subscribe(fibnum, AF_INET6, nd6_subscription_cb, NULL,
-	    RIB_NOTIFY_IMMEDIATE, M_NOWAIT) == NULL)
-		log(LOG_ERR, "in6_inithead(): unable to subscribe to fib %u\n",
-		    fibnum);
-	NET_EPOCH_EXIT(et);
+	rs = rib_subscribe(fibnum, AF_INET6, nd6_subscription_cb, NULL,
+	    RIB_NOTIFY_IMMEDIATE, true);
+	KASSERT(rs != NULL, ("Unable to subscribe to fib %u\n", fibnum));
 
 	return (1);
 }


More information about the svn-src-head mailing list