Beispiel #1
0
/* Must be called before starting the monitor timer */
static int tlb_initialize(struct bonding *bond)
{
	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
	int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
	struct tlb_client_info *new_hashtbl;
	int i;

	spin_lock_init(&(bond_info->tx_hashtbl_lock));

	new_hashtbl = kzalloc(size, GFP_KERNEL);
	if (!new_hashtbl) {
		pr_err("%s: Error: Failed to allocate TLB hash table\n",
		       bond->dev->name);
		return -1;
	}
	_lock_tx_hashtbl(bond);

	bond_info->tx_hashtbl = new_hashtbl;

	for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) {
		tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1);
	}

	_unlock_tx_hashtbl(bond);

	return 0;
}
Beispiel #2
0
/* Caller must hold bond lock for read */
static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
{
	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
	struct tlb_client_info *hash_table;
	struct slave *assigned_slave,max_assigned_slave,slave;
	int i;

	_lock_tx_hashtbl(bond);

	hash_table = bond_info->tx_hashtbl;
	assigned_slave = hash_table[hash_index].tx_slave;
	if (!assigned_slave) {
		assigned_slave = tlb_get_least_loaded_slave(bond);
		if(assigned_slave == assigend_slave_old) {
			max_assigned_slave = assigned_slave;
			assigned_slave = max_assigned_slave->next;
			bond_for_each_slave_from(bond,slave,i) {
				if (IS_UP(slave->dev) && (slave->link == BOND_LINK_UP) 
					&& (slave->state == BOND_STATE_ACTIVE)) {
					if (compute_gap(slave) > compute_gap(assigned_slave) 
							&& slave != max_assigned_slave)
						assigned_slave = slave;
				}
			}
		}
Beispiel #3
0
/* Must be called only after all slaves have been released */
static void tlb_deinitialize(struct bonding *bond)
{
	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));

	_lock_tx_hashtbl(bond);

	kfree(bond_info->tx_hashtbl);
	bond_info->tx_hashtbl = NULL;

	_unlock_tx_hashtbl(bond);
}
Beispiel #4
0
/* Caller must hold bond lock for read */
struct slave*
tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
{
	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
	struct tlb_client_info *hash_table = NULL;
	struct slave *assigned_slave = NULL;

	_lock_tx_hashtbl(bond);

	hash_table = bond_info->tx_hashtbl;
	if (hash_table == NULL) {
		printk (KERN_ERR "%s: TLB hash table is NULL\n",
			bond->device->name);
		_unlock_tx_hashtbl(bond);
		return NULL;
	}

	assigned_slave = hash_table[hash_index].tx_slave;
	if (!assigned_slave) {
		assigned_slave = tlb_get_least_loaded_slave(bond);

		if (assigned_slave) {
			struct tlb_slave_info *slave_info =
				&(SLAVE_TLB_INFO(assigned_slave));
			u32 next_index = slave_info->head;

			hash_table[hash_index].tx_slave = assigned_slave;
			hash_table[hash_index].next = next_index;
			hash_table[hash_index].prev = TLB_NULL_INDEX;

			if (next_index != TLB_NULL_INDEX) {
				hash_table[next_index].prev = hash_index;
			}

			slave_info->head = hash_index;
			slave_info->load +=
				hash_table[hash_index].load_history;
		}
	}

	if (assigned_slave) {
		hash_table[hash_index].tx_bytes += skb_len;
	}

	_unlock_tx_hashtbl(bond);

	return assigned_slave;
}
Beispiel #5
0
/* Must be called before starting the monitor timer */
static int
tlb_initialize(struct bonding *bond)
{
	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
	int i;
	size_t size;

#if(TLB_HASH_TABLE_SIZE != 256)
	/* Key to the hash table is byte wide. Check the size! */
	#error Hash Table size is wrong.
#endif

	spin_lock_init(&(bond_info->tx_hashtbl_lock));

	_lock_tx_hashtbl(bond);
	if (bond_info->tx_hashtbl != NULL) {
		printk (KERN_ERR "%s: TLB hash table is not NULL\n",
			bond->device->name);
		_unlock_tx_hashtbl(bond);
		return -1;
	}

	size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
	bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
	if (bond_info->tx_hashtbl == NULL) {
		printk (KERN_ERR "%s: Failed to allocate TLB hash table\n",
			bond->device->name);
		_unlock_tx_hashtbl(bond);
		return -1;
	}

	memset(bond_info->tx_hashtbl, 0, size);
	for (i=0; i<TLB_HASH_TABLE_SIZE; i++) {
		tlb_init_table_entry(bond, i, 1);
	}
	_unlock_tx_hashtbl(bond);

	return 0;
}
Beispiel #6
0
/* Caller must hold bond lock for read */
static inline void
tlb_clear_slave(struct bonding *bond, struct slave *slave, u8 save_load)
{
	struct tlb_client_info *tx_hash_table = NULL;
	u32 index, next_index;

	/* clear slave from tx_hashtbl */
	_lock_tx_hashtbl(bond);
	tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;

	if (tx_hash_table) {
		index = SLAVE_TLB_INFO(slave).head;
		while (index != TLB_NULL_INDEX) {
			next_index = tx_hash_table[index].next;
			tlb_init_table_entry(bond, index, save_load);
			index = next_index;
		}
	}
	_unlock_tx_hashtbl(bond);

	tlb_init_slave(slave);
}
Beispiel #7
0
/* Caller must hold bond lock for read */
static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_load)
{
	struct tlb_client_info *tx_hash_table;
	u32 index;

	_lock_tx_hashtbl(bond);

	/* clear slave from tx_hashtbl */
	tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;

	/* skip this if we've already freed the tx hash table */
	if (tx_hash_table) {
		index = SLAVE_TLB_INFO(slave).head;
		while (index != TLB_NULL_INDEX) {
			u32 next_index = tx_hash_table[index].next;
			tlb_init_table_entry(&tx_hash_table[index], save_load);
			index = next_index;
		}
	}

	tlb_init_slave(slave);

	_unlock_tx_hashtbl(bond);
}