FreeBSD/sys/net/if_vlan.c
/*
 * Grow the hash larger or smaller if memory permits.
 */
Grow the hash larger or smaller if memory permits.
Grow the hash larger or smaller if memory permits .
static void
vlan_growhash(struct ifvlantrunk *trunk, int howmuch)
{
	struct ifvlan *ifv;
	struct ifvlanhead *hash2;
	int hwidth2, i, j, n, n2;
	TRUNK_LOCK_ASSERT(trunk);
	KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
	if (howmuch == 0) {
		printf("%s: howmuch is 0\n", __func__);
		return;
	}
	hwidth2 = trunk->hwidth + howmuch;
	n = 1 << trunk->hwidth;
	n2 = 1 << hwidth2;
	if (hwidth2 < VLAN_DEF_HWIDTH)
		return;
	hash2 = malloc(sizeof(struct ifvlanhead) * n2, M_VLAN, M_NOWAIT);
	if (hash2 == NULL) {
		printf("%s: out of memory -- hash size not changed\n",
		    __func__);
		return;		
	}
	for (j = 0; j < n2; j++)
		LIST_INIT(&hash2[j]);
	for (i = 0; i < n; i++)
		while ((ifv = LIST_FIRST(&trunk->hash[i])) != NULL) {
			LIST_REMOVE(ifv, ifv_list);
			j = HASH(ifv->ifv_vid, n2 - 1);
			LIST_INSERT_HEAD(&hash2[j], ifv, ifv_list);
		}
	free(trunk->hash, M_VLAN);
	trunk->hash = hash2;
	trunk->hwidth = hwidth2;
	trunk->hmask = n2 - 1;
	if (bootverbose)
		if_printf(trunk->parent,
		    "VLAN hash table resized from %d to %d buckets\n", n, n2);
}
static void vlan_growhash ( struct ifvlantrunk * trunk , int howmuch ) { struct ifvlan * ifv ; struct ifvlanhead * hash2 ; int hwidth2 , i , j , n , n2 ; TRUNK_LOCK_ASSERT ( trunk ) ; KASSERT ( trunk -> hwidth > 0 , ( " " , __func__ ) ) ; if ( howmuch == 0 ) { printf ( " \n " , __func__ ) ; return ; } hwidth2 = trunk -> hwidth + howmuch ; n = 1 << trunk -> hwidth ; n2 = 1 << hwidth2 ; if ( hwidth2 < VLAN_DEF_HWIDTH ) return ; hash2 = malloc ( sizeof ( struct ifvlanhead ) * n2 , M_VLAN , M_NOWAIT ) ; if ( hash2 == NULL ) { printf ( " \n " , __func__ ) ; return ; } for ( j = 0 ; j < n2 ; j ++ ) LIST_INIT ( & hash2 [ j ] ) ; for ( i = 0 ; i < n ; i ++ ) while ( ( ifv = LIST_FIRST ( & trunk -> hash [ i ] ) ) != NULL ) { LIST_REMOVE ( ifv , ifv_list ) ; j = HASH ( ifv -> ifv_vid , n2 - 1 ) ; LIST_INSERT_HEAD ( & hash2 [ j ] , ifv , ifv_list ) ; } free ( trunk -> hash , M_VLAN ) ; trunk -> hash = hash2 ; trunk -> hwidth = hwidth2 ; trunk -> hmask = n2 - 1 ; if ( bootverbose ) if_printf ( trunk -> parent , " \n " , n , n2 ) ; }
Grow the hash larger or smaller if memory permits.
Grow the hash larger or smaller if memory permits .
/* Harmless yet obvious coding error */ /* Do not shrink the table below the default */ /* M_NOWAIT because we're called with trunk mutex held */ /* We can live with the old hash table */