Skip to content

Commit 1507722

Browse files
NikAleksandrovdavem330
authored andcommitted
bonding: factor out slave id tx code and simplify xmit paths
I factored out the tx xmit code which relies on slave id in bond_xmit_slave_id. It is global because later it can be used also in 3ad mode xmit. Unnecessary obvious comments are removed. Active-backup mode is simplified because bond_dev_queue_xmit always consumes the skb. bond_xmit_xor becomes one line because of bond_xmit_slave_id. bond_for_each_slave_from is not used in bond_xmit_slave_id because later when RCU is used we can avoid important race condition by using standard rculist routines. Signed-off-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 78a646c commit 1507722

File tree

2 files changed

+61
-67
lines changed

2 files changed

+61
-67
lines changed

drivers/net/bonding/bond_main.c

Lines changed: 51 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -3795,12 +3795,50 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
37953795
return res;
37963796
}
37973797

3798+
/**
3799+
* bond_xmit_slave_id - transmit skb through slave with slave_id
3800+
* @bond: bonding device that is transmitting
3801+
* @skb: buffer to transmit
3802+
* @slave_id: slave id up to slave_cnt-1 through which to transmit
3803+
*
3804+
* This function tries to transmit through slave with slave_id but in case
3805+
* it fails, it tries to find the first available slave for transmission.
3806+
* The skb is consumed in all cases, thus the function is void.
3807+
*/
3808+
void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id)
3809+
{
3810+
struct slave *slave;
3811+
int i = slave_id;
3812+
3813+
/* Here we start from the slave with slave_id */
3814+
bond_for_each_slave(bond, slave) {
3815+
if (--i < 0) {
3816+
if (slave_can_tx(slave)) {
3817+
bond_dev_queue_xmit(bond, skb, slave->dev);
3818+
return;
3819+
}
3820+
}
3821+
}
3822+
3823+
/* Here we start from the first slave up to slave_id */
3824+
i = slave_id;
3825+
bond_for_each_slave(bond, slave) {
3826+
if (--i < 0)
3827+
break;
3828+
if (slave_can_tx(slave)) {
3829+
bond_dev_queue_xmit(bond, skb, slave->dev);
3830+
return;
3831+
}
3832+
}
3833+
/* no slave that can tx has been found */
3834+
kfree_skb(skb);
3835+
}
3836+
37983837
static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
37993838
{
38003839
struct bonding *bond = netdev_priv(bond_dev);
3801-
struct slave *slave, *start_at;
3802-
int i, slave_no, res = 1;
38033840
struct iphdr *iph = ip_hdr(skb);
3841+
struct slave *slave;
38043842

38053843
/*
38063844
* Start with the curr_active_slave that joined the bond as the
@@ -3809,46 +3847,20 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
38093847
* send the join/membership reports. The curr_active_slave found
38103848
* will send all of this type of traffic.
38113849
*/
3812-
if ((iph->protocol == IPPROTO_IGMP) &&
3813-
(skb->protocol == htons(ETH_P_IP))) {
3850+
if (iph->protocol == IPPROTO_IGMP && skb->protocol == htons(ETH_P_IP)) {
38143851
slave = bond->curr_active_slave;
3815-
if (!slave)
3816-
goto out;
3852+
if (slave && slave_can_tx(slave))
3853+
bond_dev_queue_xmit(bond, skb, slave->dev);
3854+
else
3855+
bond_xmit_slave_id(bond, skb, 0);
38173856
} else {
3818-
/*
3819-
* Concurrent TX may collide on rr_tx_counter; we accept
3820-
* that as being rare enough not to justify using an
3821-
* atomic op here.
3822-
*/
3823-
slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
3824-
3825-
bond_for_each_slave(bond, slave) {
3826-
slave_no--;
3827-
if (slave_no < 0)
3828-
break;
3829-
}
3830-
}
3831-
3832-
start_at = slave;
3833-
bond_for_each_slave_from(bond, slave, i, start_at) {
3834-
if (IS_UP(slave->dev) &&
3835-
(slave->link == BOND_LINK_UP) &&
3836-
bond_is_active_slave(slave)) {
3837-
res = bond_dev_queue_xmit(bond, skb, slave->dev);
3838-
break;
3839-
}
3840-
}
3841-
3842-
out:
3843-
if (res) {
3844-
/* no suitable interface, frame not sent */
3845-
kfree_skb(skb);
3857+
bond_xmit_slave_id(bond, skb,
3858+
bond->rr_tx_counter++ % bond->slave_cnt);
38463859
}
38473860

38483861
return NETDEV_TX_OK;
38493862
}
38503863

3851-
38523864
/*
38533865
* in active-backup mode, we know that bond->curr_active_slave is always valid if
38543866
* the bond has a usable interface.
@@ -3857,14 +3869,11 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
38573869
{
38583870
struct bonding *bond = netdev_priv(bond_dev);
38593871
struct slave *slave;
3860-
int res = 1;
38613872

38623873
slave = bond->curr_active_slave;
38633874
if (slave)
3864-
res = bond_dev_queue_xmit(bond, skb, slave->dev);
3865-
3866-
if (res)
3867-
/* no suitable interface, frame not sent */
3875+
bond_dev_queue_xmit(bond, skb, slave->dev);
3876+
else
38683877
kfree_skb(skb);
38693878

38703879
return NETDEV_TX_OK;
@@ -3878,34 +3887,9 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
38783887
static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
38793888
{
38803889
struct bonding *bond = netdev_priv(bond_dev);
3881-
struct slave *slave, *start_at;
3882-
int slave_no;
3883-
int i;
3884-
int res = 1;
3885-
3886-
slave_no = bond->xmit_hash_policy(skb, bond->slave_cnt);
3887-
3888-
bond_for_each_slave(bond, slave) {
3889-
slave_no--;
3890-
if (slave_no < 0)
3891-
break;
3892-
}
3893-
3894-
start_at = slave;
38953890

3896-
bond_for_each_slave_from(bond, slave, i, start_at) {
3897-
if (IS_UP(slave->dev) &&
3898-
(slave->link == BOND_LINK_UP) &&
3899-
bond_is_active_slave(slave)) {
3900-
res = bond_dev_queue_xmit(bond, skb, slave->dev);
3901-
break;
3902-
}
3903-
}
3904-
3905-
if (res) {
3906-
/* no suitable interface, frame not sent */
3907-
kfree_skb(skb);
3908-
}
3891+
bond_xmit_slave_id(bond, skb,
3892+
bond->xmit_hash_policy(skb, bond->slave_cnt));
39093893

39103894
return NETDEV_TX_OK;
39113895
}

drivers/net/bonding/bonding.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,20 @@ static inline __be32 bond_confirm_addr(struct net_device *dev, __be32 dst, __be3
426426
return addr;
427427
}
428428

429+
static inline bool slave_can_tx(struct slave *slave)
430+
{
431+
if (IS_UP(slave->dev) && slave->link == BOND_LINK_UP &&
432+
bond_is_active_slave(slave))
433+
return true;
434+
else
435+
return false;
436+
}
437+
429438
struct bond_net;
430439

431440
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
432441
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
442+
void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id);
433443
int bond_create(struct net *net, const char *name);
434444
int bond_create_sysfs(struct bond_net *net);
435445
void bond_destroy_sysfs(struct bond_net *net);

0 commit comments

Comments
 (0)