Skip to contentSkip to conversation

s2io: add dynamic LRO disable support

PATCH Applied Amerigo Wang 5 participants 11 messages Jun 22, 2010 – Jun 29, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v4 1/2 s2io: add dynamic LRO disable support

This patch adds dynamic LRO diable support for s2io net driver.

(I don't have s2io card, so only did compiling test. Anyone who wants to test this is more than welcome.)

This is based on Neil's initial work, and heavily modified based on Ramkrishna's suggestions.

---

drivers/net/s2io.c +38 -1
index 668327c..2e6e3b3 100644
@@ -795,7 +795,6 @@ static int init_shared_mem(struct s2io_nic *nic)
 		ring->rx_curr_put_info.ring_len = rx_cfg->num_rxd - 1;
 		ring->nic = nic;
 		ring->ring_no = i;
-		ring->lro = lro_enable;
 
 		blk_cnt = rx_cfg->num_rxd / (rxd_count[nic->rxd_mode] + 1);
 		/*  Allocating all the Rx blocks */
@@ -6684,6 +6683,41 @@ static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
 
 	return 0;
 }
+static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+{
+	struct s2io_nic *sp = netdev_priv(dev);
+	int rc = 0;
+	int changed = 0;
+
+	if (data & ~ETH_FLAG_LRO)
+		return -EOPNOTSUPP;
+
+	if (data & ETH_FLAG_LRO) {
+		if (lro_enable) {
+			if (!(dev->features & NETIF_F_LRO)) {
+				dev->features |= NETIF_F_LRO;
+				changed = 1;
+			}
+		} else
+			rc = -EOPNOTSUPP;
+	} else if (dev->features & NETIF_F_LRO) {
+		dev->features &= ~NETIF_F_LRO;
+		changed = 1;
+	}
+
+	if (changed && netif_running(dev)) {
+		s2io_stop_all_tx_queue(sp);
+		s2io_card_down(sp);
+		sp->lro = dev->features & NETIF_F_LRO;
+		rc = s2io_card_up(sp);
+		if (rc)
+			s2io_reset(sp);
+		else
+			s2io_start_all_tx_queue(sp);
+	}
+
+	return rc;
+}
 
 static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_settings = s2io_ethtool_gset,
@@ -6701,6 +6735,8 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_rx_csum = s2io_ethtool_get_rx_csum,
 	.set_rx_csum = s2io_ethtool_set_rx_csum,
 	.set_tx_csum = s2io_ethtool_op_set_tx_csum,
+	.set_flags = s2io_ethtool_set_flags,
+	.get_flags = ethtool_op_get_flags,
 	.set_sg = ethtool_op_set_sg,
 	.get_tso = s2io_ethtool_op_get_tso,
 	.set_tso = s2io_ethtool_op_set_tso,
@@ -7229,6 +7265,7 @@ static int s2io_card_up(struct s2io_nic *sp)
 		struct ring_info *ring = &mac_control->rings[i];
 
 		ring->mtu = dev->mtu;
+		ring->lro = sp->lro;
 		ret = fill_rx_buffers(sp, ring, 1);
 		if (ret) {
 			DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
#1 lore raw

PATCH v4 2/2 mlx4: add dynamic LRO disable support

This patch adds dynamic LRO diable support for mlx4 net driver. It also fixes a bug of mlx4, which checks NETIF_F_LRO flag in rx path without rtnl lock.

(I don't have mlx4 card, so only did compiling test. Anyone who wants to test this is more than welcome.)

This is based on Neil's initial work too, and heavily modified based on Stanislaw's suggestions.

---

drivers/net/mlx4/en_ethtool.c +37 -1
index d5afd03..b275238 100644
@@ -387,6 +387,42 @@ static void mlx4_en_get_ringparam(struct net_device *dev,
 	param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size;
 }
 
+static int mlx4_ethtool_op_set_flags(struct net_device *dev, u32 data)
+{
+	struct mlx4_en_priv *priv = netdev_priv(dev);
+	struct mlx4_en_dev *mdev = priv->mdev;
+	int rc = 0;
+	int changed = 0;
+
+	if (data & ~ETH_FLAG_LRO)
+		return -EOPNOTSUPP;
+
+	if (data & ETH_FLAG_LRO) {
+		if (mdev->profile.num_lro == 0)
+			return -EOPNOTSUPP;
+		if (!(dev->features & NETIF_F_LRO))
+			changed = 1;
+	} else if (dev->features & NETIF_F_LRO) {
+		changed = 1;
+	}
+
+	if (changed) {
+		if (netif_running(dev)) {
+			mutex_lock(&mdev->state_lock);
+			mlx4_en_stop_port(dev);
+		}
+		dev->features ^= NETIF_F_LRO;
+		if (netif_running(dev)) {
+			rc = mlx4_en_start_port(dev);
+			if (rc)
+				en_err(priv, "Failed to restart port\n");
+			mutex_unlock(&mdev->state_lock);
+		}
+	}
+
+	return rc;
+}
+
 const struct ethtool_ops mlx4_en_ethtool_ops = {
 	.get_drvinfo = mlx4_en_get_drvinfo,
 	.get_settings = mlx4_en_get_settings,
@@ -415,7 +451,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
 	.get_ringparam = mlx4_en_get_ringparam,
 	.set_ringparam = mlx4_en_set_ringparam,
 	.get_flags = ethtool_op_get_flags,
-	.set_flags = ethtool_op_set_flags,
+	.set_flags = mlx4_ethtool_op_set_flags,
 };
 
 
maintainer Applied
#2 lore raw

Re: [v4 Patch 2/2] mlx4: add dynamic LRO disable support

From: Amerigo Wang <[email protected]>
Date: Tue, 22 Jun 2010 04:50:17 -0400

Quoted 8 lines

This patch adds dynamic LRO diable support for mlx4 net driver. It also fixes a bug of mlx4, which checks NETIF_F_LRO flag in rx path without rtnl lock.

(I don't have mlx4 card, so only did compiling test. Anyone who wants to test this is more than welcome.)

Quoted 8 lines

This is based on Neil's initial work too, and heavily modified based on Stanislaw's suggestions.

Applied to net-next-2.6

I'd really like the module options to just die as the dynamic ethtool mechanism should be the only knob for this for consistency with the rest of the drivers.

#3 lore raw
In reply to Amerigo Wang
Quoted 7 lines · Amerigo Wang

This patch adds dynamic LRO diable support for s2io net driver.

(I don't have s2io card, so only did compiling test. Anyone who wants to test this is more than welcome.)

This is based on Neil's initial work, and heavily modified based on Ramkrishna's suggestions.

[...]

Quoted 7 lines
drivers/net/s2io.c +7 -0
+static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+{
+	struct s2io_nic *sp = netdev_priv(dev);
+	int rc = 0;
+	int changed = 0;
+
+	if (data & ~ETH_FLAG_LRO)

drivers/net/s2io.c static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data) · line 6702

Quoted 10 lines
drivers/net/s2io.c +10 -0
+		return -EOPNOTSUPP;
+
+	if (data & ETH_FLAG_LRO) {
+		if (lro_enable) {
+			if (!(dev->features & NETIF_F_LRO)) {
+				dev->features |= NETIF_F_LRO;
+				changed = 1;
+			}
+		} else
+			rc = -EOPNOTSUPP;

Should lro_enable=0 really prevent enabling it later? This seems unusual.

drivers/net/s2io.c static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data) · line 6711

Quoted 9 lines
drivers/net/s2io.c +9 -0
+	} else if (dev->features & NETIF_F_LRO) {
+		dev->features &= ~NETIF_F_LRO;
+		changed = 1;
+	}
+
+	if (changed && netif_running(dev)) {
+		s2io_stop_all_tx_queue(sp);
+		s2io_card_down(sp);
+		sp->lro = dev->features & NETIF_F_LRO;

[...]

This means s2io_nic::lro and ring_info::lro can have the value NETIF_F_LRO, where previously they would only have the value 0 or 1. I don't know whether this could be a problem, but the safe thing to do is to coerce the value by writing !!(dev->features & NETIF_F_LRO).

Ben.

Signature · 3 lines
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
#4 lore raw
Quoted 21 lines · On Tue, 22 Jun 2010 12:44:40 +0100 Ben Hutchings <[email protected]>…
Quoted 7 lines · Amerigo Wang

This patch adds dynamic LRO diable support for s2io net driver.

(I don't have s2io card, so only did compiling test. Anyone who wants to test this is more than welcome.)

This is based on Neil's initial work, and heavily modified based on Ramkrishna's suggestions.

[...]

Quoted 12 lines
drivers/net/s2io.c +12 -0
+static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+{
+	struct s2io_nic *sp = netdev_priv(dev);
+	int rc = 0;
+	int changed = 0;
+
+	if (data & ~ETH_FLAG_LRO)
+		return -EOPNOTSUPP;
+
+	if (data & ETH_FLAG_LRO) {
+		if (lro_enable) {
+			if (!(dev->features & NETIF_F_LRO)) {
Quoted 8 lines

drivers/net/s2io.c static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data) · line 6702

Quoted 5 lines
drivers/net/s2io.c +5 -0
+				dev->features |= NETIF_F_LRO;
+				changed = 1;
+			}
+		} else
+			rc = -EOPNOTSUPP;

Should lro_enable=0 really prevent enabling it later? This seems unusual.

We are doing this in bnx2x. Current Amerigo patch change to the same behavior mlx4. For me that have sense - if you want to disallow LRO - use module option.

In this case however lro_enable variable looks obsolete from times where there was no ethtool possibility to dynamic set/unset LRO. Perhaps it should be removed at all, but maybe not as part of that patch.

Stanislaw

author
#5 lore raw
In reply to Ben Hutchings
Quoted 21 lines · Ben Hutchings
Quoted 7 lines · Amerigo Wang

This patch adds dynamic LRO diable support for s2io net driver.

(I don't have s2io card, so only did compiling test. Anyone who wants to test this is more than welcome.)

This is based on Neil's initial work, and heavily modified based on Ramkrishna's suggestions.

[...]

Quoted 12 lines
drivers/net/s2io.c +12 -0
+static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+{
+	struct s2io_nic *sp = netdev_priv(dev);
+	int rc = 0;
+	int changed = 0;
+
+	if (data&  ~ETH_FLAG_LRO)
+		return -EOPNOTSUPP;
+
+	if (data&  ETH_FLAG_LRO) {
+		if (lro_enable) {
+			if (!(dev->features&  NETIF_F_LRO)) {
Quoted 9 lines

drivers/net/s2io.c static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data) · line 6702

Quoted 5 lines
drivers/net/s2io.c +5 -0
+				dev->features |= NETIF_F_LRO;
+				changed = 1;
+			}
+		} else
+			rc = -EOPNOTSUPP;

Should lro_enable=0 really prevent enabling it later? This seems unusual.

I agree with Stanislaw on this point.

Quoted 11 lines
Quoted 9 lines
drivers/net/s2io.c +9 -0
+	} else if (dev->features&  NETIF_F_LRO) {
+		dev->features&= ~NETIF_F_LRO;
+		changed = 1;
+	}
+
+	if (changed&&  netif_running(dev)) {
+		s2io_stop_all_tx_queue(sp);
+		s2io_card_down(sp);
+		sp->lro = dev->features&  NETIF_F_LRO;

[...]

Quoted 5 lines

This means s2io_nic::lro and ring_info::lro can have the value NETIF_F_LRO, where previously they would only have the value 0 or 1. I don't know whether this could be a problem, but the safe thing to do is to coerce the value by writing !!(dev->features& NETIF_F_LRO).

Yeah, agreed.
It seems that Jon already fixed this when he updated the patch.

Thanks!

#6 lore raw
In reply to Amerigo Wang
Quoted 5 lines · Amerigo Wang

This patch adds dynamic LRO diable support for s2io net driver.

(I don't have s2io card, so only did compiling test. Anyone who wants to test this is more than welcome.)

Unfortunately the patch did not quite work, mostly due to NETIF_F_LRO needing to be added at probe time to the device features. I was able to modify the patch to get it working, and will respond seperately with the working patch.

Thanks,
Jon

Quoted 87 lines

This is based on Neil's initial work, and heavily modified based on Ramkrishna's suggestions.

---

drivers/net/s2io.c +38 -2
index 668327c..2e6e3b3 100644
@@ -795,7 +795,6 @@ static int init_shared_mem(struct s2io_nic *nic)
 		ring->rx_curr_put_info.ring_len = rx_cfg->num_rxd - 1;
 		ring->nic = nic;
 		ring->ring_no = i;
-		ring->lro = lro_enable;
 
 		blk_cnt = rx_cfg->num_rxd / (rxd_count[nic->rxd_mode] + 1);
 		/*  Allocating all the Rx blocks */
@@ -6684,6 +6683,41 @@ static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
 
 	return 0;
 }
+static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+{
+	struct s2io_nic *sp = netdev_priv(dev);
+	int rc = 0;
+	int changed = 0;
+
+	if (data & ~ETH_FLAG_LRO)
+		return -EOPNOTSUPP;
+
+	if (data & ETH_FLAG_LRO) {
+		if (lro_enable) {
+			if (!(dev->features & NETIF_F_LRO)) {
+				dev->features |= NETIF_F_LRO;
+				changed = 1;
+			}
+		} else
+			rc = -EOPNOTSUPP;
+	} else if (dev->features & NETIF_F_LRO) {
+		dev->features &= ~NETIF_F_LRO;
+		changed = 1;
+	}
+
+	if (changed && netif_running(dev)) {
+		s2io_stop_all_tx_queue(sp);
+		s2io_card_down(sp);
+		sp->lro = dev->features & NETIF_F_LRO;
+		rc = s2io_card_up(sp);
+		if (rc)
+			s2io_reset(sp);
+		else
+			s2io_start_all_tx_queue(sp);
+	}
+
+	return rc;
+}
 
 static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_settings = s2io_ethtool_gset,
@@ -6701,6 +6735,8 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_rx_csum = s2io_ethtool_get_rx_csum,
 	.set_rx_csum = s2io_ethtool_set_rx_csum,
 	.set_tx_csum = s2io_ethtool_op_set_tx_csum,
+	.set_flags = s2io_ethtool_set_flags,
+	.get_flags = ethtool_op_get_flags,
 	.set_sg = ethtool_op_set_sg,
 	.get_tso = s2io_ethtool_op_get_tso,
 	.set_tso = s2io_ethtool_op_set_tso,
@@ -7229,6 +7265,7 @@ static int s2io_card_up(struct s2io_nic *sp)
 		struct ring_info *ring = &mac_control->rings[i];
 
 		ring->mtu = dev->mtu;
+		ring->lro = sp->lro;
 		ret = fill_rx_buffers(sp, ring, 1);
 		if (ret) {
 			DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
--

To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#7 lore raw
Quoted 4 lines · Jon Mason
Quoted 3 lines · Amerigo Wang

This patch adds dynamic LRO diable support for s2io net driver.

Quoted 8 lines
Quoted 2 lines

(I don't have s2io card, so only did compiling test. Anyone who wants to test this is more than welcome.)

Unfortunately the patch did not quite work, mostly due to NETIF_F_LRO needing to be added at probe time to the device features. I was able to modify the patch to get it working, and will respond seperately with the working patch.

Thanks very much, Jon!

I am very pleased to see this patch gets tested. :)

#8 lore raw

PATCH 1/1 s2io: add dynamic LRO disable support

In reply to Amerigo Wang

This patch adds dynamic LRO disable support for s2io net driver, enables LRO by default, increases the driver version number, and corrects the name of the LRO modparm.

This is mostly Wang's patch based on Neil's initial work, heavily modified based on Ramkrishna's suggestions. This has been tested on a Neterion Xframe adapter and verified via adapter LRO statistics.

---

drivers/net/s2io.c +45 -5
index 668327c..a032d72 100644
@@ -38,7 +38,7 @@
  * Tx descriptors that can be associated with each corresponding FIFO.
  * intr_type: This defines the type of interrupt. The values can be 0(INTA),
  *     2(MSI_X). Default value is '2(MSI_X)'
- * lro_enable: Specifies whether to enable Large Receive Offload (LRO) or not.
+ * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
  *     Possible values '1' for enable '0' for disable. Default is '0'
  * lro_max_pkts: This parameter defines maximum number of packets can be
  *     aggregated as a single large packet
@@ -90,7 +90,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.25"
+#define DRV_VERSION "2.0.26.26"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -496,7 +496,7 @@ S2IO_PARM_INT(rxsync_frequency, 3);
 /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
 S2IO_PARM_INT(intr_type, 2);
 /* Large receive offload feature */
-static unsigned int lro_enable;
+static unsigned int lro_enable = 1;
 module_param_named(lro, lro_enable, uint, 0);
 
 /* Max pkts to be aggregated by LRO at one time. If not specified,
@@ -795,7 +795,6 @@ static int init_shared_mem(struct s2io_nic *nic)
 		ring->rx_curr_put_info.ring_len = rx_cfg->num_rxd - 1;
 		ring->nic = nic;
 		ring->ring_no = i;
-		ring->lro = lro_enable;
 
 		blk_cnt = rx_cfg->num_rxd / (rxd_count[nic->rxd_mode] + 1);
 		/*  Allocating all the Rx blocks */
@@ -6675,6 +6674,7 @@ static u32 s2io_ethtool_op_get_tso(struct net_device *dev)
 {
 	return (dev->features & NETIF_F_TSO) != 0;
 }
+
 static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
 {
 	if (data)
@@ -6685,6 +6685,42 @@ static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
 	return 0;
 }
 
+static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+{
+	struct s2io_nic *sp = netdev_priv(dev);
+	int rc = 0;
+	int changed = 0;
+
+	if (data & ~ETH_FLAG_LRO)
+		return -EOPNOTSUPP;
+
+	if (data & ETH_FLAG_LRO) {
+		if (lro_enable) {
+			if (!(dev->features & NETIF_F_LRO)) {
+				dev->features |= NETIF_F_LRO;
+				changed = 1;
+			}
+		} else
+			rc = -EINVAL;
+	} else if (dev->features & NETIF_F_LRO) {
+		dev->features &= ~NETIF_F_LRO;
+		changed = 1;
+	}
+
+	if (changed && netif_running(dev)) {
+		s2io_stop_all_tx_queue(sp);
+		s2io_card_down(sp);
+		sp->lro = !!(dev->features & NETIF_F_LRO);
+		rc = s2io_card_up(sp);
+		if (rc)
+			s2io_reset(sp);
+		else
+			s2io_start_all_tx_queue(sp);
+	}
+
+	return rc;
+}
+
 static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_settings = s2io_ethtool_gset,
 	.set_settings = s2io_ethtool_sset,
@@ -6701,6 +6737,8 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_rx_csum = s2io_ethtool_get_rx_csum,
 	.set_rx_csum = s2io_ethtool_set_rx_csum,
 	.set_tx_csum = s2io_ethtool_op_set_tx_csum,
+	.set_flags = s2io_ethtool_set_flags,
+	.get_flags = ethtool_op_get_flags,
 	.set_sg = ethtool_op_set_sg,
 	.get_tso = s2io_ethtool_op_get_tso,
 	.set_tso = s2io_ethtool_op_set_tso,
@@ -7229,6 +7267,7 @@ static int s2io_card_up(struct s2io_nic *sp)
 		struct ring_info *ring = &mac_control->rings[i];
 
 		ring->mtu = dev->mtu;
+		ring->lro = sp->lro;
 		ret = fill_rx_buffers(sp, ring, 1);
 		if (ret) {
 			DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
@@ -7974,7 +8013,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	dev->netdev_ops = &s2io_netdev_ops;
 	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-
+	if (lro_enable)
+		dev->features |= NETIF_F_LRO;
 	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
 	if (sp->high_dma_flag == true)
 		dev->features |= NETIF_F_HIGHDMA;
author
#9 lore raw
Quoted 4 lines · Jon Mason

This patch adds dynamic LRO disable support for s2io net driver, enables LRO by default, increases the driver version number, and corrects the name of the LRO modparm.

Very good work, Jon! I believe this version is the best we have.

Thanks again!

maintainer Applied
#10 lore raw
In reply to Jon Mason

From: Jon Mason <[email protected]>
Date: Thu, 24 Jun 2010 23:45:10 -0500

Quoted 8 lines

This patch adds dynamic LRO disable support for s2io net driver, enables LRO by default, increases the driver version number, and corrects the name of the LRO modparm.

This is mostly Wang's patch based on Neil's initial work, heavily modified based on Ramkrishna's suggestions. This has been tested on a Neterion Xframe adapter and verified via adapter LRO statistics.

Quoted 6 lines

Applied to net-next-2.6