* [PATCH v5 10/10] ARM: dts: berlin: enable the Ethernet port on the BG2Q DMP
From: Antoine Tenart @ 2014-09-26 14:33 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: thomas.petazzoni, zmxu, devicetree, netdev, Antoine Tenart,
linux-kernel, alexandre.belloni, jszhang, linux-arm-kernel
In-Reply-To: <1411742036-23520-1-git-send-email-antoine.tenart@free-electrons.com>
This patch enables the Ethernet port on the Marvell Berlin2Q DMP board.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/boot/dts/berlin2q-marvell-dmp.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
index a357ce02a64e..ea1f99b8eed6 100644
--- a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
+++ b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
@@ -45,3 +45,7 @@
&uart0 {
status = "okay";
};
+
+ð0 {
+ status = "okay";
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v5 09/10] ARM: dts: berlin: add the Ethernet node
From: Antoine Tenart @ 2014-09-26 14:33 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: Antoine Tenart, alexandre.belloni, thomas.petazzoni, zmxu,
jszhang, netdev, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <1411742036-23520-1-git-send-email-antoine.tenart@free-electrons.com>
This patch adds the Ethernet node, enabling the network unit on Berlin
BG2Q SoCs.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/boot/dts/berlin2q.dtsi | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 902eddb19cd8..d442b22fd1ea 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -114,6 +114,23 @@
#interrupt-cells = <3>;
};
+ eth0: ethernet@b90000 {
+ compatible = "marvell,pxa168-eth";
+ reg = <0xb90000 0x10000>;
+ clocks = <&chip CLKID_GETH0>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ /* set by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy-handle = <ðphy0>;
+ status = "disabled";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
cpu-ctrl@dd0000 {
compatible = "marvell,berlin-cpu-ctrl";
reg = <0xdd0000 0x10000>;
--
1.9.1
^ permalink raw reply related
* [PATCH v5 08/10] net: pxa168_eth: allow to compile the pxa168_eth driver for tests
From: Antoine Tenart @ 2014-09-26 14:33 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: thomas.petazzoni, zmxu, devicetree, netdev, Antoine Tenart,
linux-kernel, alexandre.belloni, jszhang, linux-arm-kernel
In-Reply-To: <1411742036-23520-1-git-send-email-antoine.tenart@free-electrons.com>
Add a dependency to COMPILE_TEST so that the driver can be compiled for
test purposes.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/ethernet/marvell/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index 48b9466d1781..bed8fbb3edc5 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -64,7 +64,7 @@ config MVPP2
config PXA168_ETH
tristate "Marvell pxa168 ethernet support"
- depends on CPU_PXA168 || ARCH_BERLIN
+ depends on CPU_PXA168 || ARCH_BERLIN || COMPILE_TEST
select PHYLIB
---help---
This driver supports the pxa168 Ethernet ports.
--
1.9.1
^ permalink raw reply related
* [PATCH v5 07/10] net: pxa168_eth: allow Berlin SoCs to use the pxa168_eth driver
From: Antoine Tenart @ 2014-09-26 14:33 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: thomas.petazzoni, zmxu, devicetree, netdev, Antoine Tenart,
linux-kernel, alexandre.belloni, jszhang, linux-arm-kernel
In-Reply-To: <1411742036-23520-1-git-send-email-antoine.tenart@free-electrons.com>
Berlin SoCs have an Ethernet controller compatible with the pxa168.
Allow these SoCs to use the pxa168_eth driver.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/ethernet/marvell/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index 1b4fc7c639e6..48b9466d1781 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -64,7 +64,7 @@ config MVPP2
config PXA168_ETH
tristate "Marvell pxa168 ethernet support"
- depends on CPU_PXA168
+ depends on CPU_PXA168 || ARCH_BERLIN
select PHYLIB
---help---
This driver supports the pxa168 Ethernet ports.
--
1.9.1
^ permalink raw reply related
* [PATCH v5 05/10] net: pxa168_eth: set the mac address on the Ethernet controller
From: Antoine Tenart @ 2014-09-26 14:33 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: Antoine Tenart, alexandre.belloni, thomas.petazzoni, zmxu,
jszhang, netdev, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <1411742036-23520-1-git-send-email-antoine.tenart@free-electrons.com>
When changing the MAC address, in addition to updating the dev_addr in
the net_device structure, this patch also update the MAC address
registers (high and low) of the Ethernet controller with the new MAC.
The address stored in these registers is used for IEEE 802.3x Ethernet
flow control, which is already enabled.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/ethernet/marvell/pxa168_eth.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index b9073e2f3623..34f17dde1cb0 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -60,6 +60,8 @@
#define PORT_COMMAND 0x0410
#define PORT_STATUS 0x0418
#define HTPR 0x0428
+#define MAC_ADDR_LOW 0x0430
+#define MAC_ADDR_HIGH 0x0438
#define SDMA_CONFIG 0x0440
#define SDMA_CMD 0x0448
#define INT_CAUSE 0x0450
@@ -609,11 +611,22 @@ static int pxa168_eth_set_mac_address(struct net_device *dev, void *addr)
struct sockaddr *sa = addr;
struct pxa168_eth_private *pep = netdev_priv(dev);
unsigned char oldMac[ETH_ALEN];
+ u32 mac_h, mac_l;
if (!is_valid_ether_addr(sa->sa_data))
return -EADDRNOTAVAIL;
memcpy(oldMac, dev->dev_addr, ETH_ALEN);
memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
+
+ mac_h = sa->sa_data[0] << 24;
+ mac_h |= sa->sa_data[1] << 16;
+ mac_h |= sa->sa_data[2] << 8;
+ mac_h |= sa->sa_data[3];
+ mac_l = sa->sa_data[4] << 8;
+ mac_l |= sa->sa_data[5];
+ wrl(pep, MAC_ADDR_HIGH, mac_h);
+ wrl(pep, MAC_ADDR_LOW, mac_l);
+
netif_addr_lock_bh(dev);
update_hash_table_mac_address(pep, oldMac, dev->dev_addr);
netif_addr_unlock_bh(dev);
--
1.9.1
^ permalink raw reply related
* [PATCH v5 04/10] net: pxa168_eth: fix Ethernet flow control status
From: Antoine Tenart @ 2014-09-26 14:33 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: thomas.petazzoni, zmxu, devicetree, netdev, Antoine Tenart,
linux-kernel, alexandre.belloni, jszhang, linux-arm-kernel
In-Reply-To: <1411742036-23520-1-git-send-email-antoine.tenart@free-electrons.com>
IEEE 802.3x Ethernet flow control is disabled when bit (1 << 2) is set
in the port status register. Fix the flow control detection in the link
event handling function which was relying on the opposite assumption.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/ethernet/marvell/pxa168_eth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index 978f26198dd6..b9073e2f3623 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -163,7 +163,7 @@
/* Bit definitions for Port status */
#define PORT_SPEED_100 (1 << 0)
#define FULL_DUPLEX (1 << 1)
-#define FLOW_CONTROL_ENABLED (1 << 2)
+#define FLOW_CONTROL_DISABLED (1 << 2)
#define LINK_UP (1 << 3)
/* Bit definitions for work to be done */
@@ -885,7 +885,7 @@ static void handle_link_event(struct pxa168_eth_private *pep)
speed = 10;
duplex = (port_status & FULL_DUPLEX) ? 1 : 0;
- fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0;
+ fc = (port_status & FLOW_CONTROL_DISABLED) ? 0 : 1;
netdev_info(dev, "link up, %d Mb/s, %s duplex, flow control %sabled\n",
speed, duplex ? "full" : "half", fc ? "en" : "dis");
if (!netif_carrier_ok(dev))
--
1.9.1
^ permalink raw reply related
* [PATCH v5 03/10] Documentation: bindings: net: add the Marvell PXA168 Ethernet controller
From: Antoine Tenart @ 2014-09-26 14:33 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: thomas.petazzoni, zmxu, devicetree, netdev, Antoine Tenart,
linux-kernel, alexandre.belloni, jszhang, linux-arm-kernel
In-Reply-To: <1411742036-23520-1-git-send-email-antoine.tenart@free-electrons.com>
This adds the binding documentation for the Marvell PXA168 Ethernet
controller, following its DT support.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
.../devicetree/bindings/net/marvell-pxa168.txt | 36 ++++++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/marvell-pxa168.txt
diff --git a/Documentation/devicetree/bindings/net/marvell-pxa168.txt b/Documentation/devicetree/bindings/net/marvell-pxa168.txt
new file mode 100644
index 000000000000..845a148a346e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/marvell-pxa168.txt
@@ -0,0 +1,36 @@
+* Marvell PXA168 Ethernet Controller
+
+Required properties:
+- compatible: should be "marvell,pxa168-eth".
+- reg: address and length of the register set for the device.
+- interrupts: interrupt for the device.
+- clocks: pointer to the clock for the device.
+
+Optional properties:
+- port-id: Ethernet port number. Should be '0','1' or '2'.
+- #address-cells: must be 1 when using sub-nodes.
+- #size-cells: must be 0 when using sub-nodes.
+- phy-handle: see ethernet.txt file in the same directory.
+- local-mac-address: see ethernet.txt file in the same directory.
+
+Sub-nodes:
+Each PHY can be represented as a sub-node. This is not mandatory.
+
+Sub-nodes required properties:
+- reg: the MDIO address of the PHY.
+
+Example:
+
+ eth0: ethernet@f7b90000 {
+ compatible = "marvell,pxa168-eth";
+ reg = <0xf7b90000 0x10000>;
+ clocks = <&chip CLKID_GETH0>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy-handle = <ðphy0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v5 02/10] net: pxa168_eth: add device tree support
From: Antoine Tenart @ 2014-09-26 14:33 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: thomas.petazzoni, zmxu, devicetree, netdev, Antoine Tenart,
linux-kernel, alexandre.belloni, jszhang, linux-arm-kernel
In-Reply-To: <1411742036-23520-1-git-send-email-antoine.tenart@free-electrons.com>
Add the device tree support to the pxa168_eth driver.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/ethernet/marvell/pxa168_eth.c | 70 +++++++++++++++++++++----------
1 file changed, 47 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index b370162dbe02..978f26198dd6 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -193,6 +193,7 @@ struct tx_desc {
struct pxa168_eth_private {
int port_num; /* User Ethernet port number */
+ int phy_addr;
int rx_resource_err; /* Rx ring resource error flag */
@@ -1360,24 +1361,25 @@ static struct phy_device *phy_scan(struct pxa168_eth_private *pep, int phy_addr)
return phydev;
}
-static void phy_init(struct pxa168_eth_private *pep, int speed, int duplex)
+static void phy_init(struct pxa168_eth_private *pep)
{
struct phy_device *phy = pep->phy;
phy_attach(pep->dev, dev_name(&phy->dev), PHY_INTERFACE_MODE_MII);
- if (speed == 0) {
+ if (pep->pd && pep->pd->speed != 0) {
+ phy->autoneg = AUTONEG_DISABLE;
+ phy->advertising = 0;
+ phy->speed = pep->pd->speed;
+ phy->duplex = pep->pd->duplex;
+ } else {
phy->autoneg = AUTONEG_ENABLE;
phy->speed = 0;
phy->duplex = 0;
phy->supported &= PHY_BASIC_FEATURES;
phy->advertising = phy->supported | ADVERTISED_Autoneg;
- } else {
- phy->autoneg = AUTONEG_DISABLE;
- phy->advertising = 0;
- phy->speed = speed;
- phy->duplex = duplex;
}
+
phy_start_aneg(phy);
}
@@ -1385,11 +1387,13 @@ static int ethernet_phy_setup(struct net_device *dev)
{
struct pxa168_eth_private *pep = netdev_priv(dev);
- if (pep->pd->init)
+ if (pep->pd && pep->pd->init)
pep->pd->init();
- pep->phy = phy_scan(pep, pep->pd->phy_addr & 0x1f);
+
+ pep->phy = phy_scan(pep, pep->phy_addr & 0x1f);
if (pep->phy != NULL)
- phy_init(pep, pep->pd->speed, pep->pd->duplex);
+ phy_init(pep);
+
update_hash_table_mac_address(pep, NULL, dev->dev_addr);
return 0;
@@ -1449,16 +1453,17 @@ static int pxa168_eth_probe(struct platform_device *pdev)
struct net_device *dev = NULL;
struct resource *res;
struct clk *clk;
+ struct device_node *np;
int err;
printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
- clk = clk_get(&pdev->dev, "MFUCLK");
+ clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "Fast Ethernet failed to get clock\n");
return -ENODEV;
}
- clk_enable(clk);
+ clk_prepare_enable(clk);
dev = alloc_etherdev(sizeof(struct pxa168_eth_private));
if (!dev) {
@@ -1475,8 +1480,8 @@ static int pxa168_eth_probe(struct platform_device *pdev)
err = -ENODEV;
goto err_netdev;
}
- pep->base = ioremap(res->start, resource_size(res));
- if (pep->base == NULL) {
+ pep->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pep->base)) {
err = -ENOMEM;
goto err_netdev;
}
@@ -1493,16 +1498,28 @@ static int pxa168_eth_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Using random mac address\n");
eth_hw_addr_random(dev);
- pep->pd = dev_get_platdata(&pdev->dev);
pep->rx_ring_size = NUM_RX_DESCS;
- if (pep->pd->rx_queue_size)
- pep->rx_ring_size = pep->pd->rx_queue_size;
-
pep->tx_ring_size = NUM_TX_DESCS;
- if (pep->pd->tx_queue_size)
- pep->tx_ring_size = pep->pd->tx_queue_size;
- pep->port_num = pep->pd->port_number;
+ pep->pd = dev_get_platdata(&pdev->dev);
+ if (pep->pd) {
+ if (pep->pd->rx_queue_size)
+ pep->rx_ring_size = pep->pd->rx_queue_size;
+
+ if (pep->pd->tx_queue_size)
+ pep->tx_ring_size = pep->pd->tx_queue_size;
+
+ pep->port_num = pep->pd->port_number;
+ pep->phy_addr = pep->pd->phy_addr;
+ } else if (pdev->dev.of_node) {
+ of_property_read_u32(pdev->dev.of_node, "port-id",
+ &pep->port_num);
+
+ np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
+ if (np)
+ of_property_read_u32(np, "reg", &pep->phy_addr);
+ }
+
/* Hardware supports only 3 ports */
BUG_ON(pep->port_num > 2);
netif_napi_add(dev, &pep->napi, pxa168_rx_poll, pep->rx_ring_size);
@@ -1603,6 +1620,12 @@ static int pxa168_eth_suspend(struct platform_device *pdev, pm_message_t state)
#define pxa168_eth_suspend NULL
#endif
+static const struct of_device_id pxa168_eth_of_match[] = {
+ { .compatible = "marvell,pxa168-eth" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, pxa168_eth_of_match)
+
static struct platform_driver pxa168_eth_driver = {
.probe = pxa168_eth_probe,
.remove = pxa168_eth_remove,
@@ -1610,8 +1633,9 @@ static struct platform_driver pxa168_eth_driver = {
.resume = pxa168_eth_resume,
.suspend = pxa168_eth_suspend,
.driver = {
- .name = DRIVER_NAME,
- },
+ .name = DRIVER_NAME,
+ .of_match_table = of_match_ptr(pxa168_eth_of_match),
+ },
};
module_platform_driver(pxa168_eth_driver);
--
1.9.1
^ permalink raw reply related
* [PATCH v5 01/10] net: pxa168_eth: clean up
From: Antoine Tenart @ 2014-09-26 14:33 UTC (permalink / raw)
To: sebastian.hesselbarth
Cc: thomas.petazzoni, zmxu, devicetree, netdev, Antoine Tenart,
linux-kernel, alexandre.belloni, jszhang, linux-arm-kernel
In-Reply-To: <1411742036-23520-1-git-send-email-antoine.tenart@free-electrons.com>
Clean up a bit the pxa168_eth driver before adding the device tree
support.
Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/ethernet/marvell/pxa168_eth.c | 102 +++++++++++++++---------------
1 file changed, 50 insertions(+), 52 deletions(-)
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index 8f5aa7c62b18..b370162dbe02 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -22,27 +22,29 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/dma-mapping.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#include <linux/etherdevice.h>
#include <linux/bitops.h>
+#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
#include <linux/ethtool.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
+#include <linux/in.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ip.h>
#include <linux/kernel.h>
-#include <linux/workqueue.h>
-#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of.h>
#include <linux/phy.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/pxa168_eth.h>
+#include <linux/tcp.h>
#include <linux/types.h>
+#include <linux/udp.h>
+#include <linux/workqueue.h>
+
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
-#include <linux/pxa168_eth.h>
#define DRIVER_NAME "pxa168-eth"
#define DRIVER_VERSION "0.3"
@@ -296,7 +298,7 @@ static void abort_dma(struct pxa168_eth_private *pep)
} while (max_retries-- > 0 && delay <= 0);
if (max_retries <= 0)
- printk(KERN_ERR "%s : DMA Stuck\n", __func__);
+ netdev_err(pep->dev, "%s : DMA Stuck\n", __func__);
}
static int ethernet_phy_get(struct pxa168_eth_private *pep)
@@ -507,9 +509,10 @@ static int add_del_hash_entry(struct pxa168_eth_private *pep,
if (i == HOP_NUMBER) {
if (!del) {
- printk(KERN_INFO "%s: table section is full, need to "
- "move to 16kB implementation?\n",
- __FILE__);
+ netdev_info(pep->dev,
+ "%s: table section is full, need to "
+ "move to 16kB implementation?\n",
+ __FILE__);
return -ENOSPC;
} else
return 0;
@@ -726,7 +729,7 @@ static int txq_reclaim(struct net_device *dev, int force)
if (cmd_sts & TX_ERROR) {
if (net_ratelimit())
- printk(KERN_ERR "%s: Error in TX\n", dev->name);
+ netdev_err(dev, "Error in TX\n");
dev->stats.tx_errors++;
}
dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);
@@ -743,8 +746,7 @@ static void pxa168_eth_tx_timeout(struct net_device *dev)
{
struct pxa168_eth_private *pep = netdev_priv(dev);
- printk(KERN_INFO "%s: TX timeout desc_count %d\n",
- dev->name, pep->tx_desc_count);
+ netdev_info(dev, "TX timeout desc_count %d\n", pep->tx_desc_count);
schedule_work(&pep->tx_timeout_task);
}
@@ -814,9 +816,8 @@ static int rxq_process(struct net_device *dev, int budget)
if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
(RX_FIRST_DESC | RX_LAST_DESC)) {
if (net_ratelimit())
- printk(KERN_ERR
- "%s: Rx pkt on multiple desc\n",
- dev->name);
+ netdev_err(dev,
+ "Rx pkt on multiple desc\n");
}
if (cmd_sts & RX_ERROR)
stats->rx_errors++;
@@ -871,7 +872,7 @@ static void handle_link_event(struct pxa168_eth_private *pep)
port_status = rdl(pep, PORT_STATUS);
if (!(port_status & LINK_UP)) {
if (netif_carrier_ok(dev)) {
- printk(KERN_INFO "%s: link down\n", dev->name);
+ netdev_info(dev, "link down\n");
netif_carrier_off(dev);
txq_reclaim(dev, 1);
}
@@ -884,9 +885,8 @@ static void handle_link_event(struct pxa168_eth_private *pep)
duplex = (port_status & FULL_DUPLEX) ? 1 : 0;
fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0;
- printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
- "flow control %sabled\n", dev->name,
- speed, duplex ? "full" : "half", fc ? "en" : "dis");
+ netdev_info(dev, "link up, %d Mb/s, %s duplex, flow control %sabled\n",
+ speed, duplex ? "full" : "half", fc ? "en" : "dis");
if (!netif_carrier_ok(dev))
netif_carrier_on(dev);
}
@@ -1039,9 +1039,8 @@ static void rxq_deinit(struct net_device *dev)
}
}
if (pep->rx_desc_count)
- printk(KERN_ERR
- "Error in freeing Rx Ring. %d skb's still\n",
- pep->rx_desc_count);
+ netdev_err(dev, "Error in freeing Rx Ring. %d skb's still\n",
+ pep->rx_desc_count);
/* Free RX ring */
if (pep->p_rx_desc_area)
dma_free_coherent(pep->dev->dev.parent, pep->rx_desc_area_size,
@@ -1280,15 +1279,15 @@ static int pxa168_smi_read(struct mii_bus *bus, int phy_addr, int regnum)
int val;
if (smi_wait_ready(pep)) {
- printk(KERN_WARNING "pxa168_eth: SMI bus busy timeout\n");
+ netdev_warn(pep->dev, "pxa168_eth: SMI bus busy timeout\n");
return -ETIMEDOUT;
}
wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) | SMI_OP_R);
/* now wait for the data to be valid */
for (i = 0; !((val = rdl(pep, SMI)) & SMI_R_VALID); i++) {
if (i == PHY_WAIT_ITERATIONS) {
- printk(KERN_WARNING
- "pxa168_eth: SMI bus read not valid\n");
+ netdev_warn(pep->dev,
+ "pxa168_eth: SMI bus read not valid\n");
return -ENODEV;
}
msleep(10);
@@ -1303,7 +1302,7 @@ static int pxa168_smi_write(struct mii_bus *bus, int phy_addr, int regnum,
struct pxa168_eth_private *pep = bus->priv;
if (smi_wait_ready(pep)) {
- printk(KERN_WARNING "pxa168_eth: SMI bus busy timeout\n");
+ netdev_warn(pep->dev, "pxa168_eth: SMI bus busy timeout\n");
return -ETIMEDOUT;
}
@@ -1311,7 +1310,7 @@ static int pxa168_smi_write(struct mii_bus *bus, int phy_addr, int regnum,
SMI_OP_W | (value & 0xffff));
if (smi_wait_ready(pep)) {
- printk(KERN_ERR "pxa168_eth: SMI bus busy timeout\n");
+ netdev_err(pep->dev, "pxa168_eth: SMI bus busy timeout\n");
return -ETIMEDOUT;
}
@@ -1425,23 +1424,23 @@ static void pxa168_get_drvinfo(struct net_device *dev,
}
static const struct ethtool_ops pxa168_ethtool_ops = {
- .get_settings = pxa168_get_settings,
- .set_settings = pxa168_set_settings,
- .get_drvinfo = pxa168_get_drvinfo,
- .get_link = ethtool_op_get_link,
- .get_ts_info = ethtool_op_get_ts_info,
+ .get_settings = pxa168_get_settings,
+ .set_settings = pxa168_set_settings,
+ .get_drvinfo = pxa168_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static const struct net_device_ops pxa168_eth_netdev_ops = {
- .ndo_open = pxa168_eth_open,
- .ndo_stop = pxa168_eth_stop,
- .ndo_start_xmit = pxa168_eth_start_xmit,
- .ndo_set_rx_mode = pxa168_eth_set_rx_mode,
- .ndo_set_mac_address = pxa168_eth_set_mac_address,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = pxa168_eth_do_ioctl,
- .ndo_change_mtu = pxa168_eth_change_mtu,
- .ndo_tx_timeout = pxa168_eth_tx_timeout,
+ .ndo_open = pxa168_eth_open,
+ .ndo_stop = pxa168_eth_stop,
+ .ndo_start_xmit = pxa168_eth_start_xmit,
+ .ndo_set_rx_mode = pxa168_eth_set_rx_mode,
+ .ndo_set_mac_address = pxa168_eth_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = pxa168_eth_do_ioctl,
+ .ndo_change_mtu = pxa168_eth_change_mtu,
+ .ndo_tx_timeout = pxa168_eth_tx_timeout,
};
static int pxa168_eth_probe(struct platform_device *pdev)
@@ -1456,8 +1455,7 @@ static int pxa168_eth_probe(struct platform_device *pdev)
clk = clk_get(&pdev->dev, "MFUCLK");
if (IS_ERR(clk)) {
- printk(KERN_ERR "%s: Fast Ethernet failed to get clock\n",
- DRIVER_NAME);
+ dev_err(&pdev->dev, "Fast Ethernet failed to get clock\n");
return -ENODEV;
}
clk_enable(clk);
@@ -1492,7 +1490,7 @@ static int pxa168_eth_probe(struct platform_device *pdev)
INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
- printk(KERN_INFO "%s:Using random mac address\n", DRIVER_NAME);
+ dev_info(&pdev->dev, "Using random mac address\n");
eth_hw_addr_random(dev);
pep->pd = dev_get_platdata(&pdev->dev);
--
1.9.1
^ permalink raw reply related
* RE: [PATCH v1 2/4] net: fec: ptp: Use hardware algorithm to adjust PTP counter.
From: Frank.Li @ 2014-09-26 14:31 UTC (permalink / raw)
To: luwei.zhou@freescale.com, davem@davemloft.net,
richardcochran@gmail.com
Cc: netdev@vger.kernel.org, shawn.guo@linaro.org,
bhutchings@solarflare.com, Fabio.Estevam@freescale.com,
fugang.duan@freescale.com, stephen@networkplumber.org
In-Reply-To: <859d1e45326a41d2b53d954e8ecd9d46@BY2PR03MB441.namprd03.prod.outlook.com>
>
> Hi Frank,
>
> I ran checkpatch and it can pass. I will update it in the next version.
>
Don't top post message in community mail list.
Frank Li
> Luwei
> Best Regards
>
> -----Original Message-----
> From: Li Frank-B20596
> Sent: Thursday, September 25, 2014 9:30 PM
> To: Zhou Luwei-B45643; davem@davemloft.net; richardcochran@gmail.com
> Cc: netdev@vger.kernel.org; shawn.guo@linaro.org; bhutchings@solarflare.com;
> Estevam Fabio-R49496; Duan Fugang-B38611; stephen@networkplumber.org
> Subject: RE: [PATCH v1 2/4] net: fec: ptp: Use hardware algorithm to adjust PTP
> counter.
>
>
>
> > -----Original Message-----
> > From: Luwei Zhou [mailto:b45643@freescale.com]
> > Sent: Thursday, September 25, 2014 3:10 AM
> > To: davem@davemloft.net; richardcochran@gmail.com
> > Cc: netdev@vger.kernel.org; shawn.guo@linaro.org;
> > bhutchings@solarflare.com; Estevam Fabio-R49496; Duan Fugang-B38611;
> > Li Frank-B20596; stephen@networkplumber.org
> > Subject: [PATCH v1 2/4] net: fec: ptp: Use hardware algorithm to
> > adjust PTP counter.
> >
> > The FEC IP supports hardware adjustment for ptp timer. Refer to the
> > description of ENET_ATCOR and ENET_ATINC registers in the spec about the
> hardware adjustment.
> > This patch uses hardware support to adjust the ptp offset and
> > frequency on the slave side.
> >
> > Signed-off-by: Luwei Zhou <b45643@freescale.com>
> > Signed-off-by: Frank Li <Frank.Li@freescale.com>
> > Signed-off-by: Fugang Duan <b38611@freescale.com>
> > ---
> > drivers/net/ethernet/freescale/fec_ptp.c | 68
> > +++++++++++++++++++++++++++-----
> > 1 file changed, 58 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/freescale/fec_ptp.c
> > b/drivers/net/ethernet/freescale/fec_ptp.c
> > index 8016bdd..e2bf786 100644
> > --- a/drivers/net/ethernet/freescale/fec_ptp.c
> > +++ b/drivers/net/ethernet/freescale/fec_ptp.c
> > @@ -71,6 +71,7 @@
> >
> > #define FEC_CC_MULT (1 << 31)
> > #define FEC_COUNTER_PERIOD (1 << 31)
> > +#define FEC_T_PERIOD_ONE_SEC (1000000000UL)
> > /**
> > * fec_ptp_read - read raw cycle counter (to be used by time counter)
> > * @cc: the cyclecounter structure
> > @@ -145,33 +146,65 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
> > */
> > static int fec_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) {
> > - u64 diff;
> > unsigned long flags;
> > int neg_adj = 0;
> > - u32 mult = FEC_CC_MULT;
> > + u32 i, tmp;
> > + u32 ptp_ts_clk, ptp_inc;
> > + u32 corr_inc, corr_period;
> > + u32 corr_ns;
> >
> > struct fec_enet_private *fep =
> > container_of(ptp, struct fec_enet_private, ptp_caps);
> >
> > + if (ppb == 0)
> > + return 0;
> > +
> > if (ppb < 0) {
> > ppb = -ppb;
> > neg_adj = 1;
> > }
> >
> > - diff = mult;
> > - diff *= ppb;
> > - diff = div_u64(diff, 1000000000ULL);
> > + ptp_ts_clk = clk_get_rate(fep->clk_ptp);
> > + ptp_inc = FEC_T_PERIOD_ONE_SEC / ptp_ts_clk;
> > +
> > + /*
> > + * In theory, corr_inc/corr_period = ppb/FEC_T_PERIOD_ONE_SEC;
> > + * Try to find the corr_inc between 1 to ptp_inc to meet adjustment
> > + * requirement.
> > + */
> > + for (i = 1; i <= ptp_inc; i++) {
> > + if (((i * FEC_T_PERIOD_ONE_SEC) / ppb) >= ptp_inc) {
> > + corr_inc = i;
> > + corr_period = ((i * FEC_T_PERIOD_ONE_SEC) /
> > + (ptp_inc * ppb));
> > + break;
> > + }
> > + }
> > + /*
> > + * Not found? Set it to high value - double speed
> > + * correct in every clock step.
> > + */
> > + if (i > ptp_inc) {
> > + corr_inc = ptp_inc;
> > + corr_period = 1;
> > + }
> > +
> > + if (neg_adj)
> > + corr_ns = ptp_inc - corr_inc;
> > + else
> > + corr_ns = ptp_inc + corr_inc;
> >
> > spin_lock_irqsave(&fep->tmreg_lock, flags);
> > +
> > + tmp = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK;
> > + tmp |= corr_ns << FEC_T_INC_CORR_OFFSET;
> > + writel(tmp, fep->hwp + FEC_ATIME_INC);
> > + writel(corr_period, fep->hwp + FEC_ATIME_CORR);
> > /*
> > - * dummy read to set cycle_last in tc to now.
> > - * So use adjusted mult to calculate when next call
> > - * timercounter_read.
> > + * dummy read to update the timer.
> > */
> > timecounter_read(&fep->tc);
> >
> > - fep->cc.mult = neg_adj ? mult - diff : mult + diff;
> > -
> > spin_unlock_irqrestore(&fep->tmreg_lock, flags);
> >
> > return 0;
> > @@ -190,12 +223,20 @@ static int fec_ptp_adjtime(struct ptp_clock_info
> > *ptp, s64
> > delta)
> > container_of(ptp, struct fec_enet_private, ptp_caps);
> > unsigned long flags;
> > u64 now;
> > + u32 counter;
> >
> > spin_lock_irqsave(&fep->tmreg_lock, flags);
> >
> > now = timecounter_read(&fep->tc);
> > now += delta;
> >
> > + /*
> > + * Get the timer value based on adjusted timestamp.
> > + * Update the counter with the masked value.
> > + */
>
> Comments should like
>
> /* Get the xxx
> * dds
> */
>
> First empty line is not necessary.
> Please check the other place.
>
> Did you run checkpatch script?
>
> Best regards
> Frank Li
>
> > + counter = now & fep->cc.mask;
> > + writel(counter, fep->hwp + FEC_ATIME);
> > +
> > /* reset the timecounter */
> > timecounter_init(&fep->tc, &fep->cc, now);
> >
> > @@ -246,6 +287,7 @@ static int fec_ptp_settime(struct ptp_clock_info
> > *ptp,
> >
> > u64 ns;
> > unsigned long flags;
> > + u32 counter;
> >
> > mutex_lock(&fep->ptp_clk_mutex);
> > /* Check the ptp clock */
> > @@ -256,8 +298,14 @@ static int fec_ptp_settime(struct ptp_clock_info
> > *ptp,
> >
> > ns = ts->tv_sec * 1000000000ULL;
> > ns += ts->tv_nsec;
> > + /*
> > + * Get the timer value based on timestamp.
> > + * Update the counter with the masked value.
> > + */
> > + counter = ns & fep->cc.mask;
> >
> > spin_lock_irqsave(&fep->tmreg_lock, flags);
> > + writel(counter, fep->hwp + FEC_ATIME);
> > timecounter_init(&fep->tc, &fep->cc, ns);
> > spin_unlock_irqrestore(&fep->tmreg_lock, flags);
> > mutex_unlock(&fep->ptp_clk_mutex);
> > --
> > 1.9.1
^ permalink raw reply
* Re: BCM4313 & brcmsmac & 3.12: only semi-working?
From: Michael Tokarev @ 2014-09-26 14:26 UTC (permalink / raw)
To: Arend van Spriel; +Cc: Seth Forshee, brcm80211-dev-list, linux-wireless, netdev
In-Reply-To: <8d3f6516-9578-406c-9444-6fe1ba982ea6@email.android.com>
Okay, so finally, today, without any updates from your side,
I opened up the laptop again and inserted a newly bought
Intel 6235ANHMW card instead of this creaky brcm4313. This
card works right out of the box - plug it in and set up,
both wifi and bluetooth (I had numerous probs with bluetooth
too with brcm card), and it works on both 2.4GHz and 5GHz
bands. Connection is very good and stable, I wasn't able
to trigger a single glitch no matter how hard I tried.
My only sorry is a lot of wasted time, efforts and money -
all that have much better value than trying to deal with
non-working drivers. And my only wish is so vendors stop
using non-working parts in their hardware.. But oh well.
Thanks,
/mjt
^ permalink raw reply
* [PATCH net-next v2] bonding: make global bonding stats more reliable
From: Andy Gospodarek @ 2014-09-25 22:37 UTC (permalink / raw)
To: netdev; +Cc: j.vosburgh, vfalico, nikolay
As the code stands today, bonding stats are based simply on the stats
from the member interfaces. If a member was to be removed from a bond,
the stats would instantly drop. This would be confusing to an admin
would would suddonly see interface stats drop while traffic is still
flowing.
In addition to preventing the stats drops mentioned above, new members
will now be added to the bond and only traffic received after the member
was added to the bond will be counted as part of bonding stats.
v2: Changes suggested by Nik to properly allocate/free stats memory.
Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
---
drivers/net/bonding/bond_main.c | 85 +++++++++++++++++++++++++++--------------
drivers/net/bonding/bonding.h | 3 ++
2 files changed, 60 insertions(+), 28 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 5390475..61333b1 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1147,17 +1147,26 @@ static struct slave *bond_alloc_slave(struct bonding *bond)
slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
if (!slave)
- return NULL;
+ goto slave_fail;
+
+ slave->slave_stats = kzalloc(sizeof(struct rtnl_link_stats64),
+ GFP_KERNEL);
+ if (!slave->slave_stats)
+ goto slave_stats_fail;
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info),
GFP_KERNEL);
- if (!SLAVE_AD_INFO(slave)) {
- kfree(slave);
- return NULL;
- }
+ if (!SLAVE_AD_INFO(slave))
+ goto slave_ad_fail;
}
return slave;
+slave_ad_fail:
+ kfree(slave->slave_stats);
+slave_stats_fail:
+ kfree(slave);
+slave_fail:
+ return NULL;
}
static void bond_free_slave(struct slave *slave)
@@ -1167,6 +1176,7 @@ static void bond_free_slave(struct slave *slave)
if (BOND_MODE(bond) == BOND_MODE_8023AD)
kfree(SLAVE_AD_INFO(slave));
+ kfree(slave->slave_stats);
kfree(slave);
}
@@ -1344,6 +1354,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
}
slave_dev->priv_flags |= IFF_BONDING;
+ /* initialize slave stats */
+ dev_get_stats(new_slave->dev, new_slave->slave_stats);
if (bond_is_lb(bond)) {
/* bond_alb_init_slave() must be called before all other stages since
@@ -3085,38 +3097,43 @@ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
struct list_head *iter;
struct slave *slave;
- memset(stats, 0, sizeof(*stats));
+ memcpy(stats, bond->bond_stats, sizeof(*stats));
bond_for_each_slave(bond, slave, iter) {
const struct rtnl_link_stats64 *sstats =
dev_get_stats(slave->dev, &temp);
+ struct rtnl_link_stats64 *pstats = slave->slave_stats;
- stats->rx_packets += sstats->rx_packets;
- stats->rx_bytes += sstats->rx_bytes;
- stats->rx_errors += sstats->rx_errors;
- stats->rx_dropped += sstats->rx_dropped;
+ stats->rx_packets += sstats->rx_packets - pstats->rx_packets;
+ stats->rx_bytes += sstats->rx_bytes - pstats->rx_bytes;
+ stats->rx_errors += sstats->rx_errors - pstats->rx_errors;
+ stats->rx_dropped += sstats->rx_dropped - pstats->rx_dropped;
- stats->tx_packets += sstats->tx_packets;
- stats->tx_bytes += sstats->tx_bytes;
- stats->tx_errors += sstats->tx_errors;
- stats->tx_dropped += sstats->tx_dropped;
+ stats->tx_packets += sstats->tx_packets - pstats->tx_packets;;
+ stats->tx_bytes += sstats->tx_bytes - pstats->tx_bytes;
+ stats->tx_errors += sstats->tx_errors - pstats->tx_errors;
+ stats->tx_dropped += sstats->tx_dropped - pstats->tx_dropped;
- stats->multicast += sstats->multicast;
- stats->collisions += sstats->collisions;
+ stats->multicast += sstats->multicast - pstats->multicast;
+ stats->collisions += sstats->collisions - pstats->collisions;
- stats->rx_length_errors += sstats->rx_length_errors;
- stats->rx_over_errors += sstats->rx_over_errors;
- stats->rx_crc_errors += sstats->rx_crc_errors;
- stats->rx_frame_errors += sstats->rx_frame_errors;
- stats->rx_fifo_errors += sstats->rx_fifo_errors;
- stats->rx_missed_errors += sstats->rx_missed_errors;
+ stats->rx_length_errors += sstats->rx_length_errors - pstats->rx_length_errors;
+ stats->rx_over_errors += sstats->rx_over_errors - pstats->rx_over_errors;
+ stats->rx_crc_errors += sstats->rx_crc_errors - pstats->rx_crc_errors;
+ stats->rx_frame_errors += sstats->rx_frame_errors - pstats->rx_frame_errors;
+ stats->rx_fifo_errors += sstats->rx_fifo_errors - pstats->rx_fifo_errors;
+ stats->rx_missed_errors += sstats->rx_missed_errors - pstats->rx_missed_errors;
- stats->tx_aborted_errors += sstats->tx_aborted_errors;
- stats->tx_carrier_errors += sstats->tx_carrier_errors;
- stats->tx_fifo_errors += sstats->tx_fifo_errors;
- stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors;
- stats->tx_window_errors += sstats->tx_window_errors;
+ stats->tx_aborted_errors += sstats->tx_aborted_errors - pstats->tx_aborted_errors;
+ stats->tx_carrier_errors += sstats->tx_carrier_errors - pstats->tx_carrier_errors;
+ stats->tx_fifo_errors += sstats->tx_fifo_errors - pstats->tx_fifo_errors;
+ stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors - pstats->tx_heartbeat_errors;
+ stats->tx_window_errors += sstats->tx_window_errors - pstats->tx_window_errors;
+
+ /* save off the slave stats for the next run */
+ memcpy(pstats, sstats, sizeof(*sstats));
}
+ memcpy(bond->bond_stats, stats, sizeof(*stats));
return stats;
}
@@ -3857,6 +3874,8 @@ static void bond_uninit(struct net_device *bond_dev)
__bond_release_one(bond_dev, slave->dev, true);
netdev_info(bond_dev, "Released all slaves\n");
+ kfree(bond->bond_stats);
+
list_del(&bond->bond_list);
bond_debug_unregister(bond);
@@ -4243,7 +4262,13 @@ static int bond_init(struct net_device *bond_dev)
bond->wq = create_singlethread_workqueue(bond_dev->name);
if (!bond->wq)
- return -ENOMEM;
+ goto bond_wq_fail;
+
+ /* initialize persistent stats for the bond */
+ bond->bond_stats = kzalloc(sizeof(struct rtnl_link_stats64),
+ GFP_KERNEL);
+ if (!bond->bond_stats)
+ goto bond_stats_fail;
bond_set_lockdep_class(bond_dev);
@@ -4259,6 +4284,10 @@ static int bond_init(struct net_device *bond_dev)
eth_hw_addr_random(bond_dev);
return 0;
+bond_stats_fail:
+ kfree(bond->wq);
+bond_wq_fail:
+ return -ENOMEM;
}
unsigned int bond_get_num_tx_queues(void)
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 6140bf0..fe25265 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -24,6 +24,7 @@
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/reciprocal_div.h>
+#include <linux/if_link.h>
#include "bond_3ad.h"
#include "bond_alb.h"
@@ -175,6 +176,7 @@ struct slave {
struct netpoll *np;
#endif
struct kobject kobj;
+ struct rtnl_link_stats64 *slave_stats;
};
/*
@@ -224,6 +226,7 @@ struct bonding {
/* debugging support via debugfs */
struct dentry *debug_dir;
#endif /* CONFIG_DEBUG_FS */
+ struct rtnl_link_stats64 *bond_stats;
};
#define bond_slave_get_rcu(dev) \
--
1.9.3
^ permalink raw reply related
* Re: [PATCH net-next] bonding: make global bonding stats more reliable
From: Andy Gospodarek @ 2014-09-26 13:52 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: netdev, j.vosburgh, vfalico
In-Reply-To: <54256BA5.9080803@redhat.com>
On Fri, Sep 26, 2014 at 03:35:33PM +0200, Nikolay Aleksandrov wrote:
> On 26/09/14 15:26, Andy Gospodarek wrote:
> >On Fri, Sep 26, 2014 at 10:52:16AM +0200, Nikolay Aleksandrov wrote:
> >>On 25/09/14 15:16, Andy Gospodarek wrote:
> >>>As the code stands today, bonding stats are based simply on the stats
> >>>from the member interfaces. If a member was to be removed from a bond,
> >>>the stats would instantly drop. This would be confusing to an admin
> >>>would would suddonly see interface stats drop while traffic is still
> >>>flowing.
> >>>
> >>>In addition to preventing the stats drops mentioned above, new members
> >>>will now be added to the bond and only traffic received after the member
> >>>was added to the bond will be counted as part of bonding stats.
> >>>
> >>>Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> >>>---
> >>Hi Andy,
> >>
> <<<<snip>>>>
> >>>@@ -4258,6 +4274,9 @@ static int bond_init(struct net_device *bond_dev)
> >>> bond_dev->addr_assign_type == NET_ADDR_PERM)
> >>> eth_hw_addr_random(bond_dev);
> >>>
> >>>+ /* initialize persistent stats for the bond */
> >>>+ bond->bond_stats = kzalloc(sizeof(struct rtnl_link_stats64),
> >>>+ GFP_ATOMIC);
> >>^^^^^^^^^^^^^^^^^^^^^^^^
> >>I don't think this will get freed if the bond device is destroyed.
> >Another good catch. Thanks for the review. V2 incoming after some
> >testing.
> >
> Great, one more thing I forgot to ask, why the GFP_ATOMIC here ? I believe
> we're allowed to sleep in ndo_init(), and you should probably handle the
ndo_init() can (and likely will) sleep, but since all not skb data
allocated in bonding appears to be GFP_KERNEL, I'll switch to that for
consistency.
> case where the bond_stats allocation fails, too.
Yep, on it! :)
>
> >>
> >>> return 0;
> >>> }
> >>>
> >>>diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
> >>>index 6140bf0..fe25265 100644
> >>>--- a/drivers/net/bonding/bonding.h
> >>>+++ b/drivers/net/bonding/bonding.h
> >>>@@ -24,6 +24,7 @@
> >>> #include <linux/inetdevice.h>
> >>> #include <linux/etherdevice.h>
> >>> #include <linux/reciprocal_div.h>
> >>>+#include <linux/if_link.h>
> >>>
> >>> #include "bond_3ad.h"
> >>> #include "bond_alb.h"
> >>>@@ -175,6 +176,7 @@ struct slave {
> >>> struct netpoll *np;
> >>> #endif
> >>> struct kobject kobj;
> >>>+ struct rtnl_link_stats64 *slave_stats;
> >>> };
> >>>
> >>> /*
> >>>@@ -224,6 +226,7 @@ struct bonding {
> >>> /* debugging support via debugfs */
> >>> struct dentry *debug_dir;
> >>> #endif /* CONFIG_DEBUG_FS */
> >>>+ struct rtnl_link_stats64 *bond_stats;
> >>> };
> >>>
> >>> #define bond_slave_get_rcu(dev) \
> >>>
> >>
>
^ permalink raw reply
* [PATCH v2] net: stmmac: fix stmmac_pci_probe failed when CONFIG_HAVE_CLK is selected
From: Kweh Hock Leong @ 2014-09-26 13:42 UTC (permalink / raw)
To: David S. Miller, Giuseppe Cavallaro, rayagond
Cc: Vince Bridgers, Chen-Yu Tsai, netdev, LKML, Ong Boon Leong,
Tobias Klausmann
From: "Kweh, Hock Leong" <hock.leong.kweh@intel.com>
When the CONFIG_HAVE_CLK is selected for the system, the stmmac_pci_probe
will fail with dmesg:
[ 2.167225] stmmaceth 0000:00:14.6: enabling device (0000 -> 0002)
[ 2.178267] stmmaceth 0000:00:14.6: enabling bus mastering
[ 2.178436] stmmaceth 0000:00:14.6: irq 24 for MSI/MSI-X
[ 2.178703] stmmaceth 0000:00:14.6: stmmac_dvr_probe: warning: cannot
get CSR clock
[ 2.186503] stmmac_pci_probe: main driver probe failed
[ 2.194003] stmmaceth 0000:00:14.6: disabling bus mastering
[ 2.196473] stmmaceth: probe of 0000:00:14.6 failed with error -2
This patch fix the issue by breaking the dependency to devm_clk_get()
as the CSR clock can be obtained at priv->plat->clk_csr from pci driver.
Reported-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
Signed-off-by: Kweh, Hock Leong <hock.leong.kweh@intel.com>
---
changelog v2:
* retain the dev_warn message while devm_clk_get failed
* add in comments to indicate clk_csr failed condition
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 08addd6..90cac23 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2716,8 +2716,15 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
if (IS_ERR(priv->stmmac_clk)) {
dev_warn(priv->device, "%s: warning: cannot get CSR clock\n",
__func__);
- ret = PTR_ERR(priv->stmmac_clk);
- goto error_clk_get;
+ /* If failed to obtain stmmac_clk and specific clk_csr value
+ * is NOT passed from the platform, probe fail.
+ */
+ if (!priv->plat->clk_csr) {
+ ret = PTR_ERR(priv->stmmac_clk);
+ goto error_clk_get;
+ } else {
+ priv->stmmac_clk = NULL;
+ }
}
clk_prepare_enable(priv->stmmac_clk);
--
1.7.9.5
^ permalink raw reply related
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Nicolas Dichtel @ 2014-09-26 13:40 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andy Lutomirski, Stephen Hemminger, Eric W. Biederman,
linux-api-u79uwXL29TY76Z2rM5mHXA, Andrew Morton, David Miller
In-Reply-To: <CAHA+R7Ooyam2L-QfP-TjMEZEOqrQcQDxYiebmw760kgEji4G=g@mail.gmail.com>
Le 26/09/2014 04:09, Cong Wang a écrit :
> On Thu, Sep 25, 2014 at 1:53 AM, Nicolas Dichtel
> <nicolas.dichtel@6wind.com> wrote:
>> Le 24/09/2014 18:45, Cong Wang a écrit :
>>>
>>> On Wed, Sep 24, 2014 at 9:27 AM, Nicolas Dichtel
>>> <nicolas.dichtel@6wind.com> wrote:
>>>>
>>>> Now informations got with 'ip link' are wrong and incomplete:
>>>> - the link dev is now tunl0 instead of eth0, because we only got an
>>>> ifindex
>>>> from the kernel without any netns informations.
>>>
>>>
>>> This is not new, macvlan has the same problem. This is why I said
>>> it is mostly a display problem, maybe just mark the ifindex as -1 or
>>> something when it is not in this netns. At least I don't expect the inner
>>> netns know anything outside, and I don't think I am the only one using
>>> netns in this way.
>>
>> I understand your point but there is several use of netns. Netns can be used
>> also to instantiate virtual routers. In this case, administrators or daemons
>> need to be able to monitor and dump the configuration on all netns
>> (particularly beeing able to identify fully x-netns interfaces). We start to
>> discuss this in one of the two thread pointed in my cover letter and get the
>> conclusion that checking user ns is a good way to know if an id should be
>> disclosed or not for a peer netns.
>
> Then you are leaking information, this breaks isolation.
>
>> Can you describe your use case?
>
> Yes, too simple: isolation networking, different netns's don't see each other
> (including anything inside) and only communicate via veth.
If you are a privileged user and you are able to access a peer netns (move an
interface into this peer netns, move an interface from this peer netns to your
own netns), I don't see any reason to not beeing able to get information about
this peer netns (you are already a privileged user in both netns).
If you want to isolate this peer netns (I think you call it "inner netns"), you
have to create a new user ns for this netns, hence a privileged user into this
peer netns will not be able to act in your own netns. And with this scenario and
my patches, this privileged user will not be able to get an id. Isolation is
preserved.
How do you preserved it in your scenario?
>
>
>> If you only play with netns, you may want to monitor all activies in all
>> netns
>> (this is already possible) and beeing able to link information between netns
>> (this is what I'm trying to solve).
>
>
> No, I don't want to monitor anything. Even if I wanted, I would just start one
> daemon in each netns instead of one for all.
Ok you don't want, but some other people (not only me) want it! And having one
daemon per netns does not scale: there are scenarii with thousand netns which
are dynamically created and deleted.
>
> On the other hand, why not exchange the configuration via veth
> between different netns? There are many ways to do so with TCP HTTP etc.
> This doesn't have to be solved in kernel.
>
The standard way with linux to monitor network configuration is netlink.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Nicolas Dichtel @ 2014-09-26 13:38 UTC (permalink / raw)
To: Cong Wang
Cc: netdev, containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andy Lutomirski, Stephen Hemminger, Eric W. Biederman,
linux-api-u79uwXL29TY76Z2rM5mHXA, Andrew Morton, David Miller
In-Reply-To: <CAHA+R7OdOUMShX6Nphdfh8+fGiXyO+sGNHy0ch_XYh5dpURcmQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Le 26/09/2014 03:58, Cong Wang a écrit :
> On Thu, Sep 25, 2014 at 1:53 AM, Nicolas Dichtel
> <nicolas.dichtel@6wind.com> wrote:
>> Le 24/09/2014 18:48, Cong Wang a écrit :
>>
>>> On Wed, Sep 24, 2014 at 9:31 AM, Nicolas Dichtel
>>> <nicolas.dichtel@6wind.com> wrote:
>>>>>
>>>>> I think in this case your ID's are still available, but aren't you
>>>>> providing a new way
>>>>> for the inner netns device to escape which we are trying to avoid?
>>>>
>>>>
>>>> It's why the ids depend on user ns. Only if user ns are the same we allow
>>>> to
>>>> get an id for a peer netns.
>>>
>>>
>>> Too late, userns is relatively new, relying on it breaks our existing
>>> assumption.
>>>
>> I don't get your point. netns has been added in kernel after user ns:
>> acce292c82d4 user namespace: add the framework => 2.6.23
>> 5f256becd868 [NET]: Basic network namespace infrastructure. => 2.6.24
>
> Was it complete on 2.6.x? I doubt...
>
> https://lkml.org/lkml/2014/8/20/826
>
> As at Linux 3.8, most relevant subsystems supported user names‐
> paces, but a number of filesystems did not have the infrastruc‐
> ture needed to map user and group IDs between user namespaces.
> Linux 3.9 added the required infrastructure support for many of
> the remaining unsupported filesystems (Plan 9 (9P), Andrew File
> System (AFS), Ceph, CIFS, CODA, NFS, and OCFS2). Linux 3.11
> added support the last of the unsupported major filesystems, XFS.
>
>
>>
>> In the kernel, each netns is linked with a user ns.
>
> Are you saying every time we create a netns we have a new userns?
> This doesn't make sense for me.
>
No. I mean that each netns depends on a userns.
See include/net/net_namespace.h:
struct net {
[snip]
struct user_namespace *user_ns; /* Owning user namespace */
[snip]
}
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
^ permalink raw reply
* RE: [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Eric Dumazet @ 2014-09-26 13:38 UTC (permalink / raw)
To: David Laight
Cc: Tom Herbert, Jesper Dangaard Brouer, Linux Netdev List,
David S. Miller, Alexander Duyck,
Toke Høiland-Jørgensen, Florian Westphal,
Jamal Hadi Salim, Dave Taht, John Fastabend, Daniel Borkmann,
Hannes Frederic Sowa
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1749E538@AcuExch.aculab.com>
On Fri, 2014-09-26 at 13:16 +0000, David Laight wrote:
> OTOH it looks as though there is a big hit if you read then write
> a non-present cache line.
Well, this is exactly what it is about. Welcome to the club.
This is a well known problem.
Look at following old commit :
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=3f9d35b9514da6757ca98831372518f9eeb71b33
^ permalink raw reply
* Re: [PATCH net-next] bonding: make global bonding stats more reliable
From: Nikolay Aleksandrov @ 2014-09-26 13:35 UTC (permalink / raw)
To: Andy Gospodarek; +Cc: netdev, j.vosburgh, vfalico
In-Reply-To: <20140926132631.GA18564@gospo.home.greyhouse.net>
On 26/09/14 15:26, Andy Gospodarek wrote:
> On Fri, Sep 26, 2014 at 10:52:16AM +0200, Nikolay Aleksandrov wrote:
>> On 25/09/14 15:16, Andy Gospodarek wrote:
>>> As the code stands today, bonding stats are based simply on the stats
>> >from the member interfaces. If a member was to be removed from a bond,
>>> the stats would instantly drop. This would be confusing to an admin
>>> would would suddonly see interface stats drop while traffic is still
>>> flowing.
>>>
>>> In addition to preventing the stats drops mentioned above, new members
>>> will now be added to the bond and only traffic received after the member
>>> was added to the bond will be counted as part of bonding stats.
>>>
>>> Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
>>> ---
>> Hi Andy,
>>
<<<<snip>>>>
>>> @@ -4258,6 +4274,9 @@ static int bond_init(struct net_device *bond_dev)
>>> bond_dev->addr_assign_type == NET_ADDR_PERM)
>>> eth_hw_addr_random(bond_dev);
>>>
>>> + /* initialize persistent stats for the bond */
>>> + bond->bond_stats = kzalloc(sizeof(struct rtnl_link_stats64),
>>> + GFP_ATOMIC);
>> ^^^^^^^^^^^^^^^^^^^^^^^^
>> I don't think this will get freed if the bond device is destroyed.
> Another good catch. Thanks for the review. V2 incoming after some
> testing.
>
Great, one more thing I forgot to ask, why the GFP_ATOMIC here ? I believe we're
allowed to sleep in ndo_init(), and you should probably handle the case where
the bond_stats allocation fails, too.
>>
>>> return 0;
>>> }
>>>
>>> diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
>>> index 6140bf0..fe25265 100644
>>> --- a/drivers/net/bonding/bonding.h
>>> +++ b/drivers/net/bonding/bonding.h
>>> @@ -24,6 +24,7 @@
>>> #include <linux/inetdevice.h>
>>> #include <linux/etherdevice.h>
>>> #include <linux/reciprocal_div.h>
>>> +#include <linux/if_link.h>
>>>
>>> #include "bond_3ad.h"
>>> #include "bond_alb.h"
>>> @@ -175,6 +176,7 @@ struct slave {
>>> struct netpoll *np;
>>> #endif
>>> struct kobject kobj;
>>> + struct rtnl_link_stats64 *slave_stats;
>>> };
>>>
>>> /*
>>> @@ -224,6 +226,7 @@ struct bonding {
>>> /* debugging support via debugfs */
>>> struct dentry *debug_dir;
>>> #endif /* CONFIG_DEBUG_FS */
>>> + struct rtnl_link_stats64 *bond_stats;
>>> };
>>>
>>> #define bond_slave_get_rcu(dev) \
>>>
>>
^ permalink raw reply
* Re: [RFC] fclone layout suboptimal
From: Eric Dumazet @ 2014-09-26 13:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <1411736859.16953.121.camel@edumazet-glaptop2.roam.corp.google.com>
On Fri, 2014-09-26 at 06:07 -0700, Eric Dumazet wrote:
> [sk_buff skb1]
> [atomic_t fclone_ref]
> [sk_buff skb2]
Untested patch would be :
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index da1378a3e2c7..e39f03ea1822 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -178,6 +178,15 @@ out:
return skb;
}
+/* Layout of fast clones : [skb1][fclone_ref][skb2] */
+struct sk_buff_fclones {
+ struct sk_buff skb1;
+
+ atomic_t fclone_ref;
+
+ struct sk_buff skb2;
+};
+
/**
* __alloc_skb - allocate a network buffer
* @size: size to allocate
@@ -257,16 +266,17 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
kmemcheck_annotate_variable(shinfo->destructor_arg);
if (flags & SKB_ALLOC_FCLONE) {
- struct sk_buff *child = skb + 1;
- atomic_t *fclone_ref = (atomic_t *) (child + 1);
+ struct sk_buff_fclones *fclones;
+
+ fclones = (struct sk_buff_fclones *)skb;
- kmemcheck_annotate_bitfield(child, flags1);
- kmemcheck_annotate_bitfield(child, flags2);
- skb->fclone = SKB_FCLONE_ORIG;
- atomic_set(fclone_ref, 1);
+ kmemcheck_annotate_bitfield(&fclones->skb2, flags1);
+ kmemcheck_annotate_bitfield(&fclones->skb2, flags2);
+ fclones->skb1.fclone = SKB_FCLONE_ORIG;
+ atomic_set(&fclones->fclone_ref, 1);
- child->fclone = SKB_FCLONE_UNAVAILABLE;
- child->pfmemalloc = pfmemalloc;
+ fclones->skb2.fclone = SKB_FCLONE_UNAVAILABLE;
+ fclones->skb2.pfmemalloc = pfmemalloc;
}
out:
return skb;
@@ -524,8 +534,7 @@ static void skb_release_data(struct sk_buff *skb)
*/
static void kfree_skbmem(struct sk_buff *skb)
{
- struct sk_buff *other;
- atomic_t *fclone_ref;
+ struct sk_buff_fclones *fclones;
switch (skb->fclone) {
case SKB_FCLONE_UNAVAILABLE:
@@ -533,22 +542,21 @@ static void kfree_skbmem(struct sk_buff *skb)
break;
case SKB_FCLONE_ORIG:
- fclone_ref = (atomic_t *) (skb + 2);
- if (atomic_dec_and_test(fclone_ref))
- kmem_cache_free(skbuff_fclone_cache, skb);
+ fclones = container_of(skb, struct sk_buff_fclones, skb1);
+ if (atomic_dec_and_test(&fclones->fclone_ref))
+ kmem_cache_free(skbuff_fclone_cache, fclones);
break;
case SKB_FCLONE_CLONE:
- fclone_ref = (atomic_t *) (skb + 1);
- other = skb - 1;
+ fclones = container_of(skb, struct sk_buff_fclones, skb2);
/* The clone portion is available for
* fast-cloning again.
*/
skb->fclone = SKB_FCLONE_UNAVAILABLE;
- if (atomic_dec_and_test(fclone_ref))
- kmem_cache_free(skbuff_fclone_cache, other);
+ if (atomic_dec_and_test(&fclones->fclone_ref))
+ kmem_cache_free(skbuff_fclone_cache, fclones);
break;
}
}
@@ -855,17 +863,16 @@ EXPORT_SYMBOL_GPL(skb_copy_ubufs);
struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
{
- struct sk_buff *n;
+ struct sk_buff_fclones *fclones = (struct sk_buff_fclones *)skb;
+ struct sk_buff *n = &fclones->skb2;
if (skb_orphan_frags(skb, gfp_mask))
return NULL;
- n = skb + 1;
if (skb->fclone == SKB_FCLONE_ORIG &&
n->fclone == SKB_FCLONE_UNAVAILABLE) {
- atomic_t *fclone_ref = (atomic_t *) (n + 1);
n->fclone = SKB_FCLONE_CLONE;
- atomic_inc(fclone_ref);
+ atomic_inc(&fclones->fclone_ref);
} else {
if (skb_pfmemalloc(skb))
gfp_mask |= __GFP_MEMALLOC;
^ permalink raw reply related
* Re: FIXMEs in rt2800lib.c
From: Nicholas Krause @ 2014-09-26 13:32 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: Ivo Van Doorn, helmut.schaa-gM/Ye1E23mwN+BqQ9rBEUg, John Linville,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
users-poMEt7QlJxcwIE2E9O76wjtx2kNaKg5H,
netdev-u79uwXL29TY76Z2rM5mHXA,
julia.lawall-L2FTfq7BK8M@public.gmane.org oneukum-l3A5Bk7waGM@public.gmane.org
In-Reply-To: <20140926122207.GA27809-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Fri, Sep 26, 2014 at 8:22 AM, Stanislaw Gruszka <sgruszka-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On Thu, Sep 25, 2014 at 01:52:43PM -0400, nick wrote:
>> I seem to be hitting to fix mes in the file I listed in the subject. Would someone tell me if it's Ok to remove
>> the lines that over write certain registers.
>
> No, as long you prove that they are not needed.
>
> Stanislaw
Sure Stanislw,
I will remove the lines as needed and send it a patch.
Nick
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next] bonding: make global bonding stats more reliable
From: Andy Gospodarek @ 2014-09-26 13:26 UTC (permalink / raw)
To: Nikolay Aleksandrov; +Cc: netdev, j.vosburgh, vfalico
In-Reply-To: <54252940.6070100@redhat.com>
On Fri, Sep 26, 2014 at 10:52:16AM +0200, Nikolay Aleksandrov wrote:
> On 25/09/14 15:16, Andy Gospodarek wrote:
> >As the code stands today, bonding stats are based simply on the stats
> >from the member interfaces. If a member was to be removed from a bond,
> >the stats would instantly drop. This would be confusing to an admin
> >would would suddonly see interface stats drop while traffic is still
> >flowing.
> >
> >In addition to preventing the stats drops mentioned above, new members
> >will now be added to the bond and only traffic received after the member
> >was added to the bond will be counted as part of bonding stats.
> >
> >Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> >---
> Hi Andy,
>
> > drivers/net/bonding/bond_main.c | 63 +++++++++++++++++++++++++++--------------
> > drivers/net/bonding/bonding.h | 3 ++
> > 2 files changed, 44 insertions(+), 22 deletions(-)
> >
> >diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> >index 5390475..4543c74 100644
> >--- a/drivers/net/bonding/bond_main.c
> >+++ b/drivers/net/bonding/bond_main.c
> >@@ -1149,11 +1149,19 @@ static struct slave *bond_alloc_slave(struct bonding *bond)
> > if (!slave)
> > return NULL;
> >
> >+ slave->slave_stats = kzalloc(sizeof(struct rtnl_link_stats64),
> >+ GFP_KERNEL);
> >+ if (!slave->slave_stats) {
> >+ kfree(slave);
> >+ return NULL;
> >+ }
> >+
> > if (BOND_MODE(bond) == BOND_MODE_8023AD) {
> > SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info),
> > GFP_KERNEL);
> > if (!SLAVE_AD_INFO(slave)) {
> > kfree(slave);
> >+ kfree(slave->slave_stats);
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Wrong order. 1. slave_stats, 2. slave.
Ah yes, thanks! Clearly I didn't test the error path.
>
> > return NULL;
> > }
> > }
> >@@ -1167,6 +1175,7 @@ static void bond_free_slave(struct slave *slave)
> > if (BOND_MODE(bond) == BOND_MODE_8023AD)
> > kfree(SLAVE_AD_INFO(slave));
> >
> >+ kfree(slave->slave_stats);
> > kfree(slave);
> > }
> >
> >@@ -1344,6 +1353,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
> > }
> >
> > slave_dev->priv_flags |= IFF_BONDING;
> >+ /* initialize slave stats */
> >+ dev_get_stats(new_slave->dev, new_slave->slave_stats);
> >
> > if (bond_is_lb(bond)) {
> > /* bond_alb_init_slave() must be called before all other stages since
> >@@ -3085,38 +3096,43 @@ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
> > struct list_head *iter;
> > struct slave *slave;
> >
> >- memset(stats, 0, sizeof(*stats));
> >+ memcpy(stats, bond->bond_stats, sizeof(*stats));
> >
> > bond_for_each_slave(bond, slave, iter) {
> > const struct rtnl_link_stats64 *sstats =
> > dev_get_stats(slave->dev, &temp);
> >+ struct rtnl_link_stats64 *pstats = slave->slave_stats;
> >+
> >+ stats->rx_packets += sstats->rx_packets - pstats->rx_packets;
> >+ stats->rx_bytes += sstats->rx_bytes - pstats->rx_bytes;
> >+ stats->rx_errors += sstats->rx_errors - pstats->rx_errors;
> >+ stats->rx_dropped += sstats->rx_dropped - pstats->rx_dropped;
> >
> >- stats->rx_packets += sstats->rx_packets;
> >- stats->rx_bytes += sstats->rx_bytes;
> >- stats->rx_errors += sstats->rx_errors;
> >- stats->rx_dropped += sstats->rx_dropped;
> >+ stats->tx_packets += sstats->tx_packets - pstats->tx_packets;;
> >+ stats->tx_bytes += sstats->tx_bytes - pstats->tx_bytes;
> >+ stats->tx_errors += sstats->tx_errors - pstats->tx_errors;
> >+ stats->tx_dropped += sstats->tx_dropped - pstats->tx_dropped;
> >
> >- stats->tx_packets += sstats->tx_packets;
> >- stats->tx_bytes += sstats->tx_bytes;
> >- stats->tx_errors += sstats->tx_errors;
> >- stats->tx_dropped += sstats->tx_dropped;
> >+ stats->multicast += sstats->multicast - pstats->multicast;
> >+ stats->collisions += sstats->collisions - pstats->collisions;
> >
> >- stats->multicast += sstats->multicast;
> >- stats->collisions += sstats->collisions;
> >+ stats->rx_length_errors += sstats->rx_length_errors - pstats->rx_length_errors;
> >+ stats->rx_over_errors += sstats->rx_over_errors - pstats->rx_over_errors;
> >+ stats->rx_crc_errors += sstats->rx_crc_errors - pstats->rx_crc_errors;
> >+ stats->rx_frame_errors += sstats->rx_frame_errors - pstats->rx_frame_errors;
> >+ stats->rx_fifo_errors += sstats->rx_fifo_errors - pstats->rx_fifo_errors;
> >+ stats->rx_missed_errors += sstats->rx_missed_errors - pstats->rx_missed_errors;
> >
> >- stats->rx_length_errors += sstats->rx_length_errors;
> >- stats->rx_over_errors += sstats->rx_over_errors;
> >- stats->rx_crc_errors += sstats->rx_crc_errors;
> >- stats->rx_frame_errors += sstats->rx_frame_errors;
> >- stats->rx_fifo_errors += sstats->rx_fifo_errors;
> >- stats->rx_missed_errors += sstats->rx_missed_errors;
> >+ stats->tx_aborted_errors += sstats->tx_aborted_errors - pstats->tx_aborted_errors;
> >+ stats->tx_carrier_errors += sstats->tx_carrier_errors - pstats->tx_carrier_errors;
> >+ stats->tx_fifo_errors += sstats->tx_fifo_errors - pstats->tx_fifo_errors;
> >+ stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors - pstats->tx_heartbeat_errors;
> >+ stats->tx_window_errors += sstats->tx_window_errors - pstats->tx_window_errors;
> >
> >- stats->tx_aborted_errors += sstats->tx_aborted_errors;
> >- stats->tx_carrier_errors += sstats->tx_carrier_errors;
> >- stats->tx_fifo_errors += sstats->tx_fifo_errors;
> >- stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors;
> >- stats->tx_window_errors += sstats->tx_window_errors;
> >+ /* save off the slave stats for the next run */
> >+ memcpy(pstats, sstats, sizeof(*sstats));
> > }
> >+ memcpy(bond->bond_stats, stats, sizeof(*stats));
> >
> > return stats;
> > }
> >@@ -4258,6 +4274,9 @@ static int bond_init(struct net_device *bond_dev)
> > bond_dev->addr_assign_type == NET_ADDR_PERM)
> > eth_hw_addr_random(bond_dev);
> >
> >+ /* initialize persistent stats for the bond */
> >+ bond->bond_stats = kzalloc(sizeof(struct rtnl_link_stats64),
> >+ GFP_ATOMIC);
> ^^^^^^^^^^^^^^^^^^^^^^^^
> I don't think this will get freed if the bond device is destroyed.
Another good catch. Thanks for the review. V2 incoming after some
testing.
>
> > return 0;
> > }
> >
> >diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
> >index 6140bf0..fe25265 100644
> >--- a/drivers/net/bonding/bonding.h
> >+++ b/drivers/net/bonding/bonding.h
> >@@ -24,6 +24,7 @@
> > #include <linux/inetdevice.h>
> > #include <linux/etherdevice.h>
> > #include <linux/reciprocal_div.h>
> >+#include <linux/if_link.h>
> >
> > #include "bond_3ad.h"
> > #include "bond_alb.h"
> >@@ -175,6 +176,7 @@ struct slave {
> > struct netpoll *np;
> > #endif
> > struct kobject kobj;
> >+ struct rtnl_link_stats64 *slave_stats;
> > };
> >
> > /*
> >@@ -224,6 +226,7 @@ struct bonding {
> > /* debugging support via debugfs */
> > struct dentry *debug_dir;
> > #endif /* CONFIG_DEBUG_FS */
> >+ struct rtnl_link_stats64 *bond_stats;
> > };
> >
> > #define bond_slave_get_rcu(dev) \
> >
>
^ permalink raw reply
* RE: [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: David Laight @ 2014-09-26 13:16 UTC (permalink / raw)
To: David Laight, 'Eric Dumazet', Tom Herbert
Cc: Jesper Dangaard Brouer, Linux Netdev List, David S. Miller,
Alexander Duyck, Toke Høiland-Jørgensen,
Florian Westphal, Jamal Hadi Salim, Dave Taht, John Fastabend,
Daniel Borkmann, Hannes Frederic Sowa
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1749E380@AcuExch.aculab.com>
From: David Laight
> From: Eric Dumazet
> > On Wed, 2014-09-24 at 19:12 -0700, Eric Dumazet wrote:
> ...
> > It turned out the problem I noticed was caused by compiler trying to be
> > smart, but involving a bad MESI transaction.
> >
> > 0.05 mov 0xc0(%rax),%edi // LOAD dql->num_queued
> > 0.48 mov %edx,0xc8(%rax) // STORE dql->last_obj_cnt = count
> > 58.23 add %edx,%edi
> > 0.58 cmp %edi,0xc4(%rax)
> > 0.76 mov %edi,0xc0(%rax) // STORE dql->num_queued += count
> > 0.72 js bd8
> >
> >
> > I get an incredible 10 % gain by making sure cpu wont get the cache line
> > in Shared mode.
>
> That is a stunning difference between requesting 'exclusive' access
> and upgrading 'shared' to exclusive.
> Stinks of a cpu bug?
>
> Or is the reported stall a side effect of waiting for the earlier
> 'cache line read' to complete in order to issue the 'upgrade to exclusive'.
> In which case gcc's instruction scheduler probably needs to be taught
> to schedule writes before reads.
Thinking further.
gcc is probably moving memory reads before writes under the assumption that
the cpu might stall waiting for the read to complete but that the write
can be buffered by the hardware.
That assumption is true for simple cpus (like the Nios2), but for x86 with
its multiple instructions in flight (etc) may make little difference if
the memory is in the cache.
OTOH it looks as though there is a big hit if you read then write
a non-present cache line.
(This may even depend on which instructions get executed in parallel,
minor changes to the code could easily change that.)
I wonder how easy it would be to modify gcc to remove (or even reverse)
that memory ordering 'optimisation'.
David
^ permalink raw reply
* [RFC] fclone layout suboptimal
From: Eric Dumazet @ 2014-09-26 13:07 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Fast clones have following layout :
[sk_buff 1]
[sk_buff 2]
[atomic_t fclone_ref]
Main consumer is TCP stack for its write queue.
When tcp_ack()/tcp_clean_rtx_queue() frees skb,
kfree_skbmem() needs to fetch a cold cache line :
0.72 │ je b0
│6f: add $0x8,%rsp
│ pop %rbx
0.07 │ pop %rbp
│ retq
│ nop
0.52 │80: lock decl 0x1b0(%rbx)
90.23 │ ┌──je 90
│ │ jmp 6f
│ │ nop
│90:└─ mov 0x5c4e29(%rip),%rdi
│ mov %rbx,%rsi
│ callq kmem_cache_free
1.37 │ add $0x8,%rsp
│ pop %rbx
│ pop %rbp
0.91 │ retq
│ nop
│b0: mov 0x5c4e09(%rip),%rdi
│ lea -0xd8(%rbx),%rsi
│ callq kmem_cache_free
It might be better to have :
[sk_buff skb1]
[atomic_t fclone_ref]
[sk_buff skb2]
__alloc(skb) would not have to dirty a cache line to perform the
atomic_set(fclone_ref, 1);
kfree_skbmem() would do the atomic_dec_and_test() on a hot cache line
(Because we had access to skb_shinfo() a bit earlier while doing
skb_release_all()
When TX completions has to free the cloned sk_buff, fetching fclone_ref
would use an already hot cache line as well (skb2->next / skb2->sk are
already in cpu cache)
^ permalink raw reply
* Re: [PATCH net-next v3] tcp: use tcp_flags in tcp_data_queue()
From: Eric Dumazet @ 2014-09-26 12:38 UTC (permalink / raw)
To: Weiping Pan; +Cc: netdev, edumazet
In-Reply-To: <ba777860fdfc42d53ecd35bdac5d81ca5a9872eb.1411568111.git.panweiping3@gmail.com>
On Wed, 2014-09-24 at 22:17 +0800, Weiping Pan wrote:
> This patch is a cleanup which follows the idea in commit e11ecddf5128 (tcp: use
> TCP_SKB_CB(skb)->tcp_flags in input path),
> and it may reduce register pressure since skb->cb[] access is fast,
> bacause skb is probably in a register.
>
> v2: remove variable th
> v3: reword the changelog
>
> Signed-off-by: Weiping Pan <panweiping3@gmail.com>
> ---
Acked-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* Re: [PATCH net-next 2/3] ipv6: mld: do not overwrite uri when receiving an mldv2 query
From: Daniel Borkmann @ 2014-09-26 12:23 UTC (permalink / raw)
To: David L Stevens; +Cc: davem, hannes, netdev
In-Reply-To: <54255875.20409@oracle.com>
On 09/26/2014 02:13 PM, David L Stevens wrote:
> On 09/26/2014 05:29 AM, Daniel Borkmann wrote:
>> On 09/26/2014 01:23 AM, David L Stevens wrote:
>
>> I'm fine with either suggestion. Actually the _current_ situation we're in is
>> that in IPv4 we _always_ use the current, uncached _sysctl_ tuned setting of URI
>> (independent of any protocol version); while in IPv6 we use the _cached_ sysctl
>> URI in case of MLDv1 and _always_ overwrite the URI in case of MLDv2 (even for
>> MLDv1). Are you suggesting that, we then better adapt using the maxdelay value
>> everywhere and adapt URI to it, plus having a boolean knob defaulting to off for
>> an admin to enforce always using the provided sysctl default setting and not
>> the snooped MLD?
>
> Yes.
>
> Definitely, IGMP and MLD, all versions, should do the same thing and I think that
> ought to use the querier MRC, if present and not overridden by an admin.
>
> Further, I think a version switch or failure to hear from a querier for qrv*qi
> ought to reset everything.
I'll recook the patch set and keep you in the loop. Thanks David!
Best,
Daniel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox