Date: Mon, 5 Jan 2015 17:23:03 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r276712 - in projects/routing/sys: net netinet netinet6 Message-ID: <201501051723.t05HN3lw031769@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Mon Jan 5 17:23:02 2015 New Revision: 276712 URL: https://svnweb.freebsd.org/changeset/base/276712 Log: * Allocate hash tables separately * Make llt_hash() callback more flexible * Default hash size and hashing method is now per-af * Move lltable allocation to separate function Modified: projects/routing/sys/net/if_llatbl.c projects/routing/sys/net/if_llatbl_var.h projects/routing/sys/netinet/in.c projects/routing/sys/netinet6/in6.c Modified: projects/routing/sys/net/if_llatbl.c ============================================================================== --- projects/routing/sys/net/if_llatbl.c Mon Jan 5 16:52:25 2015 (r276711) +++ projects/routing/sys/net/if_llatbl.c Mon Jan 5 17:23:02 2015 (r276712) @@ -94,7 +94,7 @@ lltable_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) @@ -151,15 +151,15 @@ static void llentry_link(struct lltable *llt, struct llentry *lle) { struct llentries *lleh; - uint32_t hashkey; + uint32_t hashidx; if ((lle->la_flags & LLE_LINKED) != 0) return; IF_AFDATA_RUN_WLOCK_ASSERT(llt->llt_ifp); - hashkey = llt->llt_hash(lle); - lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)]; + hashidx = llt->llt_hash(lle, llt->llt_hsize); + lleh = &llt->lle_head[hashidx]; lle->lle_tbl = llt; lle->lle_head = lleh; @@ -274,10 +274,28 @@ lltable_free_cb(struct lltable *llt, str return (0); } +struct lltable * +lltable_allocate_htbl(uint32_t hsize) +{ + struct lltable *llt; + int i; + + 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); + + for (i = 0; i < llt->llt_hsize; i++) + LIST_INIT(&llt->lle_head[i]); + + return (llt); +} + static void lltable_free_tbl(struct lltable *llt) { + free(llt->lle_head, M_LLTABLE); free(llt, M_LLTABLE); } @@ -370,7 +388,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) { @@ -703,7 +721,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: projects/routing/sys/net/if_llatbl_var.h ============================================================================== --- projects/routing/sys/net/if_llatbl_var.h Mon Jan 5 16:52:25 2015 (r276711) +++ projects/routing/sys/net/if_llatbl_var.h Mon Jan 5 17:23:02 2015 (r276712) @@ -35,24 +35,13 @@ extern struct rwlock lltable_rwlock; #define LLTABLE_WUNLOCK() rw_wunlock(&lltable_rwlock) #define LLTABLE_LOCK_ASSERT() rw_assert(&lltable_rwlock, RA_LOCKED) -#ifndef LLTBL_HASHTBL_SIZE -#define LLTBL_HASHTBL_SIZE 32 /* default 32 ? */ -#endif - -#ifndef LLTBL_HASHMASK -#define LLTBL_HASHMASK (LLTBL_HASHTBL_SIZE - 1) -#endif - -#define LLATBL_HASH(key, mask) \ - (((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask) - typedef struct llentry *(llt_lookup_t)(struct lltable *, u_int flags, const void *paddr); typedef struct llentry *(llt_create_t)(struct lltable *, u_int flags, const void *paddr); typedef int (llt_dump_entry_t)(struct lltable *, struct llentry *, struct sysctl_req *); -typedef uint32_t (llt_hash_t)(const struct llentry *); +typedef uint32_t (llt_hash_t)(const struct llentry *, uint32_t); typedef int (llt_match_prefix_t)(const struct sockaddr *, const struct sockaddr *, u_int, struct llentry *); typedef void (llt_clear_entry_t)(struct lltable *, struct llentry *); @@ -70,8 +59,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; @@ -93,6 +83,7 @@ MALLOC_DECLARE(M_LLTABLE); void lltable_link(struct lltable *llt); void lltable_free(struct lltable *llt); +struct lltable *lltable_allocate_htbl(uint32_t hsize); /* helper functions */ size_t lltable_drop_entry_queue(struct llentry *); Modified: projects/routing/sys/netinet/in.c ============================================================================== --- projects/routing/sys/netinet/in.c Mon Jan 5 16:52:25 2015 (r276711) +++ projects/routing/sys/netinet/in.c Mon Jan 5 17:23:02 2015 (r276712) @@ -989,6 +989,11 @@ in_purgemaddrs(struct ifnet *ifp) IN_MULTI_UNLOCK(); } + +#define IN_LLTBL_DEFAULT_HSIZE 32 +#define IN_LLTBL_HASH(k, h) \ + (((((((k >> 8) ^ k) >> 8) ^ k) >> 8) ^ k) & ((h) - 1)) + /* * Frees unlinked record. * This function is called by the timer functions @@ -1086,17 +1091,17 @@ in_lltable_rtcheck(struct ifnet *ifp, u_ } static inline uint32_t -in_lltable_hash_dst(const struct in_addr dst) +in_lltable_hash_dst(const struct in_addr dst, uint32_t hsize) { - return (dst.s_addr); + return (IN_LLTBL_HASH(dst.s_addr, hsize)); } static uint32_t -in_lltable_hash(const struct llentry *lle) +in_lltable_hash(const struct llentry *lle, uint32_t hsize) { - return (in_lltable_hash_dst(lle->r_l3addr.addr4)); + return (in_lltable_hash_dst(lle->r_l3addr.addr4, hsize)); } static const void * @@ -1126,10 +1131,10 @@ in_lltable_find_dst(struct lltable *llt, { struct llentry *lle; struct llentries *lleh; - u_int hashkey; + u_int hashidx; - hashkey = dst.s_addr; - lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)]; + hashidx = in_lltable_hash_dst(dst, llt->llt_hsize); + lleh = &llt->lle_head[hashidx]; LIST_FOREACH(lle, lleh, lle_next) { if (lle->r_l3addr.addr4.s_addr == dst.s_addr) break; @@ -1256,18 +1261,14 @@ in_lltable_dump_entry(struct lltable *ll return (error); } -void * -in_domifattach(struct ifnet *ifp) +static struct lltable * +in_lltattach(struct ifnet *ifp) { - struct in_ifinfo *ii; struct lltable *llt; - int i; - llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO); + llt = lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE); llt->llt_af = AF_INET; llt->llt_ifp = ifp; - for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) - LIST_INIT(&llt->lle_head[i]); llt->llt_lookup = in_lltable_lookup; llt->llt_create = in_lltable_create; @@ -1280,8 +1281,16 @@ in_domifattach(struct ifnet *ifp) llt->llt_prepare_static_entry = arp_lltable_prepare_static_entry; lltable_link(llt); + return (llt); +} + +void * +in_domifattach(struct ifnet *ifp) +{ + struct in_ifinfo *ii; + ii = malloc(sizeof(struct in_ifinfo), M_IFADDR, M_WAITOK|M_ZERO); - ii->ii_llt = llt; + ii->ii_llt = in_lltattach(ifp); ii->ii_igmp = igmp_domifattach(ifp); return ii; Modified: projects/routing/sys/netinet6/in6.c ============================================================================== --- projects/routing/sys/netinet6/in6.c Mon Jan 5 16:52:25 2015 (r276711) +++ projects/routing/sys/netinet6/in6.c Mon Jan 5 17:23:02 2015 (r276712) @@ -2047,6 +2047,10 @@ in6_if2idlen(struct ifnet *ifp) #include <sys/sysctl.h> +#define IN6_LLTBL_DEFAULT_HSIZE 32 +#define IN6_LLTBL_HASH(k, h) \ + (((((((k >> 8) ^ k) >> 8) ^ k) >> 8) ^ k) & ((h) - 1)) + /* * Frees already unlinked @lle. */ @@ -2133,17 +2137,17 @@ in6_lltable_rtcheck(struct ifnet *ifp, } static inline uint32_t -in6_lltable_hash_dst(const struct in6_addr *dst) +in6_lltable_hash_dst(const struct in6_addr *dst, uint32_t hsize) { - return (dst->s6_addr32[3]); + return (IN6_LLTBL_HASH(dst->s6_addr32[3], hsize)); } static uint32_t -in6_lltable_hash(const struct llentry *lle) +in6_lltable_hash(const struct llentry *lle, uint32_t hsize) { - return (in6_lltable_hash_dst(&lle->r_l3addr.addr6)); + return (in6_lltable_hash_dst(&lle->r_l3addr.addr6, hsize)); } static const void * @@ -2173,10 +2177,10 @@ in6_lltable_find_dst(struct lltable *llt { struct llentry *lle; struct llentries *lleh; - u_int hashkey; + u_int hashidx; - hashkey = in6_lltable_hash_dst(dst); - lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)]; + hashidx = in6_lltable_hash_dst(dst, llt->llt_hsize); + lleh = &llt->lle_head[hashidx]; LIST_FOREACH(lle, lleh, lle_next) { if (IN6_ARE_ADDR_EQUAL(&lle->r_l3addr.addr6, dst) != 0) break; @@ -2307,12 +2311,33 @@ 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_dump_entry = in6_lltable_dump_entry; + llt->llt_hash = in6_lltable_hash; + llt->llt_get_sa_addr = in6_lltable_get_sa_addr; + llt->llt_fill_sa_entry = in6_lltable_fill_sa_entry; + llt->llt_clear_entry = nd6_lltable_clear_entry; + llt->llt_match_prefix = in6_lltable_match_prefix; + llt->llt_prepare_static_entry = nd6_lltable_prepare_static_entry; + lltable_link(llt); + + return (llt); +} + void * in6_domifattach(struct ifnet *ifp) { struct in6_ifextra *ext; - struct lltable *llt; - int i; /* There are not IPv6-capable interfaces. */ switch (ifp->if_type) { @@ -2338,24 +2363,7 @@ in6_domifattach(struct ifnet *ifp) ext->nd_ifinfo = nd6_ifattach(ifp); ext->scope6_id = scope6_ifattach(ifp); - llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO); - llt->llt_af = AF_INET6; - llt->llt_ifp = ifp; - for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) - LIST_INIT(&llt->lle_head[i]); - - llt->llt_lookup = in6_lltable_lookup; - llt->llt_create = in6_lltable_create; - llt->llt_dump_entry = in6_lltable_dump_entry; - llt->llt_hash = in6_lltable_hash; - llt->llt_get_sa_addr = in6_lltable_get_sa_addr; - llt->llt_fill_sa_entry = in6_lltable_fill_sa_entry; - llt->llt_clear_entry = nd6_lltable_clear_entry; - llt->llt_match_prefix = in6_lltable_match_prefix; - llt->llt_prepare_static_entry = nd6_lltable_prepare_static_entry; - lltable_link(llt); - ext->lltable = llt; - + ext->lltable = in6_lltattach(ifp); ext->mld_ifinfo = mld_domifattach(ifp); return ext;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501051723.t05HN3lw031769>