Netdev List
 help / color / mirror / Atom feed
* [net-next 00/11][pull request] Intel Wired LAN Driver Updates
From: Jeff Kirsher @ 2012-11-13 14:03 UTC (permalink / raw)
  To: davem; +Cc: Jeff Kirsher, netdev, gospo, sassmann

This series contains updates to ixgbe, ixgbevf and igb.

The following are changes since commit 9fafd65ad407d4e0c96919a325f568dd95d032af:
  ipv6 ndisc: Use pre-defined in6addr_linklocal_allnodes.
and are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master

Akeem G. Abodunrin (2):
  igb: Support for modifying UDP RSS flow hashing
  igb: Ethtool support to enable and disable EEE

Alexander Duyck (4):
  ixgbe: Do not use DCA to prefetch the entire packet into the cache
  igb: Make TSO check for CHECKSUM_PARTIAL to avoid skb_is_gso check
  igb: Update igb Tx flags to improve code efficiency
  igb: Improve performance and reduce size of igb_tx_map

Carolyn Wyborny (1):
  igb: Clear Go Link Disconnect for 82580 and later devices

Emil Tantilov (1):
  ixgbevf: fix possible use of uninitialized variable

Greg Rose (2):
  ixgbevf: Add flag to indicate when rx is in net poll
  ixgbevf: Reduce size of maximum rx buffer

Jakub Kicinski (1):
  ixgbevf: make sure probe fails on MSI-X enable error

 drivers/net/ethernet/intel/igb/e1000_82575.c      |   8 +
 drivers/net/ethernet/intel/igb/e1000_defines.h    |   1 +
 drivers/net/ethernet/intel/igb/e1000_phy.h        |   1 +
 drivers/net/ethernet/intel/igb/igb.h              |  31 ++-
 drivers/net/ethernet/intel/igb/igb_ethtool.c      | 281 ++++++++++++++++++++++
 drivers/net/ethernet/intel/igb/igb_main.c         | 124 +++++-----
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c     |   1 -
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |   9 +-
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |  54 +++--
 9 files changed, 412 insertions(+), 98 deletions(-)

-- 
1.7.11.7

^ permalink raw reply

* [net-next 01/11] ixgbe: Do not use DCA to prefetch the entire packet into the cache
From: Jeff Kirsher @ 2012-11-13 14:03 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1352815405-751-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Alexander Duyck <alexander.h.duyck@intel.com>

The way the code was previously written it was causing DCA to prefetch the
entire packet into the cache when it was enabled.  That is excessive as we
only really need the headers.

We are now prefetching the headers via software so doing this from DCA would
be redundant anyway.  So clear the bit that was causing us to prefetch the
packet data and instead only use DCA for the descriptor rings.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 690535a..38fc186 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1015,7 +1015,6 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
 	 * which will cause the DCA tag to be cleared.
 	 */
 	rxctrl |= IXGBE_DCA_RXCTRL_DESC_RRO_EN |
-		  IXGBE_DCA_RXCTRL_DATA_DCA_EN |
 		  IXGBE_DCA_RXCTRL_DESC_DCA_EN;
 
 	IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl);
-- 
1.7.11.7

^ permalink raw reply related

* e1000e on DH55HC stalling and kernel panic in 3.6.6
From: Denys Fedoryshchenko @ 2012-11-13 13:58 UTC (permalink / raw)
  To: jeffrey.t.kirsher, jesse.brandeburg, bruce.w.allan,
	carolyn.wyborny, donald.c.skidmore, gregory.v.rose,
	peter.p.waskiewicz.jr, alexander.h.duyck, john.ronciak,
	e1000-devel, netdev, linux-kernel

Hi

I just tried to run latest kernel on my DH55HC motherboard latest 
kernel 3.6.6 and got various network problems, such as network traffic 
are stopping, and sometimes i am getting kernel panic.
When traffic are stopping, ethtool -r eth0 sometimes helps.
When i do ethtool -G eth0 rx NNN , sometimes it will give kernel panic, 
but it is hard to reproduce.

I tried to capture panic on pictures, so will try to decode on what i 
got photo, it is a nightmare, but sadly i dont have serial in hands to 
get data over it.

skbuff: skb_over_panic: text:f86fc769 len:25807 put:25807 head:c1da1800 
data:c1da1840 tail:0xc1da7d0f end:c1da1f40 dev:eth0
kernel BUG at net/core/skbuff.c:127
opcode: 0000 [#1] SMP
Pid: 0 comm: swapper/6 Not tained 3.6.6-build-0063 #23
EIP: 0060:[<c02e7980>] EFLAGS: 00010296 CPU:6
EIP is at skb_put+0x83/0x8e

There is registers and stack, let me know if you need specific fields

Call trace:
f86fc769 ? e1000_clean_rx_irq+0x1e1/0x2af [e1000e]
f86fc769 e1000_clean_rx_irq+0x1e1/0x2af [e1000e]
f86fcc73 e1000e_poll+0x6a/0x209 [e1000e]
c02f1630 net_rx_action+0x90/0x15d
c01302d5 __do_softirq+0x8a/-x13b
c013024b ? local_bh_enable+0xd/0xd
<IRQ>
c0130504 irq_exit+0x41/0x91
c0102c37 do_IRQ+0x79/0x8d

There is also more data, let me know if you need it.


---
Denys Fedoryshchenko, Network Engineer, Virtual ISP S.A.L.

^ permalink raw reply

* [RFC PATCH v1 3.7.0-rc4 2/2] dt:net/stmmac: Add dt specific phy reset callback support.
From: Srinivas KANDAGATLA @ 2012-11-13 13:50 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: netdev, devicetree-discuss, srinivas.kandagatla, davem

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch adds phy reset callback support for stmmac driver via device
trees. It adds three new properties to gmac device tree bindings to
define the reset signal via gpio.
With this patch users can conveniently pass reset gpio number with pre,
pulse and post delay in micro secs via DTs.

 active low:
	_________		 ____________
  <pre-delay>	 | <pulse-delay>|<post-delay>
		 |		|
		 |______________|

 active high:
 		 ________________
    <pre-delay>  |<pulse-delay>	|<post-delay>
		 |		|
	_________|		|___________

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 Documentation/devicetree/bindings/net/stmmac.txt  |   10 ++++
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |   50 +++++++++++++++++----
 2 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt
index b55d369..cdc536c 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -37,6 +37,12 @@ Optional properties:
 - snps,phy-bus-id	Mdio bus number to connect. if not specified 0 is used.
 - snps,phy-addr		phy address to connect to.
 
+- snps,reset-gpio 	gpio number for phy reset.
+- snps,reset-active-low boolean flag to indicate if phy reset is active low.
+- snps,reset-delays-us  is triplet of delays
+	The 1st cell is reset pre-delay in micro seconds.
+	The 2nd cell is reset pulse in micro seconds.
+	The 3rd cell is reset post-delay in micro seconds.
 
 Examples:
 
@@ -63,4 +69,8 @@ Examples:
 		snps,phy-bus-name = "stmmac";
 		snps,phy-bus-id = <0>;
 		snps,phy-addr = <0x9>;
+
+		snps,reset-gpio = <&gpio_bank4 7>;
+		snps,reset-active-low;
+		snps,reset-delays-us = <0 10000 10000>;
 	};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 0376a5e..f965e83 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -27,6 +27,9 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+
 #include <asm/io.h>
 
 #include "stmmac.h"
@@ -131,17 +134,46 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
 	struct net_device *ndev = bus->priv;
 	struct stmmac_priv *priv = netdev_priv(ndev);
 	unsigned int mii_address = priv->hw->mii.addr;
+	struct device *dev = priv->device;
 
-	if (priv->plat->mdio_bus_data->phy_reset) {
-		pr_debug("stmmac_mdio_reset: calling phy_reset\n");
-		priv->plat->mdio_bus_data->phy_reset(priv->plat->bsp_priv);
-	}
+	if (!dev->of_node) {
+		if (priv->plat->mdio_bus_data->phy_reset) {
+			pr_debug("stmmac_mdio_reset: calling phy_reset\n");
+			priv->plat->mdio_bus_data->phy_reset(
+							priv->plat->bsp_priv);
+		}
+
+		/* This is a workaround for problems with the STE101P PHY.
+		 * It doesn't complete its reset until at least one clock cycle
+		 * on MDC, so perform a dummy mdio read.
+		 */
+		writel(0, priv->ioaddr + mii_address);
+	} else {
+		int reset_gpio, active_low;
+		struct device_node *np = dev->of_node;
+		u32 delays[3] = {0,};
+
+		if (!np)
+			return 0;
+
+		reset_gpio = of_get_named_gpio(np, "snps,reset-gpio", 0);
+		if (reset_gpio < 0)
+			return 0;
 
-	/* This is a workaround for problems with the STE101P PHY.
-	 * It doesn't complete its reset until at least one clock cycle
-	 * on MDC, so perform a dummy mdio read.
-	 */
-	writel(0, priv->ioaddr + mii_address);
+		active_low = of_get_property(np,
+				"snps,reset-active-low", NULL) ? 1 : 0;
+		of_property_read_u32_array(np,
+				"snps,reset-delays-us", delays, 3);
+
+		gpio_request(reset_gpio, "mdio-reset");
+		gpio_direction_output(reset_gpio, active_low ? 1 : 0);
+		udelay(delays[0]);
+		gpio_set_value(reset_gpio, active_low ? 0 : 1);
+		udelay(delays[1]);
+		gpio_set_value(reset_gpio, active_low ? 1 : 0);
+		udelay(delays[2]);
+		gpio_free(reset_gpio);
+	}
 #endif
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related

* [RFC PATCH v1 3.7.0-rc4 1/2] dt:net/stmmac: Add complete device tree support
From: Srinivas KANDAGATLA @ 2012-11-13 13:50 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: netdev, devicetree-discuss, srinivas.kandagatla, davem

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

This patch attempts to add full device tree support to stmmac driver,
previously support to few optional properties were missed in both
bindings and driver.
With this patch DT support should be complete for stmmac driver.

Also all the vendor specific properties are prefixed with snps.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 Documentation/devicetree/bindings/net/stmmac.txt   |   41 +++++++++++++-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   58 ++++++++++++++------
 2 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt
index 060bbf0..b55d369 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -14,16 +14,53 @@ Required properties:
   Supported values are: "mii", "rmii", "gmii", "rgmii".
 
 Optional properties:
-- mac-address: 6 bytes, mac address
+- mac-address		6 bytes, mac address
+- phy-handle		Should be a phandle to the PHY.
+- snps,clk-csr		Fixed CSR Clock range selection.
+- snps,enh-desc		Boolean flag to indicate if mac support
+			enhanced descriptors.
+- snps,tx-coe		flag for Tx Checksum Offload engine presence
+- snps,rx-coe		flag fo Rx Checksum Offload engine presence.
+- snps,bugged-jumbo	some HWs are not able to perform the csum in HW for
+			over-sized frames due to limited buffer sizes.
+			Setting this flag the csum will be done in SW on
+			JUMBO frames.
+- snps,force-sf-dma-mode  force DMA to use the Store and Forward mode
+			instead of the Threshold.
+- snps,pbl		Programmable Burst Length
+- snps,fixed-burst	Program the DMA to use the fixed burst mode
+- snps,burst-len		This is the value we put in the register
+			supported values are provided as macros in
+			linux/stmmac.h header file.
+- snps,phy-bus-name	Name of the mdio bus to connect. if not specified
+			mac attempts to connect to stmmac mdio bus.
+- snps,phy-bus-id	Mdio bus number to connect. if not specified 0 is used.
+- snps,phy-addr		phy address to connect to.
+
 
 Examples:
 
 	gmac0: ethernet@e0800000 {
-		compatible = "st,spear600-gmac";
+		compatible = "snps,dwmac";
 		reg = <0xe0800000 0x8000>;
 		interrupt-parent = <&vic1>;
 		interrupts = <24 23>;
 		interrupt-names = "macirq", "eth_wake_irq";
 		mac-address = [000000000000]; /* Filled in by U-Boot */
 		phy-mode = "gmii";
+
+		snps,clk-csr	= <0x0>;
+		snps,enh-desc;
+		snps,tx-coe;
+		snps,rx-coe;
+		snps,bugged-jumbo;
+		snps,force-sf-dma-mode;
+		snps,pbl	= <32>;
+		snps,burst-len	= <32>;
+		snps,fixed-burst;
+
+		/* PHY specific */
+		snps,phy-bus-name = "stmmac";
+		snps,phy-bus-id = <0>;
+		snps,phy-addr = <0x9>;
 	};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index ed112b5..6ee7548 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -29,26 +29,31 @@
 #include "stmmac.h"
 
 #ifdef CONFIG_OF
+
+static u64 stmmac_dma_mask = DMA_BIT_MASK(32);
 static int __devinit stmmac_probe_config_dt(struct platform_device *pdev,
 					    struct plat_stmmacenet_data *plat,
 					    const char **mac)
 {
 	struct device_node *np = pdev->dev.of_node;
-
+	struct stmmac_dma_cfg *dma_cfg;
+	const char **phy_bus_name = (const char **)&plat->phy_bus_name;
 	if (!np)
 		return -ENODEV;
 
 	*mac = of_get_mac_address(np);
 	plat->interface = of_get_phy_mode(np);
-	plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
-					   sizeof(struct stmmac_mdio_bus_data),
-					   GFP_KERNEL);
+	of_property_read_string(np, "snps,phy-bus-name", phy_bus_name);
+	of_property_read_u32(np, "snps,phy-bus-id", &plat->bus_id);
+	of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr);
+
+	if (*phy_bus_name && strcmp(*phy_bus_name, "stmmac"))
+		plat->mdio_bus_data = NULL;
+	else
+		plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
+					sizeof(struct stmmac_mdio_bus_data),
+					GFP_KERNEL);
 
-	/*
-	 * Currently only the properties needed on SPEAr600
-	 * are provided. All other properties should be added
-	 * once needed on other platforms.
-	 */
 	if (of_device_is_compatible(np, "st,spear600-gmac") ||
 		of_device_is_compatible(np, "snps,dwmac-3.70a") ||
 		of_device_is_compatible(np, "snps,dwmac")) {
@@ -56,6 +61,24 @@ static int __devinit stmmac_probe_config_dt(struct platform_device *pdev,
 		plat->pmt = 1;
 	}
 
+	of_property_read_u32(np, "snps,clk-csr", &plat->clk_csr);
+
+	plat->enh_desc = of_property_read_bool(np, "snps,enh-desc");
+	plat->tx_coe = of_property_read_bool(np, "snps,tx-coe");
+	plat->rx_coe = of_property_read_bool(np, "snps,rx-coe");
+	plat->bugged_jumbo = of_property_read_bool(np, "snps,bugged-jumbo");
+	plat->force_sf_dma_mode = of_property_read_bool(np,
+					"snps,force-sf-dma-mode");
+
+	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL);
+	plat->dma_cfg = dma_cfg;
+	of_property_read_u32(np, "snps,burst-len", &dma_cfg->burst_len);
+	of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
+	dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
+	dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
+
+	if (!pdev->dev.dma_mask)
+		pdev->dev.dma_mask = &stmmac_dma_mask;
 	return 0;
 }
 #else
@@ -93,14 +116,17 @@ static int __devinit stmmac_pltfr_probe(struct platform_device *pdev)
 		pr_err("%s: ERROR: memory mapping failed", __func__);
 		return -ENOMEM;
 	}
-
+	plat_dat = pdev->dev.platform_data;
 	if (pdev->dev.of_node) {
-		plat_dat = devm_kzalloc(&pdev->dev,
+		if (!plat_dat) {
+			/* no data from OF_DEV_AUXDATA */
+			plat_dat = devm_kzalloc(&pdev->dev,
 					sizeof(struct plat_stmmacenet_data),
 					GFP_KERNEL);
-		if (!plat_dat) {
-			pr_err("%s: ERROR: no memory", __func__);
-			return  -ENOMEM;
+			if (!plat_dat) {
+				pr_err("%s: ERROR: no memory", __func__);
+				return  -ENOMEM;
+			}
 		}
 
 		ret = stmmac_probe_config_dt(pdev, plat_dat, &mac);
@@ -108,8 +134,6 @@ static int __devinit stmmac_pltfr_probe(struct platform_device *pdev)
 			pr_err("%s: main dt probe failed", __func__);
 			return ret;
 		}
-	} else {
-		plat_dat = pdev->dev.platform_data;
 	}
 
 	/* Custom initialisation (if needed)*/
-- 
1.7.0.4

^ permalink raw reply related

* [RFC PATCH v1 3.7.0-rc4 0/2] dt:net/stmmac add full device tree support
From: Srinivas KANDAGATLA @ 2012-11-13 13:50 UTC (permalink / raw)
  To: peppe.cavallaro-qxv4g6HH51o
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q

From: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>

This patch series attempts to add full device tree support to stmmac driver.
Existing device bindings do not cover all the possible use cases of stmmac driver,
so new properties are added.

And also stmmac phy reset callback support via devicetrees is added.

Srinivas Kandagatla (2):
  dt:net/stmmac: Add complete device tree support
  dt:net/stmmac: Add dt specific phy reset callback support.

 Documentation/devicetree/bindings/net/stmmac.txt   |   51 +++++++++++++++++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |   50 ++++++++++++++---
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   58 ++++++++++++++------
 3 files changed, 131 insertions(+), 28 deletions(-)

^ permalink raw reply

* Re: SR-IOV problem with Intel 82599EB (not enough MMIO resources for SR-IOV)
From: Jason Gao @ 2012-11-13 13:38 UTC (permalink / raw)
  To: bhelgaas, Rose, Gregory V, sibai.li
  Cc: ddutile, Kirsher, Jeffrey T, linux-kernel, netdev, kvm,
	e1000-devel@lists.sourceforge.net, linux-pci, Yinghai Lu
In-Reply-To: <CAErSpo4xn9t=4yXGLdPQMtUJF=n38tYrMutAoj7NCsLUzQEbcg@mail.gmail.com>

I'm very sorry for delayed reply.now SR-IOV works for me in Centos
6.3,thank all of you.


On Fri, Nov 9, 2012 at 11:26 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> Linux normally uses the resource assignments done by the BIOS, but it
> is possible for the kernel to reassign those.  We don't have good
> automatic support for that yet, but on a recent upstream kernel, you
> can try "pci=realloc".  I doubt this option is in CentOS 6.3, though

Thank you very much,I try "pci=realloc" in Centos 6.3,and now it works for me.



On Sat, Nov 10, 2012 at 2:08 AM, Li, Sibai <sibai.li@intel.com> wrote:
> DellR710 with the latest BIOS should work fine for SR-IOV. My BIOS is v.6.3.0 and release date is 07/24/2012
> Please check if you configured intel_iommu=on in the grub.conf file.
> If you did, check your kernel .config file under Device Drivers-> IOMMU Hardware support->enable Support for Intel IOMMU using DMA remapping Devices, enable Intel DMA Remapping Devices by Default, enable Support for Interrupt Remapping.

thank you Sibai,Our server "Dell R710",its BIOS version is just
v.6.3.0 and release date is 07/24/2012,and I also configured
intel_iommu=on in the grub.conf file,but I can't find these IOMMU
options in "Device Drivers" in my kernel(2.6.32-279) .config file ,
btw my os is Centos 6.3(RHEL6.3),although the problem solved,I'd like
to know what's your os version ,kernel version?

^ permalink raw reply

* [PATCH v3 03/11] bnx2x: use prandom_bytes()
From: Akinobu Mita @ 2012-11-13 13:37 UTC (permalink / raw)
  To: linux-kernel, akpm; +Cc: Akinobu Mita, Eilon Greenstein, netdev
In-Reply-To: <1352813830-4624-1-git-send-email-akinobu.mita@gmail.com>

Use prandom_bytes() to fill rss key with pseudo-random bytes.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Eilon Greenstein <eilong@broadcom.com>
Cc: netdev@vger.kernel.org
---
* v3
- rename random32_get_bytes to prandom_bytes

 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 4833b6a..257d38b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1741,7 +1741,6 @@ int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
 			bool config_hash)
 {
 	struct bnx2x_config_rss_params params = {NULL};
-	int i;
 
 	/* Although RSS is meaningless when there is a single HW queue we
 	 * still need it enabled in order to have HW Rx hash generated.
@@ -1773,9 +1772,7 @@ int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
 
 	if (config_hash) {
 		/* RSS keys */
-		for (i = 0; i < sizeof(params.rss_key) / 4; i++)
-			params.rss_key[i] = random32();
-
+		prandom_bytes(params.rss_key, sizeof(params.rss_key));
 		__set_bit(BNX2X_RSS_SET_SRCH, &params.rss_flags);
 	}
 
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH v3 02/11] prandom: introduce prandom_bytes() and prandom_bytes_state()
From: Akinobu Mita @ 2012-11-13 13:37 UTC (permalink / raw)
  To: linux-kernel, akpm
  Cc: Akinobu Mita, Theodore Ts'o, Artem Bityutskiy, Adrian Hunter,
	David Woodhouse, linux-mtd, Eilon Greenstein, netdev
In-Reply-To: <1352813830-4624-1-git-send-email-akinobu.mita@gmail.com>

Add functions to get the requested number of pseudo-random bytes.

The difference from get_random_bytes() is that it generates pseudo-random
numbers by prandom_u32().  It doesn't consume the entropy pool, and the
sequence is reproducible if the same rnd_state is used.  So it is suitable
for generating random bytes for testing.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Artem Bityutskiy <dedekind1@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: linux-mtd@lists.infradead.org
Cc: Eilon Greenstein <eilong@broadcom.com>
Cc: netdev@vger.kernel.org
---
* v3
- rename random32_get_bytes_state to prandom_bytes_state
- ensure prandom_bytes_state() generates same bytes with same rnd_state

* v2
- rename prandom32_get_bytes to random32_get_bytes_state

 include/linux/random.h |  2 ++
 lib/random32.c         | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/include/linux/random.h b/include/linux/random.h
index db6debc..d984608 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -26,6 +26,7 @@ unsigned int get_random_int(void);
 unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len);
 
 u32 prandom_u32(void);
+void prandom_bytes(void *buf, int nbytes);
 void prandom_seed(u32 seed);
 
 /*
@@ -36,6 +37,7 @@ void prandom_seed(u32 seed);
 #define srandom32(seed) prandom_seed(seed)
 
 u32 prandom_u32_state(struct rnd_state *);
+void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes);
 
 /*
  * Handle minimum values for seeds
diff --git a/lib/random32.c b/lib/random32.c
index d1830fa..52280d5 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -77,6 +77,55 @@ u32 prandom_u32(void)
 }
 EXPORT_SYMBOL(prandom_u32);
 
+/*
+ *	prandom_bytes_state - get the requested number of pseudo-random bytes
+ *
+ *	@state: pointer to state structure holding seeded state.
+ *	@buf: where to copy the pseudo-random bytes to
+ *	@bytes: the requested number of bytes
+ *
+ *	This is used for pseudo-randomness with no outside seeding.
+ *	For more random results, use prandom_bytes().
+ */
+void prandom_bytes_state(struct rnd_state *state, void *buf, int bytes)
+{
+	unsigned char *p = buf;
+	int i;
+
+	for (i = 0; i < round_down(bytes, sizeof(u32)); i += sizeof(u32)) {
+		u32 random = prandom_u32_state(state);
+		int j;
+
+		for (j = 0; j < sizeof(u32); j++) {
+			p[i + j] = random;
+			random >>= BITS_PER_BYTE;
+		}
+	}
+	if (i < bytes) {
+		u32 random = prandom_u32_state(state);
+
+		for (; i < bytes; i++) {
+			p[i] = random;
+			random >>= BITS_PER_BYTE;
+		}
+	}
+}
+EXPORT_SYMBOL(prandom_bytes_state);
+
+/**
+ *	prandom_bytes - get the requested number of pseudo-random bytes
+ *	@buf: where to copy the pseudo-random bytes to
+ *	@bytes: the requested number of bytes
+ */
+void prandom_bytes(void *buf, int bytes)
+{
+	struct rnd_state *state = &get_cpu_var(net_rand_state);
+
+	prandom_bytes_state(state, buf, bytes);
+	put_cpu_var(state);
+}
+EXPORT_SYMBOL(prandom_bytes);
+
 /**
  *	prandom_seed - add entropy to pseudo random number generator
  *	@seed: seed value
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH v3 00/11] rename random32 to prandom and introduce prandom_bytes()
From: Akinobu Mita @ 2012-11-13 13:36 UTC (permalink / raw)
  To: linux-kernel, akpm
  Cc: Akinobu Mita, Theodore Ts'o, Artem Bityutskiy, Adrian Hunter,
	David Woodhouse, linux-mtd, Eilon Greenstein, netdev, Robert Love,
	devel, Michel Lespinasse

This patchset introduces new functions into random32 library for
getting the requested number of pseudo-random bytes.

Before introducing these new functions into random32 library,
rename all random32 functions to have 'prandom_' prefix.  As a result
the function prototypes are as follows:

void prandom_seed(u32 seed);	/* rename from srandom32() */
u32 prandom_u32(void);		/* rename from random32() */
void prandom_bytes(void *buf, int nbytes);

void prandom_seed_state(struct rnd_state *state, u64 seed);
				/* rename from prandom32_seed() */
u32 prandom_u32_state(struct rnd_state *state);
				/* rename from prandom32() */
void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes);

The purpose of this renaming is to prevent some kernel developers
from assuming that prandom32() and random32() might imply that only
prandom32() was the one using a pseudo-random number generator by
prandom32's "p", and the result may be a very embarassing security
exposure.  This concern was expressed by Theodore Ts'o.

Changelog

* v3
- change common prefix from 'random32_' to 'prandom_'
- ensure prandom_bytes_state() generates same bytes with same rnd_state

* v2
- rename prandom32 to random32_state
- dropped lib/uuid.c patch
- add bnx2 and mtd_stresstest patches

Akinobu Mita (11):
  random32: rename random32 to prandom
  prandom: introduce prandom_bytes() and prandom_bytes_state()
  bnx2x: use prandom_bytes()
  mtd: nandsim: use prandom_bytes
  ubifs: use prandom_bytes
  mtd: mtd_nandecctest: use prandom_bytes instead of get_random_bytes()
  mtd: mtd_oobtest: convert to use prandom library
  mtd: mtd_pagetest: convert to use prandom library
  mtd: mtd_speedtest: use prandom_bytes
  mtd: mtd_subpagetest: convert to use prandom library
  mtd: mtd_stresstest: use prandom_bytes()

 drivers/mtd/nand/nandsim.c                      |  5 +-
 drivers/mtd/tests/mtd_nandecctest.c             |  2 +-
 drivers/mtd/tests/mtd_oobtest.c                 | 49 ++++---------
 drivers/mtd/tests/mtd_pagetest.c                | 43 ++++-------
 drivers/mtd/tests/mtd_speedtest.c               |  9 +--
 drivers/mtd/tests/mtd_stresstest.c              |  3 +-
 drivers/mtd/tests/mtd_subpagetest.c             | 42 +++--------
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |  5 +-
 drivers/scsi/fcoe/fcoe_ctlr.c                   |  4 +-
 fs/ubifs/debug.c                                |  8 +-
 include/linux/random.h                          | 19 +++--
 lib/interval_tree_test_main.c                   |  7 +-
 lib/random32.c                                  | 97 +++++++++++++++++++------
 lib/rbtree_test.c                               |  6 +-
 14 files changed, 145 insertions(+), 154 deletions(-)

Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Artem Bityutskiy <dedekind1@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: linux-mtd@lists.infradead.org
Cc: Eilon Greenstein <eilong@broadcom.com>
Cc: netdev@vger.kernel.org
Cc: Robert Love <robert.w.love@intel.com>
Cc: devel@open-fcoe.org
Cc: Michel Lespinasse <walken@google.com>
-- 
1.7.11.7

^ permalink raw reply

* Re: [PATCH] tcp: tcp_replace_ts_recent() should not be called from tcp_validate_incoming()
From: Eric Dumazet @ 2012-11-13 13:28 UTC (permalink / raw)
  To: Romain Francoise
  Cc: David Miller, netdev, Neal Cardwell, Yuchung Cheng,
	Nandita Dukkipati, H.K. Jerry Chu
In-Reply-To: <87k3tp6783.fsf@silenus.orebokech.com>

On Tue, 2012-11-13 at 13:02 +0100, Romain Francoise wrote:
> Eric Dumazet <eric.dumazet@gmail.com> writes:
> 
> > We added support for RFC 5962 in latest kernels but TCP fails
> > to perform exhaustive check of ACK sequence.
> 
> You probably meant 5961...

Oops you're right ;)

^ permalink raw reply

* [PATCH] net: cdc_ncm: add Huawei devices
From: Bjørn Mork @ 2012-11-13 13:19 UTC (permalink / raw)
  To: netdev
  Cc: linux-usb, Oliver Neukum, Alexey ORISHKO, Tommy Cheng, Olof Ermis,
	Bjørn Mork

A number of Huawei 3G and LTE modems implement a CDC NCM function,
including the necessary functional descriptors, but using a non
standard interface layout and class/subclass/protocol codes.

These devices can be handled by this driver with only a minor
change to the probing logic, allowing a single combined control
and data interface.  This works because the devices
- include a CDC Union descriptor labelling the combined
  interface as both master and slave, and
- have an alternate setting #1 for the bulk endpoints on the
  combined interface.

The 3G/LTE network connection is managed by vendor specific AT
commands on a serial function in the same composite device.
Handling the managment function is out of the scope of this
driver.  It will be handled by an appropriate USB serial
driver.

Reported-and-Tested-by: Olof Ermis <olof.ermis@gmail.com>
Reported-and-Tested-by: Tommy Cheng <tommy7765@yahoo.com>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
Hello David,

This patch had to touch more than just the device id table to
deal with the combined NCM interface on these devices.  The
changes will not affect any currently supported devices because
(ctx->data != ctx->control) always is true for those.

I am therefore requesting that this patch is put in the stable
queue like other device additons.

I guess it may be too late for v3.7, but FWIW I have verified
that the patch applies cleanly to both the current net-next/master
and to net/master, and will not cause merge conflicts either way.
I have also verified that it applies cleanly to the v3.6.6 stable
release.


Bjørn

 drivers/net/usb/cdc_ncm.c |   22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 4cd582a..74fab1a 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -540,10 +540,12 @@ advance:
 	    (ctx->ether_desc == NULL) || (ctx->control != intf))
 		goto error;
 
-	/* claim interfaces, if any */
-	temp = usb_driver_claim_interface(driver, ctx->data, dev);
-	if (temp)
-		goto error;
+	/* claim data interface, if different from control */
+	if (ctx->data != ctx->control) {
+		temp = usb_driver_claim_interface(driver, ctx->data, dev);
+		if (temp)
+			goto error;
+	}
 
 	iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
 
@@ -623,6 +625,10 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
 
 	tasklet_kill(&ctx->bh);
 
+	/* handle devices with combined control and data interface */
+	if (ctx->control == ctx->data)
+		ctx->data = NULL;
+
 	/* disconnect master --> disconnect slave */
 	if (intf == ctx->control && ctx->data) {
 		usb_set_intfdata(ctx->data, NULL);
@@ -1245,6 +1251,14 @@ static const struct usb_device_id cdc_devs[] = {
 	  .driver_info = (unsigned long) &wwan_info,
 	},
 
+	/* Huawei NCM devices disguised as vendor specific */
+	{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16),
+	  .driver_info = (unsigned long)&wwan_info,
+	},
+	{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46),
+	  .driver_info = (unsigned long)&wwan_info,
+	},
+
 	/* Generic CDC-NCM devices */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM,
 		USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
-- 
1.7.10.4

^ permalink raw reply related

* Re: [PATCH 0/3] netfilter updates for net-next
From: Pablo Neira Ayuso @ 2012-11-13 12:40 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1352765203-4160-1-git-send-email-pablo@netfilter.org>

On Tue, Nov 13, 2012 at 01:06:40AM +0100, pablo@netfilter.org wrote:
> From: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> Hi David,
> 
> The following three patches contain updates for your net-next tree,
> they include:
> 
> * Little cleanup for IPVS the use of a strange notation to assign the
>   conntrack object, from Alan Cox.
> 
> * getsockopt support to obtain the original IPv6 address after NAT,
>   similar to the one that IPv4 provides, from Florian Westphal.
> 
> * Another little cleanup for nf_nat to save a couple of lines by using
>   PTR_RET, from Wu Fengguang.

Please, hold on with this pull request. We need a follow-up patch to
resolve an issue regarding the getsockopt to obtain original address
with IPv6 NAT.

I'll send you a new pull request.

Sorry for the inconvenience.

^ permalink raw reply

* Re: [PATCH v5 3/9] net: xfrm: use __this_cpu_read per-cpu helper
From: Shan Wei @ 2012-11-13 12:36 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: Christoph Lameter, David Miller, NetDev, Herbert Xu,
	Kernel-Maillist
In-Reply-To: <20121113104839.GJ22290@secunet.com>

Steffen Klassert said, at 2012/11/13 18:48:
> 
> Ok, so please add a commit message to describe your changes.
> 
> Thanks.
> 

[PATCH v5] net: xfrm: use __this_cpu_read per-cpu helper

this_cpu_ptr/this_cpu_read is faster than per_cpu_ptr(p, smp_processor_id()) 
and can reduce  memory accesses.
The latter helper needs to find the offset for current cpu,
and needs more assembler instructions which objdump shows in following. 

this_cpu_ptr relocates and address. this_cpu_read() relocates the address
and performs the fetch. this_cpu_read() saves you more instructions
since it can do the relocation and the fetch in one instruction.

per_cpu_ptr(p, smp_processor_id()):
  1e:   65 8b 04 25 00 00 00 00         mov    %gs:0x0,%eax
  26:   48 98                           cltq
  28:   31 f6                           xor    %esi,%esi
  2a:   48 c7 c7 00 00 00 00            mov    $0x0,%rdi
  31:   48 8b 04 c5 00 00 00 00         mov    0x0(,%rax,8),%rax
  39:   c7 44 10 04 14 00 00 00         movl   $0x14,0x4(%rax,%rdx,1)

this_cpu_ptr(p)
  1e:   65 48 03 14 25 00 00 00 00      add    %gs:0x0,%rdx
  27:   31 f6                           xor    %esi,%esi
  29:   c7 42 04 14 00 00 00            movl   $0x14,0x4(%rdx)
  30:   48 c7 c7 00 00 00 00            mov    $0x0,%rdi

Signed-off-by: Shan Wei <davidshan@tencent.com>
---
 net/xfrm/xfrm_ipcomp.c |    8 +++-----
 1 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c
index e5246fb..2906d52 100644
--- a/net/xfrm/xfrm_ipcomp.c
+++ b/net/xfrm/xfrm_ipcomp.c
@@ -276,18 +276,16 @@ static struct crypto_comp * __percpu *ipcomp_alloc_tfms(const char *alg_name)
 	struct crypto_comp * __percpu *tfms;
 	int cpu;
 
-	/* This can be any valid CPU ID so we don't need locking. */
-	cpu = raw_smp_processor_id();
 
 	list_for_each_entry(pos, &ipcomp_tfms_list, list) {
 		struct crypto_comp *tfm;
 
-		tfms = pos->tfms;
-		tfm = *per_cpu_ptr(tfms, cpu);
+		/* This can be any valid CPU ID so we don't need locking. */
+		tfm = __this_cpu_read(*pos->tfms);
 
 		if (!strcmp(crypto_comp_name(tfm), alg_name)) {
 			pos->users++;
-			return tfms;
+			return pos->tfms;
 		}
 	}
 
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH] tcp: tcp_replace_ts_recent() should not be called from tcp_validate_incoming()
From: Romain Francoise @ 2012-11-13 12:02 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Miller, netdev, Neal Cardwell, Yuchung Cheng,
	Nandita Dukkipati, H.K. Jerry Chu
In-Reply-To: <1352793951.6185.28.camel@edumazet-glaptop>

Eric Dumazet <eric.dumazet@gmail.com> writes:

> We added support for RFC 5962 in latest kernels but TCP fails
> to perform exhaustive check of ACK sequence.

You probably meant 5961...

^ permalink raw reply

* Re: [PATCH v4] Network driver for the Armada 370 and Armada XP ARM Marvell SoCs
From: Thomas Petazzoni @ 2012-11-13 11:34 UTC (permalink / raw)
  To: Francois Romieu
  Cc: Eric Dumazet, David S. Miller, Lennert Buytenhek, netdev,
	linux-arm-kernel, Jason Cooper, Andrew Lunn, Gregory Clement,
	Lior Amsalem, Maen Suleiman
In-Reply-To: <20121103115321.GA4539@electric-eye.fr.zoreil.com>

François,

Thanks for your detailed review. I have a few comments/questions below
on specific topics.

On Sat, 3 Nov 2012 12:53:21 +0100, Francois Romieu wrote:
> > +	if (rxq->descs == NULL) {
> > +		netdev_err(pp->dev,
> > +			   "rxQ=%d: Can't allocate %d bytes for %d RX descr\n",
> > +			   rxq->id, rxq->size * MVNETA_DESC_ALIGNED_SIZE,
> > +			   rxq->size);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	BUG_ON(rxq->descs !=
> > +	       PTR_ALIGN(rxq->descs, MVNETA_CPU_D_CACHE_LINE_SIZE));
> 
> There is no reason to crash.

Well, there is a reason: the hardware will not work properly if
rxq->descs is not aligned on a MVNETA_CPU_D_CACHE_LINE_SIZE boundary.
So one solution is to over-allocated to guarantee the alignment, but
since practically speaking MVNETA_CPU_D_CACHE_LINE_SIZE=32 and
dma_alloc_coherent() returns things that seem at least 32 bytes
aligned, it sounded overkill to include more code to fix a problem that
doesn't exist. This BUG_ON() is here solely for the purpose of noisily
letting the user know if this implicit assumption on the alignment of
dma_alloc_coherent() allocated buffer changes in the future. I can turn
this into an error if you prefer:

	if (rxq->descs != PTR_ALIGN(rxq->descs, MVNETA_CPU_D_CACHE_LINE_SIZE)) {
		netdev_err(pp->dev, "improper buffer alignement assumption, driver needs fixing\n");
		dma_free_coherent(...);
		return -EINVAL;
	}

> (...]
> > +static int mvneta_txq_init(struct mvneta_port *pp,
> > +			   struct mvneta_tx_queue *txq)
> > +{
> > +	txq->size = pp->tx_ring_size;
> > +
> > +	/* Allocate memory for TX descriptors */
> > +	txq->descs = dma_alloc_coherent(pp->dev->dev.parent,
> > +					txq->size * MVNETA_DESC_ALIGNED_SIZE,
> > +					&txq->descs_phys,
> > +					DMA_BIDIRECTIONAL);
> 
> 					&txq->descs_phys, DMA_BIDIRECTIONAL);

Aaah, thanks for pointing this one! It should have been GFP_KERNEL, not
DMA_BIDIRECTIONAL here.

> > +	if (txq->descs == NULL) {
> > +		netdev_err(pp->dev,
> > +			   "txQ=%d: Can't allocate %d bytes for %d TX descr\n",
> > +			   txq->id, txq->size * MVNETA_DESC_ALIGNED_SIZE,
> > +			   txq->size);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	/* Make sure descriptor address is cache line size aligned  */
> > +	BUG_ON(txq->descs !=
> > +	       PTR_ALIGN(txq->descs, MVNETA_CPU_D_CACHE_LINE_SIZE));
> 
> There is no reason to crash.

Same as above :-)

> [...]
> > +static int mvneta_setup_rxqs(struct mvneta_port *pp)
> > +{
> > +	int queue;
> > +
> > +	for (queue = 0; queue < rxq_number; queue++) {
> > +		int err = mvneta_rxq_init(pp, &pp->rxqs[queue]);
> > +		if (err) {
> > +			netdev_err(pp->dev,
> > +				   "%s: can't create RxQ rxq=%d\n",
> 
> 			netdev_err(pp->dev, "%s: can't create RxQ rxq=%d\n",
> 
> > +				   __func__, queue);
> > +			mvneta_cleanup_rxqs(pp);
> > +			return -ENODEV;
> 
> mvneta_rxq_init should return a proper error code and it should be
> propagated (option: break instead of return and mvneta_setup_rxqs scoped
> err variable)

Besides turning the "return -ENODEV;" into "return err;", I don't see
what is the other problem here? mvneta_rxq_init() properly returns
-ENOMEM where there is a memory allocation failure, and
mvneta_cleanup_rxqs() properly cleans up *all* initialized rxqs. Is
there something I'm missing?

Thanks again for your review!

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* Re: [PATCH v4 3/9] net: xfrm: use __this_cpu_read per-cpu helper
From: Steffen Klassert @ 2012-11-13 10:48 UTC (permalink / raw)
  To: Shan Wei
  Cc: Christoph Lameter, David Miller, NetDev, Herbert Xu,
	Kernel-Maillist
In-Reply-To: <50A213DF.1040103@gmail.com>

On Tue, Nov 13, 2012 at 05:33:19PM +0800, Shan Wei wrote:
> Steffen Klassert said, at 2012/11/13 15:21:
> > 
> > This should just fetch the tfm pointer, so why exactly __this_cpu_read
> > is better than __this_cpu_ptr? Please keep in mind that performance is
> > not the most important thing here. It's much more important that it
> > works in any case.
>  
> [0/9] describes why we should submit this series patches.
> you are not included in original mail.
> 
> this_cpu_ptr relocates and address. this_cpu_read() relocates the address
> and performs the fetch. If you want to operate on rda(defined as per_cpu) 
> then you can only use this_cpu_ptr. this_cpu_read() saves you more instructions
> since it can do the relocation and the fetch in one instruction.
> 

Ok, so please add a commit message to describe your changes.

Thanks.

^ permalink raw reply

* Re: [REGRESSION, v3.7-rc5, bisected] 100% CPU usage in softirqd, unable to shutdown(Internet mail)
From: dannyfeng(冯小天) @ 2012-11-13 10:26 UTC (permalink / raw)
  To: Lekensteyn, David S. Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <5934660.4HuQirPM4Z@al>


________________________________________
发件人: Lekensteyn [lekensteyn@gmail.com]
发送时间: 2012年11月13日 5:20
收件人: dannyfeng(冯小天); David S. Miller
Cc: netdev@vger.kernel.org
主题: [REGRESSION, v3.7-rc5, bisected] 100% CPU usage in softirqd, unable to shutdown(Internet mail)

Hi,

After upgrading from 3.7-rc4 to 3.7-rc5 I found that I was unable to suspend
without locking up the system afterwards. Neither was I able to shutdown as it
would simply hang where it should halt. The second suspend/resume in a session
would make Networkmanager hang.

When looking in my process list, I saw that softirqd was using one full CPU
core. Watching the contents of /proc/softirqs showed that the tasklet number
would rapidly increase.

I got this message when trying to suspend for the second time in a session:

 Freezing user space processes ...
 Freezing of tasks failed after 20.01 seconds (1 tasks refusing to freeze,
wq_busy=0):
 NetworkManager  R  running task        0   332      1 0x00000004
  ffff88023169d628 ffffffff81549b86 ffff8802316e4470 ffff88023169dfd8
  ffff88023169dfd8 ffff88023169dfd8 ffff8802316e4470 ffff8802316e4470
  ffff88023169d698 ffff88023bc92a80 ffff88022fd3db70 ffff88022fd3dc90
 Call Trace:
  [<ffffffff81549b9e>] ? __schedule+0x13e/0x760
  [<ffffffff8154a4f9>] schedule+0x29/0x70
  [<ffffffff810722aa>] sys_sched_yield+0x4a/0x60
  [<ffffffff8154a7c2>] yield+0x32/0x40
  [<ffffffff810451f5>] tasklet_kill+0x35/0x80
  [<ffffffffa017c2f3>] jme_close+0xd3/0x850 [jme]
  [<ffffffff8146325d>] __dev_close_many+0x7d/0xc0
  [<ffffffff814632cd>] __dev_close+0x2d/0x40
  [<ffffffff81469551>] __dev_change_flags+0xa1/0x180
  [<ffffffff814696e8>] dev_change_flags+0x28/0x70
  [<ffffffff81475b68>] do_setlink+0x378/0xa00
  [<ffffffff81078a56>] ? find_busiest_group+0x36/0x490
  [<ffffffff812d5821>] ? nla_parse+0x31/0xe0
  [<ffffffff812d5821>] ? nla_parse+0x31/0xe0
  [<ffffffff81477e6e>] rtnl_newlink+0x36e/0x590
  [<ffffffff81286e16>] ? apparmor_capable+0x26/0x90
  [<ffffffff81477694>] rtnetlink_rcv_msg+0x114/0x300
  [<ffffffff8114d1c3>] ? __kmalloc_node_track_caller+0x63/0x1b0
  [<ffffffff8145b65b>] ? __alloc_skb+0x8b/0x290
  [<ffffffff81477580>] ? __rtnl_unlock+0x20/0x20
  [<ffffffff8148f471>] netlink_rcv_skb+0xb1/0xc0
  [<ffffffff814748f5>] rtnetlink_rcv+0x25/0x40
  [<ffffffff8148ed8b>] netlink_unicast+0x19b/0x220
  [<ffffffff8148f111>] netlink_sendmsg+0x301/0x3c0
  [<ffffffff8144f8ec>] sock_sendmsg+0xbc/0xf0
  [<ffffffff81450797>] ? sock_recvmsg+0xd7/0x110
  [<ffffffff8145045c>] __sys_sendmsg+0x3ac/0x3c0
  [<ffffffff810854dc>] ? ktime_get_ts+0x4c/0xf0
  [<ffffffff81452699>] sys_sendmsg+0x49/0x90
  [<ffffffff81553906>] system_call_fastpath+0x1a/0x1f

Bisecting leads to:
commit 175c0dffef310fc7d7f026ca4a7682beb2fbd8ec
Author: Xiaotian Feng <xtfeng@gmail.com>
Date:   Wed Oct 31 00:29:57 2012 +0000

    drivers/net: use tasklet_kill in device remove/close process

    Some driver uses tasklet_disable in device remove/close process,
    tasklet_disable will inc tasklet->count and return. If the tasklet
    is not handled yet because some softirq pressure, the tasklet will
    placed on the tasklet_vec, never have a chance to excute. This might
    lead to ksoftirqd heavy loaded, wakeup with pending_softirq, but
    tasklet is disabled. tasklet_kill should be used in this case.

    Signed-off-by: Xiaotian Feng <dannyfeng@tencent.com>
    Cc: "David S. Miller" <davem@davemloft.net>
    Cc: netdev@vger.kernel.org
    Signed-off-by: David S. Miller <davem@davemloft.net>
(if it wasn't obvious, I have an Ethernet device that needs the "jme" driver,
04:00.5 Ethernet controller [0200]: JMicron Technology Corp. JMC250 PCI
Express Gigabit Ethernet Controller [197b:0250] (rev 03))

Since 3.7, I sometimes get the below messages during suspend, but it would
never hang:
smpboot: CPU 2 is now offline
NOHZ: local_softirq_pending 02
NOHZ: local_softirq_pending 202
NOHZ: local_softirq_pending 202
NOHZ: local_softirq_pending 02
NOHZ: local_softirq_pending 202
NOHZ: local_softirq_pending 202
smpboot: CPU 3 is now offline

Time for a revert or do you have an other proposed fix?

I'm sorry, I didn't noticed that jme_open use tasklet_enable, which may reuse a killed tasklet...
Could you please try following patch?
---
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 92317e9..c0314c1 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -1860,10 +1860,14 @@ jme_open(struct net_device *netdev)
        jme_clear_pm(jme);
        JME_NAPI_ENABLE(jme);
 
-       tasklet_enable(&jme->linkch_task);
-       tasklet_enable(&jme->txclean_task);
-       tasklet_hi_enable(&jme->rxclean_task);
-       tasklet_hi_enable(&jme->rxempty_task);
+       tasklet_init(&jme->linkch_task, jme_link_change_tasklet,
+                     (unsigned long) jme);
+       tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet,
+                     (unsigned long) jme);
+       tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet,
+                     (unsigned long) jme);
+       tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet,
+                     (unsigned long) jme);
 
        rc = jme_request_irq(jme);
        if (rc)
@@ -3079,22 +3083,6 @@ jme_init_one(struct pci_dev *pdev,
        tasklet_init(&jme->pcc_task,
                     jme_pcc_tasklet,
                     (unsigned long) jme);
-       tasklet_init(&jme->linkch_task,
-                    jme_link_change_tasklet,
-                    (unsigned long) jme);
-       tasklet_init(&jme->txclean_task,
-                    jme_tx_clean_tasklet,
-                    (unsigned long) jme);
-       tasklet_init(&jme->rxclean_task,
-                    jme_rx_clean_tasklet,
-                    (unsigned long) jme);
-       tasklet_init(&jme->rxempty_task,
-                    jme_rx_empty_tasklet,
-                    (unsigned long) jme);
-       tasklet_disable_nosync(&jme->linkch_task);
-       tasklet_disable_nosync(&jme->txclean_task);
-       tasklet_disable_nosync(&jme->rxclean_task);
-       tasklet_disable_nosync(&jme->rxempty_task);
        jme->dpi.cur = PCC_P1;
 
        jme->reg_ghc = 0;


Regards,
Peter


^ permalink raw reply related

* Re: [PATCH v4 9/9] net: batman-adv: use per_cpu_add helper
From: Shan Wei @ 2012-11-13 10:25 UTC (permalink / raw)
  To: Marek Lindner
  Cc: NetDev, b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r,
	Kernel-Maillist, siwu-MaAgPAbsBIVS8oHt8HbXEIQuADTiUCJX,
	Christoph Lameter, David Miller
In-Reply-To: <201211131755.13299.lindner_marek-LWAfsSFWpa4@public.gmane.org>

Marek Lindner said, at 2012/11/13 17:55:
>>  net/batman-adv/main.h |    4 +---
>>  1 files changed, 1 insertions(+), 3 deletions(-)
> 
> Applied in our tree (revision f8b19e1). We will pass along this patch through 
> our standard workflow. No need to resend this patch in the future.

OK thanks~

> 
> Thanks,
> Marek
> 

^ permalink raw reply

* Re: [PATCH v4 9/9] net: batman-adv: use per_cpu_add helper
From: Marek Lindner @ 2012-11-13  9:55 UTC (permalink / raw)
  To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
  Cc: NetDev, Kernel-Maillist, siwu-MaAgPAbsBIVS8oHt8HbXEIQuADTiUCJX,
	Shan Wei, Christoph Lameter, David Miller
In-Reply-To: <50A1A816.3070900-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Tuesday, November 13, 2012 09:53:26 Shan Wei wrote:
> From: Shan Wei <davidshan-1Nz4purKYjRBDgjK7y7TUQ@public.gmane.org>
> 
> this_cpu_add is an atomic operation.
> and be more faster than per_cpu_ptr operation.
> 
> Signed-off-by: Shan Wei <davidshan-1Nz4purKYjRBDgjK7y7TUQ@public.gmane.org>
> Reviewed-by: Christoph Lameter <cl-vYTEC60ixJUAvxtiuMwx3w@public.gmane.org>
> ---
> v4: no changes vs v3.
> ---
>  net/batman-adv/main.h |    4 +---
>  1 files changed, 1 insertions(+), 3 deletions(-)

Applied in our tree (revision f8b19e1). We will pass along this patch through 
our standard workflow. No need to resend this patch in the future.

Thanks,
Marek

^ permalink raw reply

* Re: [PATCH 3/3] netfilter: ipv6: add getsockopt to retrieve origdst
From: Pablo Neira Ayuso @ 2012-11-13  9:39 UTC (permalink / raw)
  To: Florian Westphal; +Cc: YOSHIFUJI Hideaki, netfilter-devel, davem, netdev
In-Reply-To: <20121113085930.GE20678@breakpoint.cc>

On Tue, Nov 13, 2012 at 09:59:30AM +0100, Florian Westphal wrote:
> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> wrote:
> > pablo@netfilter.org wrote:
> > > From: Florian Westphal <fw@strlen.de>
> > > +	sin6.sin6_scope_id = sk->sk_bound_dev_if;
> > > +
> > > +	nf_ct_put(ct);
> > > +	return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0;
> > > +}
> > > +
> > 
> > I think we should set sin6_scope_id to sk->sk_bound_dev_if only if the
> > destination is link-local address.
> 
> Right, I see that getpeer/sockname has this test.
> 
> Dave, please either apply the patch as is (I'd submit a fixup)
> or discard i, I'll then send a V2 with added
> ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL
> test to Pablo.

Please, send me a follow-up patch, I'll apply and request a new pull
request.

Thanks.

^ permalink raw reply

* Re: [PATCH v4 3/9] net: xfrm: use __this_cpu_read per-cpu helper
From: Shan Wei @ 2012-11-13  9:33 UTC (permalink / raw)
  To: Steffen Klassert, Christoph Lameter
  Cc: David Miller, NetDev, Herbert Xu, Kernel-Maillist
In-Reply-To: <20121113072101.GG22290@secunet.com>

Steffen Klassert said, at 2012/11/13 15:21:
> 
> This should just fetch the tfm pointer, so why exactly __this_cpu_read
> is better than __this_cpu_ptr? Please keep in mind that performance is
> not the most important thing here. It's much more important that it
> works in any case.
 
[0/9] describes why we should submit this series patches.
you are not included in original mail.

this_cpu_ptr relocates and address. this_cpu_read() relocates the address
and performs the fetch. If you want to operate on rda(defined as per_cpu) 
then you can only use this_cpu_ptr. this_cpu_read() saves you more instructions
since it can do the relocation and the fetch in one instruction.

More info, please refer to http://www.spinics.net/lists/kernel/msg1435153.html

^ permalink raw reply

* [PATCH 11/11] batman-adv: Remove instant overwritten variable initialization
From: Antonio Quartulli @ 2012-11-13  9:15 UTC (permalink / raw)
  To: davem; +Cc: netdev, b.a.t.m.a.n, Sven Eckelmann, Marek Lindner,
	Antonio Quartulli
In-Reply-To: <1352798139-19458-1-git-send-email-ordex@autistici.org>

From: Sven Eckelmann <sven@narfation.org>

Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
 net/batman-adv/sysfs.c             |  2 +-
 net/batman-adv/translation-table.c | 20 ++++++++++----------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index fa3cc1a..84a55cb 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -688,7 +688,7 @@ int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
 			enum batadv_uev_action action, const char *data)
 {
 	int ret = -ENOMEM;
-	struct batadv_hard_iface *primary_if = NULL;
+	struct batadv_hard_iface *primary_if;
 	struct kobject *bat_kobj;
 	char *uevent_env[4] = { NULL, NULL, NULL, NULL };
 
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index dd2c254..9f5705f 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -256,8 +256,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 			 int ifindex)
 {
 	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
-	struct batadv_tt_local_entry *tt_local = NULL;
-	struct batadv_tt_global_entry *tt_global = NULL;
+	struct batadv_tt_local_entry *tt_local;
+	struct batadv_tt_global_entry *tt_global;
 	struct hlist_head *head;
 	struct hlist_node *node;
 	struct batadv_tt_orig_list_entry *orig_entry;
@@ -544,7 +544,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
 				const uint8_t *addr, const char *message,
 				bool roaming)
 {
-	struct batadv_tt_local_entry *tt_local_entry = NULL;
+	struct batadv_tt_local_entry *tt_local_entry;
 	uint16_t flags, curr_flags = BATADV_NO_FLAGS;
 
 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
@@ -784,8 +784,8 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
 			 const unsigned char *tt_addr, uint8_t flags,
 			 uint8_t ttvn)
 {
-	struct batadv_tt_global_entry *tt_global_entry = NULL;
-	struct batadv_tt_local_entry *tt_local_entry = NULL;
+	struct batadv_tt_global_entry *tt_global_entry;
+	struct batadv_tt_local_entry *tt_local_entry;
 	int ret = 0;
 	int hash_added;
 	struct batadv_tt_common_entry *common;
@@ -1067,7 +1067,7 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
 				 const unsigned char *addr,
 				 const char *message, bool roaming)
 {
-	struct batadv_tt_global_entry *tt_global_entry = NULL;
+	struct batadv_tt_global_entry *tt_global_entry;
 	struct batadv_tt_local_entry *local_entry = NULL;
 
 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
@@ -1670,7 +1670,7 @@ static bool
 batadv_send_other_tt_response(struct batadv_priv *bat_priv,
 			      struct batadv_tt_query_packet *tt_request)
 {
-	struct batadv_orig_node *req_dst_orig_node = NULL;
+	struct batadv_orig_node *req_dst_orig_node;
 	struct batadv_orig_node *res_dst_orig_node = NULL;
 	struct batadv_neigh_node *neigh_node = NULL;
 	struct batadv_hard_iface *primary_if = NULL;
@@ -1805,7 +1805,7 @@ static bool
 batadv_send_my_tt_response(struct batadv_priv *bat_priv,
 			   struct batadv_tt_query_packet *tt_request)
 {
-	struct batadv_orig_node *orig_node = NULL;
+	struct batadv_orig_node *orig_node;
 	struct batadv_neigh_node *neigh_node = NULL;
 	struct batadv_hard_iface *primary_if = NULL;
 	uint8_t my_ttvn, req_ttvn, ttvn;
@@ -1971,7 +1971,7 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
 static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
 				  struct batadv_tt_query_packet *tt_response)
 {
-	struct batadv_orig_node *orig_node = NULL;
+	struct batadv_orig_node *orig_node;
 
 	orig_node = batadv_orig_hash_find(bat_priv, tt_response->src);
 	if (!orig_node)
@@ -2013,7 +2013,7 @@ static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
 
 bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr)
 {
-	struct batadv_tt_local_entry *tt_local_entry = NULL;
+	struct batadv_tt_local_entry *tt_local_entry;
 	bool ret = false;
 
 	tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
-- 
1.8.0

^ permalink raw reply related

* [PATCH 10/11] batman-adv: roaming handling mechanism redesign
From: Antonio Quartulli @ 2012-11-13  9:15 UTC (permalink / raw)
  To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli
In-Reply-To: <1352798139-19458-1-git-send-email-ordex@autistici.org>

This patch allows clients to roam multiple times within the same
originator-interval.

To enable this new feature two key aspects that have been introduced:
1) packets are always directed to the node that was originally
serving the roamed client which will then re-route the data
to the correct destination at any point in time;
2) the client flags handling mechanism has been properly modified
in order to allow multiple roamings withinin the same orig-int.
Therefore flags are now set properly even in this scenario.

Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
 net/batman-adv/translation-table.c | 157 ++++++++++++++++++++++++++++---------
 1 file changed, 118 insertions(+), 39 deletions(-)

diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index cb8433a..dd2c254 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -238,6 +238,20 @@ static int batadv_tt_local_init(struct batadv_priv *bat_priv)
 	return 0;
 }
 
+static void batadv_tt_global_free(struct batadv_priv *bat_priv,
+				  struct batadv_tt_global_entry *tt_global,
+				  const char *message)
+{
+	batadv_dbg(BATADV_DBG_TT, bat_priv,
+		   "Deleting global tt entry %pM: %s\n",
+		   tt_global->common.addr, message);
+
+	batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
+			   batadv_choose_orig, tt_global->common.addr);
+	batadv_tt_global_entry_free_ref(tt_global);
+
+}
+
 void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 			 int ifindex)
 {
@@ -248,14 +262,38 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 	struct hlist_node *node;
 	struct batadv_tt_orig_list_entry *orig_entry;
 	int hash_added;
+	bool roamed_back = false;
 
 	tt_local = batadv_tt_local_hash_find(bat_priv, addr);
+	tt_global = batadv_tt_global_hash_find(bat_priv, addr);
 
 	if (tt_local) {
 		tt_local->last_seen = jiffies;
-		/* possibly unset the BATADV_TT_CLIENT_PENDING flag */
-		tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
-		goto out;
+		if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
+			batadv_dbg(BATADV_DBG_TT, bat_priv,
+				   "Re-adding pending client %pM\n", addr);
+			/* whatever the reason why the PENDING flag was set,
+			 * this is a client which was enqueued to be removed in
+			 * this orig_interval. Since it popped up again, the
+			 * flag can be reset like it was never enqueued
+			 */
+			tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
+			goto add_event;
+		}
+
+		if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
+			batadv_dbg(BATADV_DBG_TT, bat_priv,
+				   "Roaming client %pM came back to its original location\n",
+				   addr);
+			/* the ROAM flag is set because this client roamed away
+			 * and the node got a roaming_advertisement message. Now
+			 * that the client popped up again at its original
+			 * location such flag can be unset
+			 */
+			tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM;
+			roamed_back = true;
+		}
+		goto check_roaming;
 	}
 
 	tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
@@ -294,13 +332,14 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 		goto out;
 	}
 
+add_event:
 	batadv_tt_local_event(bat_priv, addr, tt_local->common.flags);
 
-	/* remove address from global hash if present */
-	tt_global = batadv_tt_global_hash_find(bat_priv, addr);
-
-	/* Check whether it is a roaming! */
-	if (tt_global) {
+check_roaming:
+	/* Check whether it is a roaming, but don't do anything if the roaming
+	 * process has already been handled
+	 */
+	if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) {
 		/* These node are probably going to update their tt table */
 		head = &tt_global->orig_list;
 		rcu_read_lock();
@@ -309,12 +348,19 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
 					     orig_entry->orig_node);
 		}
 		rcu_read_unlock();
-		/* The global entry has to be marked as ROAMING and
-		 * has to be kept for consistency purpose
-		 */
-		tt_global->common.flags |= BATADV_TT_CLIENT_ROAM;
-		tt_global->roam_at = jiffies;
+		if (roamed_back) {
+			batadv_tt_global_free(bat_priv, tt_global,
+					      "Roaming canceled");
+			tt_global = NULL;
+		} else {
+			/* The global entry has to be marked as ROAMING and
+			 * has to be kept for consistency purpose
+			 */
+			tt_global->common.flags |= BATADV_TT_CLIENT_ROAM;
+			tt_global->roam_at = jiffies;
+		}
 	}
+
 out:
 	if (tt_local)
 		batadv_tt_local_entry_free_ref(tt_local);
@@ -508,13 +554,28 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
 	curr_flags = tt_local_entry->common.flags;
 
 	flags = BATADV_TT_CLIENT_DEL;
+	/* if this global entry addition is due to a roaming, the node has to
+	 * mark the local entry as "roamed" in order to correctly reroute
+	 * packets later
+	 */
 	if (roaming) {
 		flags |= BATADV_TT_CLIENT_ROAM;
 		/* mark the local client as ROAMed */
 		tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
 	}
 
-	batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message);
+	if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) {
+		batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags,
+					    message);
+		goto out;
+	}
+	/* if this client has been added right now, it is possible to
+	 * immediately purge it
+	 */
+	batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
+			      curr_flags | BATADV_TT_CLIENT_DEL);
+	hlist_del_rcu(&tt_local_entry->common.hash_entry);
+	batadv_tt_local_entry_free_ref(tt_local_entry);
 
 out:
 	if (tt_local_entry)
@@ -724,12 +785,22 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
 			 uint8_t ttvn)
 {
 	struct batadv_tt_global_entry *tt_global_entry = NULL;
+	struct batadv_tt_local_entry *tt_local_entry = NULL;
 	int ret = 0;
 	int hash_added;
 	struct batadv_tt_common_entry *common;
 	uint16_t local_flags;
 
 	tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
+	tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr);
+
+	/* if the node already has a local client for this entry, it has to wait
+	 * for a roaming advertisement instead of manually messing up the global
+	 * table
+	 */
+	if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry &&
+	    !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW))
+		goto out;
 
 	if (!tt_global_entry) {
 		tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC);
@@ -764,19 +835,31 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
 			goto out_remove;
 		}
 	} else {
+		common = &tt_global_entry->common;
 		/* If there is already a global entry, we can use this one for
 		 * our processing.
-		 * But if we are trying to add a temporary client we can exit
-		 * directly because the temporary information should never
-		 * override any already known client state (whatever it is)
+		 * But if we are trying to add a temporary client then here are
+		 * two options at this point:
+		 * 1) the global client is not a temporary client: the global
+		 *    client has to be left as it is, temporary information
+		 *    should never override any already known client state
+		 * 2) the global client is a temporary client: purge the
+		 *    originator list and add the new one orig_entry
 		 */
-		if (flags & BATADV_TT_CLIENT_TEMP)
-			goto out;
+		if (flags & BATADV_TT_CLIENT_TEMP) {
+			if (!(common->flags & BATADV_TT_CLIENT_TEMP))
+				goto out;
+			if (batadv_tt_global_entry_has_orig(tt_global_entry,
+							    orig_node))
+				goto out_remove;
+			batadv_tt_global_del_orig_list(tt_global_entry);
+			goto add_orig_entry;
+		}
 
 		/* if the client was temporary added before receiving the first
 		 * OGM announcing it, we have to clear the TEMP flag
 		 */
-		tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP;
+		common->flags &= ~BATADV_TT_CLIENT_TEMP;
 
 		/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
 		 * one originator left in the list and we previously received a
@@ -785,18 +868,19 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
 		 * We should first delete the old originator before adding the
 		 * new one.
 		 */
-		if (tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM) {
+		if (common->flags & BATADV_TT_CLIENT_ROAM) {
 			batadv_tt_global_del_orig_list(tt_global_entry);
-			tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
+			common->flags &= ~BATADV_TT_CLIENT_ROAM;
 			tt_global_entry->roam_at = 0;
 		}
 	}
+add_orig_entry:
 	/* add the new orig_entry (if needed) or update it */
 	batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
 
 	batadv_dbg(BATADV_DBG_TT, bat_priv,
 		   "Creating new global tt entry: %pM (via %pM)\n",
-		   tt_global_entry->common.addr, orig_node->orig);
+		   common->addr, orig_node->orig);
 	ret = 1;
 
 out_remove:
@@ -804,12 +888,20 @@ out_remove:
 	/* remove address from local hash if present */
 	local_flags = batadv_tt_local_remove(bat_priv, tt_addr,
 					     "global tt received",
-					     flags & BATADV_TT_CLIENT_ROAM);
+					     !!(flags & BATADV_TT_CLIENT_ROAM));
 	tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
 
+	if (!(flags & BATADV_TT_CLIENT_ROAM))
+		/* this is a normal global add. Therefore the client is not in a
+		 * roaming state anymore.
+		 */
+		tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
+
 out:
 	if (tt_global_entry)
 		batadv_tt_global_entry_free_ref(tt_global_entry);
+	if (tt_local_entry)
+		batadv_tt_local_entry_free_ref(tt_local_entry);
 	return ret;
 }
 
@@ -927,20 +1019,6 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
 	spin_unlock_bh(&tt_global_entry->list_lock);
 }
 
-static void batadv_tt_global_free(struct batadv_priv *bat_priv,
-				  struct batadv_tt_global_entry *tt_global,
-				  const char *message)
-{
-	batadv_dbg(BATADV_DBG_TT, bat_priv,
-		   "Deleting global tt entry %pM: %s\n",
-		   tt_global->common.addr, message);
-
-	batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
-			   batadv_choose_orig, tt_global->common.addr);
-	batadv_tt_global_entry_free_ref(tt_global);
-
-}
-
 /* If the client is to be deleted, we check if it is the last origantor entry
  * within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the
  * timer, otherwise we simply remove the originator scheduled for deletion.
@@ -1204,7 +1282,8 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
 
 	if (src && atomic_read(&bat_priv->ap_isolation)) {
 		tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
-		if (!tt_local_entry)
+		if (!tt_local_entry ||
+		    (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
 			goto out;
 	}
 
-- 
1.8.0

^ permalink raw reply related

* [PATCH 09/11] batman-adv: refactor tt_global_del_struct()
From: Antonio Quartulli @ 2012-11-13  9:15 UTC (permalink / raw)
  To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli
In-Reply-To: <1352798139-19458-1-git-send-email-ordex@autistici.org>

batadv_tt_global_del_struct() function is not properly named.
Having a more meaningful name which reflects the current behavior helps other
developers to easily understand what it does.

A parameter has also been renamed in order to let the function header better fit
the 80-chars line-width

Signed-off-by: Antonio Quartulli <ordex@autistici.org>
---
 net/batman-adv/translation-table.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index c24e604..cb8433a 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -927,18 +927,17 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
 	spin_unlock_bh(&tt_global_entry->list_lock);
 }
 
-static void
-batadv_tt_global_del_struct(struct batadv_priv *bat_priv,
-			    struct batadv_tt_global_entry *tt_global_entry,
-			    const char *message)
+static void batadv_tt_global_free(struct batadv_priv *bat_priv,
+				  struct batadv_tt_global_entry *tt_global,
+				  const char *message)
 {
 	batadv_dbg(BATADV_DBG_TT, bat_priv,
 		   "Deleting global tt entry %pM: %s\n",
-		   tt_global_entry->common.addr, message);
+		   tt_global->common.addr, message);
 
 	batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
-			   batadv_choose_orig, tt_global_entry->common.addr);
-	batadv_tt_global_entry_free_ref(tt_global_entry);
+			   batadv_choose_orig, tt_global->common.addr);
+	batadv_tt_global_entry_free_ref(tt_global);
 
 }
 
@@ -1002,8 +1001,8 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
 						orig_node, message);
 
 		if (hlist_empty(&tt_global_entry->orig_list))
-			batadv_tt_global_del_struct(bat_priv, tt_global_entry,
-						    message);
+			batadv_tt_global_free(bat_priv, tt_global_entry,
+					      message);
 
 		goto out;
 	}
@@ -1026,7 +1025,7 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
 	if (local_entry) {
 		/* local entry exists, case 2: client roamed to us. */
 		batadv_tt_global_del_orig_list(tt_global_entry);
-		batadv_tt_global_del_struct(bat_priv, tt_global_entry, message);
+		batadv_tt_global_free(bat_priv, tt_global_entry, message);
 	} else
 		/* no local entry exists, case 1: check for roaming */
 		batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
-- 
1.8.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox