Date: Mon, 20 Apr 2009 16:16:43 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r191324 - head/sys/net Message-ID: <200904201616.n3KGGh8h051482@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Mon Apr 20 16:16:43 2009 New Revision: 191324 URL: http://svn.freebsd.org/changeset/base/191324 Log: simplify code by removing bit_fns and replacing with the use of a temporary mask Modified: head/sys/net/flowtable.c Modified: head/sys/net/flowtable.c ============================================================================== --- head/sys/net/flowtable.c Mon Apr 20 16:05:16 2009 (r191323) +++ head/sys/net/flowtable.c Mon Apr 20 16:16:43 2009 (r191324) @@ -300,9 +300,11 @@ struct flowtable { fl_rtalloc_t *ft_rtalloc; struct mtx *ft_locks; - struct flowtable *ft_next; + union flentryp ft_table; bitstr_t *ft_masks[MAXCPU]; + bitstr_t *ft_tmpmask; + struct flowtable *ft_next; }; static struct proc *flowcleanerproc; @@ -317,6 +319,7 @@ static uma_zone_t ipv6_zone; * to avoid extra cache evictions caused by incrementing a shared * counter * - add IPv6 support to flow lookup + * - add sysctls to resize && flush flow tables * - Add per flowtable sysctls for statistics and configuring timeouts * - add saturation counter to rtentry to support per-packet load-balancing * add flag to indicate round-robin flow, add list lookup from head @@ -872,6 +875,7 @@ flowtable_alloc(int nentry, int flags) ft->ft_masks[0] = bit_alloc(nentry); } + ft->ft_tmpmask = bit_alloc(nentry); /* * In the local transmit case the table truly is @@ -888,6 +892,7 @@ flowtable_alloc(int nentry, int flags) ft->ft_syn_idle = ft->ft_tcp_idle = 30; } + /* * hook in to the cleaner list */ @@ -936,65 +941,24 @@ fle_free(struct flentry *fle) uma_zfree((fle->f_flags & FL_IPV6) ? ipv6_zone : ipv4_zone, fle); } -/* - * Find the next bit set where lastbit is the last bit index - * that was set, mask is a pointer to a uint8_t that stores - * the current temporary mask because the caller can't clear - * bits in name and the lookup granularity is 1 byte - * - * This could be improved (4x reduction in overhead) for the sparse - * case by replacing bit_ffs with a more efficient function that works - * at the 4-byte granularity and change *mask to a uint32_t - * - */ -static __inline int -bit_fns(bitstr_t *name, int nbits, int lastbit, uint8_t *mask) -{ - bitstr_t *bitstr_start = &name[lastbit/8]; - int value = 0; - int bitsleft = nbits - lastbit; - - if (bitsleft <= 0) - return (-1); - /* - * Note that not only is bit_ffs inefficient, - * but it doesn't call the first bit set 1 - */ - if ((lastbit & 0x7) == 0) { - bit_ffs(bitstr_start, bitsleft, &value); - *mask = *bitstr_start; - if (value > 0) - bit_clear(mask, value); - } else { - bit_ffs(mask, 8, &value); - if (value == -1 && bitsleft > 8) { - lastbit = (lastbit & ~0x7) + 8; - bit_ffs((bitstr_start + 1), - ((bitsleft - 1) & ~0x7), &value); - if (value > 0) { - *mask = (bitstr_start + 1)[value/8]; - bit_clear(mask, (value % 8)); - } - } else { - bit_clear(mask, value); - } - } - - return (value > 0) ? (value + lastbit) : (-1); -} - static void flowtable_free_stale(struct flowtable *ft) { int curbit = 0, count; struct flentry *fle, **flehead, *fleprev; struct flentry *flefreehead, *flefreetail, *fletmp; - bitstr_t *mask; - uint8_t mask_tmp; + bitstr_t *mask, *tmpmask; flefreehead = flefreetail = NULL; mask = flowtable_mask(ft); - while ((curbit = bit_fns(mask, ft->ft_size, curbit, &mask_tmp)) != -1) { + tmpmask = ft->ft_tmpmask; + memcpy(tmpmask, mask, ft->ft_size/8); + /* + * XXX Note to self, bit_ffs operates at the byte level + * and thus adds gratuitous overhead + */ + bit_ffs(tmpmask, ft->ft_size, &curbit); + while (curbit != -1) { if (curbit >= ft->ft_size || curbit < -1) { log(LOG_ALERT, "warning: bad curbit value %d \n", @@ -1050,7 +1014,8 @@ flowtable_free_stale(struct flowtable *f if (*flehead == NULL) bit_clear(mask, curbit); FL_ENTRY_UNLOCK(ft, curbit); - curbit++; + bit_clear(tmpmask, curbit); + bit_ffs(tmpmask, ft->ft_size, &curbit); } count = 0; while ((fle = flefreehead) != NULL) { @@ -1074,10 +1039,7 @@ flowtable_cleaner(void) while (1) { ft = flow_list_head; while (ft != NULL) { - if ((ft->ft_flags & FL_PCPU) == 0) { - flowtable_free_stale(ft); - } else { - + if (ft->ft_flags & FL_PCPU) { for (i = 0; i <= mp_maxid; i++) { if (CPU_ABSENT(i)) continue; @@ -1092,6 +1054,8 @@ flowtable_cleaner(void) sched_unbind(curthread); thread_unlock(curthread); } + } else { + flowtable_free_stale(ft); } ft = ft->ft_next; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904201616.n3KGGh8h051482>