aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
authorNikolay Aleksandrov <razor@BlackWall.org>2013-08-01 10:54:50 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-01 19:42:02 -0400
commit15077228cab68e5e8c3cbf26a7f6ebacfac4c829 (patch)
treef0b8953b861203320d5387b809b0bcb5a8ef6179 /drivers/net/bonding/bond_main.c
parent78a646ced88450754613573f7d1fa7cb0de14bb3 (diff)
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 <nikolay@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c118
1 files changed, 51 insertions, 67 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index aa9da006fa68..5eee95c3b172 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3795,12 +3795,50 @@ unwind:
3795 return res; 3795 return res;
3796} 3796}
3797 3797
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 */
3808void 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
3798static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev) 3837static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
3799{ 3838{
3800 struct bonding *bond = netdev_priv(bond_dev); 3839 struct bonding *bond = netdev_priv(bond_dev);
3801 struct slave *slave, *start_at;
3802 int i, slave_no, res = 1;
3803 struct iphdr *iph = ip_hdr(skb); 3840 struct iphdr *iph = ip_hdr(skb);
3841 struct slave *slave;
3804 3842
3805 /* 3843 /*
3806 * Start with the curr_active_slave that joined the bond as the 3844 * 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
3809 * send the join/membership reports. The curr_active_slave found 3847 * send the join/membership reports. The curr_active_slave found
3810 * will send all of this type of traffic. 3848 * will send all of this type of traffic.
3811 */ 3849 */
3812 if ((iph->protocol == IPPROTO_IGMP) && 3850 if (iph->protocol == IPPROTO_IGMP && skb->protocol == htons(ETH_P_IP)) {
3813 (skb->protocol == htons(ETH_P_IP))) {
3814 slave = bond->curr_active_slave; 3851 slave = bond->curr_active_slave;
3815 if (!slave) 3852 if (slave && slave_can_tx(slave))
3816 goto out; 3853 bond_dev_queue_xmit(bond, skb, slave->dev);
3854 else
3855 bond_xmit_slave_id(bond, skb, 0);
3817 } else { 3856 } else {
3818 /* 3857 bond_xmit_slave_id(bond, skb,
3819 * Concurrent TX may collide on rr_tx_counter; we accept 3858 bond->rr_tx_counter++ % bond->slave_cnt);
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
3842out:
3843 if (res) {
3844 /* no suitable interface, frame not sent */
3845 kfree_skb(skb);
3846 } 3859 }
3847 3860
3848 return NETDEV_TX_OK; 3861 return NETDEV_TX_OK;
3849} 3862}
3850 3863
3851
3852/* 3864/*
3853 * in active-backup mode, we know that bond->curr_active_slave is always valid if 3865 * in active-backup mode, we know that bond->curr_active_slave is always valid if
3854 * the bond has a usable interface. 3866 * the bond has a usable interface.
@@ -3857,14 +3869,11 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
3857{ 3869{
3858 struct bonding *bond = netdev_priv(bond_dev); 3870 struct bonding *bond = netdev_priv(bond_dev);
3859 struct slave *slave; 3871 struct slave *slave;
3860 int res = 1;
3861 3872
3862 slave = bond->curr_active_slave; 3873 slave = bond->curr_active_slave;
3863 if (slave) 3874 if (slave)
3864 res = bond_dev_queue_xmit(bond, skb, slave->dev); 3875 bond_dev_queue_xmit(bond, skb, slave->dev);
3865 3876 else
3866 if (res)
3867 /* no suitable interface, frame not sent */
3868 kfree_skb(skb); 3877 kfree_skb(skb);
3869 3878
3870 return NETDEV_TX_OK; 3879 return NETDEV_TX_OK;
@@ -3878,34 +3887,9 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
3878static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) 3887static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
3879{ 3888{
3880 struct bonding *bond = netdev_priv(bond_dev); 3889 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;
3895 3890
3896 bond_for_each_slave_from(bond, slave, i, start_at) { 3891 bond_xmit_slave_id(bond, skb,
3897 if (IS_UP(slave->dev) && 3892 bond->xmit_hash_policy(skb, bond->slave_cnt));
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 }
3909 3893
3910 return NETDEV_TX_OK; 3894 return NETDEV_TX_OK;
3911} 3895}