Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8531c5ff authored by Arthur Kepner's avatar Arthur Kepner Committed by Jeff Garzik
Browse files

[PATCH] bonding: inherit zero-copy flags of slaves

This change allows a bonding device to inherit the "zero-copy"
features of its slave devices.

It was inspired by a couple of previous postings on this topic:
http://marc.theaimsgroup.com/?l=bonding-devel&m=111924607327794&w=2
http://marc.theaimsgroup.com/?l=bonding-devel&m=111925242706297&w=2


and it's largely a combination of the patches that appear in those
emails.

Signed-off-by: default avatarArthur Kepner <akepner@sgi.com>
parent efcce839
Loading
Loading
Loading
Loading
+57 −1
Original line number Diff line number Diff line
@@ -1604,6 +1604,44 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_
	return 0;
}

#define BOND_INTERSECT_FEATURES \
	(NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)

/* 
 * Compute the features available to the bonding device by 
 * intersection of all of the slave devices' BOND_INTERSECT_FEATURES.
 * Call this after attaching or detaching a slave to update the 
 * bond's features.
 */
static int bond_compute_features(struct bonding *bond)
{
	int i;
	struct slave *slave;
	struct net_device *bond_dev = bond->dev;
	int features = bond->bond_features;

	bond_for_each_slave(bond, slave, i) {
		struct net_device * slave_dev = slave->dev;
		if (i == 0) {
			features |= BOND_INTERSECT_FEATURES;
		}
		features &=
			~(~slave_dev->features & BOND_INTERSECT_FEATURES);
	}

	/* turn off NETIF_F_SG if we need a csum and h/w can't do it */
	if ((features & NETIF_F_SG) && 
		!(features & (NETIF_F_IP_CSUM |
			      NETIF_F_NO_CSUM |
			      NETIF_F_HW_CSUM))) {
		features &= ~NETIF_F_SG;
	}

	bond_dev->features = features;

	return 0;
}

/* enslave device <slave> to bond device <master> */
static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
{
@@ -1811,6 +1849,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
	new_slave->delay = 0;
	new_slave->link_failure_count = 0;

	bond_compute_features(bond);

	if (bond->params.miimon && !bond->params.use_carrier) {
		link_reporting = bond_check_dev_link(bond, slave_dev, 1);

@@ -2100,6 +2140,8 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de
	/* release the slave from its bond */
	bond_detach_slave(bond, slave);

	bond_compute_features(bond);

	if (bond->primary_slave == slave) {
		bond->primary_slave = NULL;
	}
@@ -2243,6 +2285,8 @@ static int bond_release_all(struct net_device *bond_dev)
			bond_alb_deinit_slave(bond, slave);
		}

		bond_compute_features(bond);

		/* now that the slave is detached, unlock and perform
		 * all the undo steps that should not be called from
		 * within a lock.
@@ -3588,6 +3632,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond
static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev)
{
	struct net_device *bond_dev = slave_dev->master;
	struct bonding *bond = bond_dev->priv;

	switch (event) {
	case NETDEV_UNREGISTER:
@@ -3626,6 +3671,9 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
		 * TODO: handle changing the primary's name
		 */
		break;
	case NETDEV_FEAT_CHANGE:
		bond_compute_features(bond);
		break;
	default:
		break;
	}
@@ -4526,6 +4574,11 @@ static inline void bond_set_mode_ops(struct bonding *bond, int mode)
	}
}

static struct ethtool_ops bond_ethtool_ops = {
	.get_tx_csum		= ethtool_op_get_tx_csum,
	.get_sg			= ethtool_op_get_sg,
};

/*
 * Does not allocate but creates a /proc entry.
 * Allowed to fail.
@@ -4555,6 +4608,7 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
	bond_dev->stop = bond_close;
	bond_dev->get_stats = bond_get_stats;
	bond_dev->do_ioctl = bond_do_ioctl;
	bond_dev->ethtool_ops = &bond_ethtool_ops;
	bond_dev->set_multicast_list = bond_set_multicast_list;
	bond_dev->change_mtu = bond_change_mtu;
	bond_dev->set_mac_address = bond_set_mac_address;
@@ -4591,6 +4645,8 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
			       NETIF_F_HW_VLAN_RX |
			       NETIF_F_HW_VLAN_FILTER);

	bond->bond_features = bond_dev->features;

#ifdef CONFIG_PROC_FS
	bond_create_proc_entry(bond);
#endif
+3 −0
Original line number Diff line number Diff line
@@ -211,6 +211,9 @@ struct bonding {
	struct   bond_params params;
	struct   list_head vlan_list;
	struct   vlan_group *vlgrp;
	/* the features the bonding device supports, independently 
	 * of any slaves */
	int	 bond_features; 
};

/**