Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Aug 2015 05:51:00 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r286616 - in head/sys: net netinet netinet6
Message-ID:  <201508110551.t7B5p0bV056807@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Tue Aug 11 05:51:00 2015
New Revision: 286616
URL: https://svnweb.freebsd.org/changeset/base/286616

Log:
  MFP r276712.
  
  * Split lltable_init() into lltable_allocate_htbl() (alloc
    hash table with default callbacks) and lltable_link() (
    links any lltable to the list).
  * Switch from LLTBL_HASHTBL_SIZE to per-lltable hash size field.
  * Move lltable setup to separate functions in in[6]_domifattach.

Modified:
  head/sys/net/if_llatbl.c
  head/sys/net/if_llatbl.h
  head/sys/netinet/in.c
  head/sys/netinet6/in6.c
Directory Properties:
  head/sys/   (props changed)

Modified: head/sys/net/if_llatbl.c
==============================================================================
--- head/sys/net/if_llatbl.c	Tue Aug 11 03:12:09 2015	(r286615)
+++ head/sys/net/if_llatbl.c	Tue Aug 11 05:51:00 2015	(r286616)
@@ -70,6 +70,7 @@ static void vnet_lltable_init(void);
 struct rwlock lltable_rwlock;
 RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
 
+static void lltable_unlink(struct lltable *llt);
 static void llentries_unlink(struct lltable *llt, struct llentries *head);
 
 static void htable_unlink_entry(struct llentry *lle);
@@ -138,7 +139,7 @@ htable_foreach_lle(struct lltable *llt, 
 
 	error = 0;
 
-	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
+	for (i = 0; i < llt->llt_hsize; i++) {
 		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
 			error = f(llt, lle, farg);
 			if (error != 0)
@@ -160,7 +161,7 @@ htable_link_entry(struct lltable *llt, s
 
 	IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp);
 
-	hashidx = llt->llt_hash(lle, LLTBL_HASHTBL_SIZE);
+	hashidx = llt->llt_hash(lle, llt->llt_hsize);
 	lleh = &llt->lle_head[hashidx];
 
 	lle->lle_tbl  = llt;
@@ -231,6 +232,14 @@ htable_prefix_free(struct lltable *llt, 
 }
 
 static void
+htable_free_tbl(struct lltable *llt)
+{
+
+	free(llt->lle_head, M_LLTABLE);
+	free(llt, M_LLTABLE);
+}
+
+static void
 llentries_unlink(struct lltable *llt, struct llentries *head)
 {
 	struct llentry *lle, *next;
@@ -355,9 +364,7 @@ lltable_free(struct lltable *llt)
 
 	KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
 
-	LLTABLE_WLOCK();
-	SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
-	LLTABLE_WUNLOCK();
+	lltable_unlink(llt);
 
 	LIST_INIT(&dchain);
 	IF_AFDATA_WLOCK(llt->llt_ifp);
@@ -372,7 +379,7 @@ lltable_free(struct lltable *llt)
 		llentry_free(lle);
 	}
 
-	free(llt, M_LLTABLE);
+	llt->llt_free_tbl(llt);
 }
 
 #if 0
@@ -388,7 +395,7 @@ lltable_drain(int af)
 		if (llt->llt_af != af)
 			continue;
 
-		for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
+		for (i=0; i < llt->llt_hsize; i++) {
 			LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
 				LLE_WLOCK(lle);
 				if (lle->la_hold) {
@@ -419,20 +426,18 @@ lltable_prefix_free(int af, struct socka
 	LLTABLE_RUNLOCK();
 }
 
-/*
- * Create a new lltable.
- */
 struct lltable *
-lltable_init(struct ifnet *ifp, int af)
+lltable_allocate_htbl(uint32_t hsize)
 {
 	struct lltable *llt;
-	register int i;
+	int i;
 
-	llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK);
+	llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO);
+	llt->llt_hsize = hsize;
+	llt->lle_head = malloc(sizeof(struct llentries) * hsize,
+	    M_LLTABLE, M_WAITOK | M_ZERO);
 
-	llt->llt_af = af;
-	llt->llt_ifp = ifp;
-	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
+	for (i = 0; i < llt->llt_hsize; i++)
 		LIST_INIT(&llt->lle_head[i]);
 
 	/* Set some default callbacks */
@@ -440,12 +445,31 @@ lltable_init(struct ifnet *ifp, int af)
 	llt->llt_unlink_entry = htable_unlink_entry;
 	llt->llt_prefix_free = htable_prefix_free;
 	llt->llt_foreach_entry = htable_foreach_lle;
+	llt->llt_free_tbl = htable_free_tbl;
+
+	return (llt);
+}
+
+/*
+ * Links lltable to global llt list.
+ */
+void
+lltable_link(struct lltable *llt)
+{
 
 	LLTABLE_WLOCK();
 	SLIST_INSERT_HEAD(&V_lltables, llt, llt_link);
 	LLTABLE_WUNLOCK();
+}
+
+static void
+lltable_unlink(struct lltable *llt)
+{
+
+	LLTABLE_WLOCK();
+	SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
+	LLTABLE_WUNLOCK();
 
-	return (llt);
 }
 
 /*
@@ -685,7 +709,7 @@ llatbl_llt_show(struct lltable *llt)
 	db_printf("llt=%p llt_af=%d llt_ifp=%p\n",
 	    llt, llt->llt_af, llt->llt_ifp);
 
-	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
+	for (i = 0; i < llt->llt_hsize; i++) {
 		LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
 
 			llatbl_lle_show((struct llentry_sa *)lle);

Modified: head/sys/net/if_llatbl.h
==============================================================================
--- head/sys/net/if_llatbl.h	Tue Aug 11 03:12:09 2015	(r286615)
+++ head/sys/net/if_llatbl.h	Tue Aug 11 05:51:00 2015	(r286616)
@@ -138,14 +138,6 @@ struct llentry {
 #define	L3_ADDR(lle)	((struct sockaddr *)(&lle[1]))
 #define	L3_ADDR_LEN(lle)	(((struct sockaddr *)(&lle[1]))->sa_len)
 
-#ifndef LLTBL_HASHTBL_SIZE
-#define	LLTBL_HASHTBL_SIZE	32	/* default 32 ? */
-#endif
-
-#ifndef LLTBL_HASHMASK
-#define	LLTBL_HASHMASK	(LLTBL_HASHTBL_SIZE - 1)
-#endif
-
 typedef	struct llentry *(llt_lookup_t)(struct lltable *, u_int flags,
     const struct sockaddr *l3addr);
 typedef	struct llentry *(llt_create_t)(struct lltable *, u_int flags,
@@ -161,6 +153,7 @@ typedef int (llt_match_prefix_t)(const s
     const struct sockaddr *, u_int, struct llentry *);
 typedef void (llt_free_entry_t)(struct lltable *, struct llentry *);
 typedef void (llt_fill_sa_entry_t)(const struct llentry *, struct sockaddr *);
+typedef void (llt_free_tbl_t)(struct lltable *);
 typedef void (llt_link_entry_t)(struct lltable *, struct llentry *);
 typedef void (llt_unlink_entry_t)(struct llentry *);
 
@@ -169,8 +162,9 @@ typedef int (llt_foreach_entry_t)(struct
 
 struct lltable {
 	SLIST_ENTRY(lltable)	llt_link;
-	struct llentries	lle_head[LLTBL_HASHTBL_SIZE];
 	int			llt_af;
+	int			llt_hsize;
+	struct llentries	*lle_head;
 	struct ifnet		*llt_ifp;
 
 	llt_lookup_t		*llt_lookup;
@@ -185,6 +179,7 @@ struct lltable {
 	llt_link_entry_t	*llt_link_entry;
 	llt_unlink_entry_t	*llt_unlink_entry;
 	llt_fill_sa_entry_t	*llt_fill_sa_entry;
+	llt_free_tbl_t		*llt_free_tbl;
 };
 
 MALLOC_DECLARE(M_LLTABLE);
@@ -204,8 +199,9 @@ MALLOC_DECLARE(M_LLTABLE);
 #define LLATBL_HASH(key, mask) \
 	(((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
 
-struct lltable *lltable_init(struct ifnet *, int);
+struct lltable *lltable_allocate_htbl(uint32_t hsize);
 void		lltable_free(struct lltable *);
+void		lltable_link(struct lltable *llt);
 void		lltable_prefix_free(int, struct sockaddr *,
 		    struct sockaddr *, u_int);
 #if 0

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Tue Aug 11 03:12:09 2015	(r286615)
+++ head/sys/netinet/in.c	Tue Aug 11 05:51:00 2015	(r286616)
@@ -1159,7 +1159,7 @@ in_lltable_find_dst(struct lltable *llt,
 	struct sockaddr_in *sin;
 	u_int hashidx;
 
-	hashidx = in_lltable_hash_dst(dst, LLTBL_HASHTBL_SIZE);
+	hashidx = in_lltable_hash_dst(dst, llt->llt_hsize);
 	lleh = &llt->lle_head[hashidx];
 	LIST_FOREACH(lle, lleh, lle_next) {
 		sin = satosin(L3_ADDR(lle));
@@ -1342,30 +1342,39 @@ in_lltable_dump_entry(struct lltable *ll
 	return (error);
 }
 
+static struct lltable *
+in_lltattach(struct ifnet *ifp)
+{
+	struct lltable *llt;
+
+	llt = lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE);
+ 	llt->llt_af = AF_INET;
+ 	llt->llt_ifp = ifp;
+
+	llt->llt_lookup = in_lltable_lookup;
+	llt->llt_create = in_lltable_create;
+	llt->llt_delete = in_lltable_delete;
+	llt->llt_dump_entry = in_lltable_dump_entry;
+	llt->llt_hash = in_lltable_hash;
+	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;
+ 	lltable_link(llt);
+
+	return (llt);
+}
+
 void *
 in_domifattach(struct ifnet *ifp)
 {
 	struct in_ifinfo *ii;
-	struct lltable *llt;
 
 	ii = malloc(sizeof(struct in_ifinfo), M_IFADDR, M_WAITOK|M_ZERO);
 
-	llt = lltable_init(ifp, AF_INET);
-	if (llt != NULL) {
-		llt->llt_lookup = in_lltable_lookup;
-		llt->llt_create = in_lltable_create;
-		llt->llt_delete = in_lltable_delete;
-		llt->llt_dump_entry = in_lltable_dump_entry;
-		llt->llt_hash = in_lltable_hash;
-		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;
-	}
-	ii->ii_llt = llt;
-
+	ii->ii_llt = in_lltattach(ifp);
 	ii->ii_igmp = igmp_domifattach(ifp);
 
-	return ii;
+	return (ii);
 }
 
 void

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Tue Aug 11 03:12:09 2015	(r286615)
+++ head/sys/netinet6/in6.c	Tue Aug 11 05:51:00 2015	(r286616)
@@ -2199,7 +2199,7 @@ in6_lltable_find_dst(struct lltable *llt
 	const struct sockaddr_in6 *sin6;
 	u_int hashidx;
 
-	hashidx = in6_lltable_hash_dst(dst, LLTBL_HASHTBL_SIZE);
+	hashidx = in6_lltable_hash_dst(dst, llt->llt_hsize);
 	lleh = &llt->lle_head[hashidx];
 	LIST_FOREACH(lle, lleh, lle_next) {
 		sin6 = (const struct sockaddr_in6 *)L3_CADDR(lle);
@@ -2378,6 +2378,28 @@ in6_lltable_dump_entry(struct lltable *l
 	return (error);
 }
 
+static struct lltable *
+in6_lltattach(struct ifnet *ifp)
+{
+	struct lltable *llt;
+
+	llt = lltable_allocate_htbl(IN6_LLTBL_DEFAULT_HSIZE);
+	llt->llt_af = AF_INET6;
+	llt->llt_ifp = ifp;
+
+	llt->llt_lookup = in6_lltable_lookup;
+	llt->llt_create = in6_lltable_create;
+	llt->llt_delete = in6_lltable_delete;
+	llt->llt_dump_entry = in6_lltable_dump_entry;
+	llt->llt_hash = in6_lltable_hash;
+	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;
+ 	lltable_link(llt);
+
+	return (llt);
+}
+
 void *
 in6_domifattach(struct ifnet *ifp)
 {
@@ -2406,17 +2428,7 @@ in6_domifattach(struct ifnet *ifp)
 
 	ext->nd_ifinfo = nd6_ifattach(ifp);
 	ext->scope6_id = scope6_ifattach(ifp);
-	ext->lltable = lltable_init(ifp, AF_INET6);
-	if (ext->lltable != NULL) {
-		ext->lltable->llt_lookup = in6_lltable_lookup;
-		ext->lltable->llt_create = in6_lltable_create;
-		ext->lltable->llt_delete = in6_lltable_delete;
-		ext->lltable->llt_dump_entry = in6_lltable_dump_entry;
-		ext->lltable->llt_hash = in6_lltable_hash;
-		ext->lltable->llt_fill_sa_entry = in6_lltable_fill_sa_entry;
-		ext->lltable->llt_free_entry = in6_lltable_free_entry;
-		ext->lltable->llt_match_prefix = in6_lltable_match_prefix;
-	}
+	ext->lltable = in6_lltattach(ifp);
 
 	ext->mld_ifinfo = mld_domifattach(ifp);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508110551.t7B5p0bV056807>