Netdev List
 help / color / mirror / Atom feed
* [PATCH RFC 6/7] net: phy: remove the indirect MMD read/write methods
From: Russell King @ 2017-01-13 15:22 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Microchip Linux Driver Support,
	netdev-u79uwXL29TY76Z2rM5mHXA, Woojung Huh,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170113152059.GR14217-l+eeeJia6m9URfEZ8mYm6t73F7V6hmMc@public.gmane.org>

Remove the indirect MMD read/write methods which are now no longer
necessary.

Signed-off-by: Russell King <rmk+kernel-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
---
 drivers/net/phy/phy-core.c | 119 +++++++++++++--------------------------------
 include/linux/phy.h        |  18 -------
 2 files changed, 35 insertions(+), 102 deletions(-)

diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index b50b3a64cf6a..80795ccd3fab 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -23,102 +23,41 @@ static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
 }
 
 /**
- * phy_read_mmd_indirect - reads data from the MMD registers
- * @phydev: The PHY device bus
- * @prtad: MMD Address
- * @devad: MMD DEVAD
- *
- * Description: it reads data from the MMD registers (clause 22 to access to
- * clause 45) of the specified phy address.
- * To read these register we have:
- * 1) Write reg 13 // DEVAD
- * 2) Write reg 14 // MMD Address
- * 3) Write reg 13 // MMD Data Command for MMD DEVAD
- * 3) Read  reg 14 // Read MMD data
- */
-int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad)
-{
-	struct phy_driver *phydrv = phydev->drv;
-	int addr = phydev->mdio.addr;
-	int value = -1;
-
-	if (!phydrv->read_mmd_indirect) {
-		struct mii_bus *bus = phydev->mdio.bus;
-
-		mutex_lock(&bus->mdio_lock);
-		mmd_phy_indirect(bus, prtad, devad, addr);
-
-		/* Read the content of the MMD's selected register */
-		value = bus->read(bus, addr, MII_MMD_DATA);
-		mutex_unlock(&bus->mdio_lock);
-	} else {
-		value = phydrv->read_mmd_indirect(phydev, prtad, devad, addr);
-	}
-	return value;
-}
-EXPORT_SYMBOL(phy_read_mmd_indirect);
-
-/**
  * phy_read_mmd - Convenience function for reading a register
  * from an MMD on a given PHY.
  * @phydev: The phy_device struct
- * @devad: The MMD to read from
- * @regnum: The register on the MMD to read
+ * @devad: The MMD to read from (0..31)
+ * @regnum: The register on the MMD to read (0..65535)
  *
  * Same rules as for phy_read();
  */
 int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
 {
+	int val;
+
 	if (regnum > (u16)~0 || devad > 32)
 		return -EINVAL;
 
-	if (phydev->drv->read_mmd)
-		return phydev->drv->read_mmd(phydev, devad, regnum);
-
-	if (phydev->is_c45) {
+	if (phydev->drv->read_mmd) {
+		val = phydev->drv->read_mmd(phydev, devad, regnum);
+	} else if (phydev->is_c45) {
 		u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
-		return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
-	}
-
-	return phy_read_mmd_indirect(phydev, regnum, devad);
-}
-EXPORT_SYMBOL(phy_read_mmd);
-
-/**
- * phy_write_mmd_indirect - writes data to the MMD registers
- * @phydev: The PHY device
- * @prtad: MMD Address
- * @devad: MMD DEVAD
- * @data: data to write in the MMD register
- *
- * Description: Write data from the MMD registers of the specified
- * phy address.
- * To write these register we have:
- * 1) Write reg 13 // DEVAD
- * 2) Write reg 14 // MMD Address
- * 3) Write reg 13 // MMD Data Command for MMD DEVAD
- * 3) Write reg 14 // Write MMD data
- */
-void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
-				   int devad, u32 data)
-{
-	struct phy_driver *phydrv = phydev->drv;
-	int addr = phydev->mdio.addr;
 
-	if (!phydrv->write_mmd_indirect) {
+		val = mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
+	} else {
 		struct mii_bus *bus = phydev->mdio.bus;
+		int phy_addr = phydev->mdio.addr;
 
 		mutex_lock(&bus->mdio_lock);
-		mmd_phy_indirect(bus, prtad, devad, addr);
+		mmd_phy_indirect(bus, regnum, devad, phy_addr);
 
-		/* Write the data into MMD's selected register */
-		bus->write(bus, addr, MII_MMD_DATA, data);
+		/* Read the content of the MMD's selected register */
+		val = bus->read(bus, phy_addr, MII_MMD_DATA);
 		mutex_unlock(&bus->mdio_lock);
-	} else {
-		phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data);
 	}
+	return val;
 }
-EXPORT_SYMBOL(phy_write_mmd_indirect);
+EXPORT_SYMBOL(phy_read_mmd);
 
 /**
  * phy_write_mmd - Convenience function for writing a register
@@ -132,19 +71,31 @@ EXPORT_SYMBOL(phy_write_mmd_indirect);
  */
 int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
 {
+	int ret;
+
 	if (regnum > (u16)~0 || devad > 32)
 		return -EINVAL;
 
-	if (phydev->drv->read_mmd)
-		return phydev->drv->write_mmd(phydev, devad, regnum, val);
-
-	if (phydev->is_c45) {
+	if (phydev->drv->read_mmd) {
+		ret = phydev->drv->write_mmd(phydev, devad, regnum, val);
+	} else if (phydev->is_c45) {
 		u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
 
-		return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
-				     addr, val);
-	}
+		ret = mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
+				    addr, val);
+	} else {
+		struct mii_bus *bus = phydev->mdio.bus;
+		int phy_addr = phydev->mdio.addr;
 
-	return phy_write_mmd_indirect(phydev, regnum, devad, val);
+		mutex_lock(&bus->mdio_lock);
+		mmd_phy_indirect(bus, regnum, devad, phy_addr);
+
+		/* Write the data into MMD's selected register */
+		bus->write(bus, phy_addr, MII_MMD_DATA, val);
+		mutex_unlock(&bus->mdio_lock);
+
+		ret = 0;
+	}
+	return ret;
 }
 EXPORT_SYMBOL(phy_write_mmd);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 54fa76efb096..ebd1c55f1624 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -607,24 +607,6 @@ struct phy_driver {
 	int (*write_mmd)(struct phy_device *dev, int devnum, u16 regnum,
 			 u16 val);
 
-	/* A function provided by a phy specific driver to override the
-	 * the PHY driver framework support for reading a MMD register
-	 * from the PHY. If not supported, return -1. This function is
-	 * optional for PHY specific drivers, if not provided then the
-	 * default MMD read function is used by the PHY framework.
-	 */
-	int (*read_mmd_indirect)(struct phy_device *dev, int ptrad,
-				 int devnum, int regnum);
-
-	/* A function provided by a phy specific driver to override the
-	 * the PHY driver framework support for writing a MMD register
-	 * from the PHY. This function is optional for PHY specific drivers,
-	 * if not provided then the default MMD read function is used by
-	 * the PHY framework.
-	 */
-	void (*write_mmd_indirect)(struct phy_device *dev, int ptrad,
-				   int devnum, int regnum, u32 val);

^ permalink raw reply related

* [PATCH RFC 2/7] net: phy: make phy_(read|write)_mmd() generic MMD accessors
From: Russell King @ 2017-01-13 15:21 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Microchip Linux Driver Support,
	netdev-u79uwXL29TY76Z2rM5mHXA, Woojung Huh,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170113152059.GR14217-l+eeeJia6m9URfEZ8mYm6t73F7V6hmMc@public.gmane.org>

Make phy_(read|write)_mmd() generic 802.3 clause 45 register accessors
for both Clause 22 and Clause 45 PHYs, using either the direct register
reading for Clause 45, or the indirect method for Clause 22 PHYs.
Allow this behaviour to be overriden by PHY drivers where necessary.

Signed-off-by: Russell King <rmk+kernel-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
---
 drivers/net/phy/phy-core.c | 31 +++++++++++++++++++++++--------
 include/linux/phy.h        | 24 ++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index b8d8276a3099..b50b3a64cf6a 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -69,11 +69,18 @@ EXPORT_SYMBOL(phy_read_mmd_indirect);
  */
 int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
 {
-	if (!phydev->is_c45)
-		return -EOPNOTSUPP;
+	if (regnum > (u16)~0 || devad > 32)
+		return -EINVAL;
 
-	return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
-			    MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff));
+	if (phydev->drv->read_mmd)
+		return phydev->drv->read_mmd(phydev, devad, regnum);
+
+	if (phydev->is_c45) {
+		u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
+		return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
+	}
+
+	return phy_read_mmd_indirect(phydev, regnum, devad);
 }
 EXPORT_SYMBOL(phy_read_mmd);
 
@@ -125,11 +132,19 @@ EXPORT_SYMBOL(phy_write_mmd_indirect);
  */
 int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
 {
-	if (!phydev->is_c45)
-		return -EOPNOTSUPP;
+	if (regnum > (u16)~0 || devad > 32)
+		return -EINVAL;
 
-	regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff);
+	if (phydev->drv->read_mmd)
+		return phydev->drv->write_mmd(phydev, devad, regnum, val);
+
+	if (phydev->is_c45) {
+		u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
+
+		return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
+				     addr, val);
+	}
 
-	return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
+	return phy_write_mmd_indirect(phydev, regnum, devad, val);
 }
 EXPORT_SYMBOL(phy_write_mmd);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 72acb0233b5f..54fa76efb096 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -583,6 +583,30 @@ struct phy_driver {
 	 */
 	void (*link_change_notify)(struct phy_device *dev);
 
+	/*
+	 * Phy specific driver override for reading a MMD register.
+	 * This function is optional for PHY specific drivers.  When
+	 * not provided, the default MMD read function will be used
+	 * by phy_read_mmd(), which will use either a direct read for
+	 * Clause 45 PHYs or an indirect read for Clause 22 PHYs.
+	 *  devnum is the MMD device number within the PHY device,
+	 *  regnum is the register within the selected MMD device.
+	 */
+	int (*read_mmd)(struct phy_device *dev, int devnum, u16 regnum);
+
+	/*
+	 * Phy specific driver override for writing a MMD register.
+	 * This function is optional for PHY specific drivers.  When
+	 * not provided, the default MMD write function will be used
+	 * by phy_write_mmd(), which will use either a direct write for
+	 * Clause 45 PHYs, or an indirect write for Clause 22 PHYs.
+	 *  devnum is the MMD device number within the PHY device,
+	 *  regnum is the register within the selected MMD device.
+	 *  val is the value to be written.
+	 */
+	int (*write_mmd)(struct phy_device *dev, int devnum, u16 regnum,
+			 u16 val);
+
 	/* A function provided by a phy specific driver to override the
 	 * the PHY driver framework support for reading a MMD register
 	 * from the PHY. If not supported, return -1. This function is
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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 related

* [PATCH RFC 1/7] net: phy: move phy MMD accessors to phy-core.c
From: Russell King @ 2017-01-13 15:21 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Microchip Linux Driver Support,
	netdev-u79uwXL29TY76Z2rM5mHXA, Woojung Huh,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170113152059.GR14217-l+eeeJia6m9URfEZ8mYm6t73F7V6hmMc@public.gmane.org>

Move the phy_(read|write)__mmd() helpers out of line, they will become
our main MMD accessor functions, and so will be a little more complex.
This complexity doesn't belong in an inline function.  Also move the
_indirect variants as well to keep like functionality together.

Signed-off-by: Russell King <rmk+kernel-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
---
 drivers/net/phy/Makefile   |   3 +-
 drivers/net/phy/phy-core.c | 135 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/phy/phy.c      |  85 ----------------------------
 include/linux/phy.h        |  20 +------
 4 files changed, 139 insertions(+), 104 deletions(-)
 create mode 100644 drivers/net/phy/phy-core.c

diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 356859ac7c18..06fa2e04ac7e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -1,6 +1,7 @@
 # Makefile for Linux PHY drivers and MDIO bus drivers
 
-libphy-y			:= phy.o phy_device.o mdio_bus.o mdio_device.o
+libphy-y			:= phy.o phy_device.o mdio_bus.o mdio_device.o \
+				   phy-core.o
 libphy-$(CONFIG_SWPHY)		+= swphy.o
 libphy-$(CONFIG_LED_TRIGGER_PHY)	+= phy_led_triggers.o
 
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
new file mode 100644
index 000000000000..b8d8276a3099
--- /dev/null
+++ b/drivers/net/phy/phy-core.c
@@ -0,0 +1,135 @@
+/*
+ * Core PHY library, taken from phy.c
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/export.h>
+#include <linux/phy.h>
+
+static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
+				    int addr)
+{
+	/* Write the desired MMD Devad */
+	bus->write(bus, addr, MII_MMD_CTRL, devad);
+
+	/* Write the desired MMD register address */
+	bus->write(bus, addr, MII_MMD_DATA, prtad);
+
+	/* Select the Function : DATA with no post increment */
+	bus->write(bus, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
+}
+
+/**
+ * phy_read_mmd_indirect - reads data from the MMD registers
+ * @phydev: The PHY device bus
+ * @prtad: MMD Address
+ * @devad: MMD DEVAD
+ *
+ * Description: it reads data from the MMD registers (clause 22 to access to
+ * clause 45) of the specified phy address.
+ * To read these register we have:
+ * 1) Write reg 13 // DEVAD
+ * 2) Write reg 14 // MMD Address
+ * 3) Write reg 13 // MMD Data Command for MMD DEVAD
+ * 3) Read  reg 14 // Read MMD data
+ */
+int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad)
+{
+	struct phy_driver *phydrv = phydev->drv;
+	int addr = phydev->mdio.addr;
+	int value = -1;
+
+	if (!phydrv->read_mmd_indirect) {
+		struct mii_bus *bus = phydev->mdio.bus;
+
+		mutex_lock(&bus->mdio_lock);
+		mmd_phy_indirect(bus, prtad, devad, addr);
+
+		/* Read the content of the MMD's selected register */
+		value = bus->read(bus, addr, MII_MMD_DATA);
+		mutex_unlock(&bus->mdio_lock);
+	} else {
+		value = phydrv->read_mmd_indirect(phydev, prtad, devad, addr);
+	}
+	return value;
+}
+EXPORT_SYMBOL(phy_read_mmd_indirect);
+
+/**
+ * phy_read_mmd - Convenience function for reading a register
+ * from an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to read from
+ * @regnum: The register on the MMD to read
+ *
+ * Same rules as for phy_read();
+ */
+int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
+{
+	if (!phydev->is_c45)
+		return -EOPNOTSUPP;
+
+	return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
+			    MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff));
+}
+EXPORT_SYMBOL(phy_read_mmd);
+
+/**
+ * phy_write_mmd_indirect - writes data to the MMD registers
+ * @phydev: The PHY device
+ * @prtad: MMD Address
+ * @devad: MMD DEVAD
+ * @data: data to write in the MMD register
+ *
+ * Description: Write data from the MMD registers of the specified
+ * phy address.
+ * To write these register we have:
+ * 1) Write reg 13 // DEVAD
+ * 2) Write reg 14 // MMD Address
+ * 3) Write reg 13 // MMD Data Command for MMD DEVAD
+ * 3) Write reg 14 // Write MMD data
+ */
+void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
+				   int devad, u32 data)
+{
+	struct phy_driver *phydrv = phydev->drv;
+	int addr = phydev->mdio.addr;
+
+	if (!phydrv->write_mmd_indirect) {
+		struct mii_bus *bus = phydev->mdio.bus;
+
+		mutex_lock(&bus->mdio_lock);
+		mmd_phy_indirect(bus, prtad, devad, addr);
+
+		/* Write the data into MMD's selected register */
+		bus->write(bus, addr, MII_MMD_DATA, data);
+		mutex_unlock(&bus->mdio_lock);
+	} else {
+		phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data);
+	}
+}
+EXPORT_SYMBOL(phy_write_mmd_indirect);
+
+/**
+ * phy_write_mmd - Convenience function for writing a register
+ * on an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to read from
+ * @regnum: The register on the MMD to read
+ * @val: value to write to @regnum
+ *
+ * Same rules as for phy_write();
+ */
+int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
+{
+	if (!phydev->is_c45)
+		return -EOPNOTSUPP;
+
+	regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff);
+
+	return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
+}
+EXPORT_SYMBOL(phy_write_mmd);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 25f93a98863b..c6022b66f81d 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1175,91 +1175,6 @@ void phy_mac_interrupt(struct phy_device *phydev, int new_link)
 }
 EXPORT_SYMBOL(phy_mac_interrupt);
 
-static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
-				    int addr)
-{
-	/* Write the desired MMD Devad */
-	bus->write(bus, addr, MII_MMD_CTRL, devad);
-
-	/* Write the desired MMD register address */
-	bus->write(bus, addr, MII_MMD_DATA, prtad);
-
-	/* Select the Function : DATA with no post increment */
-	bus->write(bus, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
-}
-
-/**
- * phy_read_mmd_indirect - reads data from the MMD registers
- * @phydev: The PHY device bus
- * @prtad: MMD Address
- * @devad: MMD DEVAD
- *
- * Description: it reads data from the MMD registers (clause 22 to access to
- * clause 45) of the specified phy address.
- * To read these register we have:
- * 1) Write reg 13 // DEVAD
- * 2) Write reg 14 // MMD Address
- * 3) Write reg 13 // MMD Data Command for MMD DEVAD
- * 3) Read  reg 14 // Read MMD data
- */
-int phy_read_mmd_indirect(struct phy_device *phydev, int prtad, int devad)
-{
-	struct phy_driver *phydrv = phydev->drv;
-	int addr = phydev->mdio.addr;
-	int value = -1;
-
-	if (!phydrv->read_mmd_indirect) {
-		struct mii_bus *bus = phydev->mdio.bus;
-
-		mutex_lock(&bus->mdio_lock);
-		mmd_phy_indirect(bus, prtad, devad, addr);
-
-		/* Read the content of the MMD's selected register */
-		value = bus->read(bus, addr, MII_MMD_DATA);
-		mutex_unlock(&bus->mdio_lock);
-	} else {
-		value = phydrv->read_mmd_indirect(phydev, prtad, devad, addr);
-	}
-	return value;
-}
-EXPORT_SYMBOL(phy_read_mmd_indirect);
-
-/**
- * phy_write_mmd_indirect - writes data to the MMD registers
- * @phydev: The PHY device
- * @prtad: MMD Address
- * @devad: MMD DEVAD
- * @data: data to write in the MMD register
- *
- * Description: Write data from the MMD registers of the specified
- * phy address.
- * To write these register we have:
- * 1) Write reg 13 // DEVAD
- * 2) Write reg 14 // MMD Address
- * 3) Write reg 13 // MMD Data Command for MMD DEVAD
- * 3) Write reg 14 // Write MMD data
- */
-void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
-				   int devad, u32 data)
-{
-	struct phy_driver *phydrv = phydev->drv;
-	int addr = phydev->mdio.addr;
-
-	if (!phydrv->write_mmd_indirect) {
-		struct mii_bus *bus = phydev->mdio.bus;
-
-		mutex_lock(&bus->mdio_lock);
-		mmd_phy_indirect(bus, prtad, devad, addr);
-
-		/* Write the data into MMD's selected register */
-		bus->write(bus, addr, MII_MMD_DATA, data);
-		mutex_unlock(&bus->mdio_lock);
-	} else {
-		phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data);
-	}
-}
-EXPORT_SYMBOL(phy_write_mmd_indirect);
-
 /**
  * phy_init_eee - init and check the EEE feature
  * @phydev: target phy_device struct
diff --git a/include/linux/phy.h b/include/linux/phy.h
index f7d95f644eed..72acb0233b5f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -647,14 +647,7 @@ struct phy_fixup {
  *
  * Same rules as for phy_read();
  */
-static inline int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
-{
-	if (!phydev->is_c45)
-		return -EOPNOTSUPP;
-
-	return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
-			    MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff));
-}
+int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
 
 /**
  * phy_read_mmd_indirect - reads data from the MMD registers
@@ -748,16 +741,7 @@ static inline bool phy_is_pseudo_fixed_link(struct phy_device *phydev)
  *
  * Same rules as for phy_write();
  */
-static inline int phy_write_mmd(struct phy_device *phydev, int devad,
-				u32 regnum, u16 val)
-{
-	if (!phydev->is_c45)
-		return -EOPNOTSUPP;
-
-	regnum = MII_ADDR_C45 | ((devad & 0x1f) << 16) | (regnum & 0xffff);

^ permalink raw reply related

* [PATCH RFC 0/7] Clean up PHY MMD accessors
From: Russell King - ARM Linux @ 2017-01-13 15:20 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Woojung Huh, netdev, linux-usb, linux-arm-kernel,
	Microchip Linux Driver Support

This series cleans up phylib's MMD accessors, so that we have a common
way of accessing the Clause 45 register set.

The current situation is far from ideal - we have phy_(read|write)_mmd()
which accesses Clause 45 registers over Clause 45 accesses, and we have
phy_(read|write)_mmd_indirect(), which accesses Clause 45 registers via
Clause 22 register 13/14.

Generic code uses the indirect methods to access standard Clause 45
features, and when we come to add Clause 45 PHY support to phylib, we
would need to make these conditional upon the PHY type, or duplicate
these functions.

An alternative solution is to merge these accessors together, and select
the appropriate access method depending upon the 802.3 clause that the
PHY conforms with.  The result is that we have a single set of
phy_(read|write)_mmd() accessors.

For cases which require special handling, we still allow PHY drivers to
override all MMD accesses - except rather than just overriding the
indirect accesses.  This keeps existing overrides working.

Combining the two also has another beneficial side effect - we get rid
of similar functions that take arguments in different orders.  The
old direct accessors took the phy structure, devad and register number,
whereas the indirect accessors took the phy structure, register number
and devad in that order.  Care must be taken when updating future
drivers that the argument order is correct, and the function name is
not merely replaced.

This patch set is against 4.10-rc3 at present.

 drivers/net/phy/Makefile      |   3 +-
 drivers/net/phy/bcm-phy-lib.c |  12 ++---
 drivers/net/phy/dp83867.c     |  18 +++----
 drivers/net/phy/intel-xway.c  |  26 +++++-----
 drivers/net/phy/micrel.c      |  13 +++--
 drivers/net/phy/microchip.c   |   5 +-
 drivers/net/phy/phy-core.c    | 101 ++++++++++++++++++++++++++++++++++++++
 drivers/net/phy/phy.c         | 110 ++++--------------------------------------
 drivers/net/phy/phy_device.c  |   4 +-
 drivers/net/usb/lan78xx.c     |  10 ++--
 include/linux/phy.h           |  56 +++++++++------------
 11 files changed, 176 insertions(+), 182 deletions(-)
 create mode 100644 drivers/net/phy/phy-core.c

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply

* Re: [PATCH V2] audit: log 32-bit socketcalls
From: Richard Guy Briggs @ 2017-01-13 15:20 UTC (permalink / raw)
  To: Eric Paris
  Cc: netdev, linux-kernel, linux-audit, Kangkook Jee, Paul Moore,
	Steve Grubb
In-Reply-To: <1484320702.5300.8.camel@redhat.com>

On 2017-01-13 10:18, Eric Paris wrote:
> On Fri, 2017-01-13 at 10:06 -0500, Richard Guy Briggs wrote:
> > On 2017-01-13 09:42, Eric Paris wrote:
> > > On Fri, 2017-01-13 at 04:51 -0500, Richard Guy Briggs wrote:
> 
> 
> > > > diff --git a/include/linux/audit.h b/include/linux/audit.h
> > > > index 9d4443f..43d8003 100644
> > > > --- a/include/linux/audit.h
> > > > +++ b/include/linux/audit.h
> > > > @@ -387,6 +387,18 @@ static inline int audit_socketcall(int
> > > > nargs,
> > > > unsigned long *args)
> > > >  		return __audit_socketcall(nargs, args);
> > > >  	return 0;
> > > >  }
> > > > +static inline int audit_socketcall_compat(int nargs, u32 *args)
> > > > +{
> > > > +	if (unlikely(!audit_dummy_context())) {
> > > 
> > > I've always hated these likely/unlikely. Mostly because I think
> > > they
> > > are so often wrong. I believe this says that you compiled audit in
> > > but
> > > you expect it to be explicitly disabled. While that is (recently)
> > > true
> > > in Fedora I highly doubt that's true on the vast majority of
> > > systems
> > > that have audit compiled in.
> > 
> > It has been argued that audit should have pretty much no performance
> > impact if it is not in use and that if it is, we're willing to take
> > the
> > more significant overhead of the rest of the code for the sake of one
> > test to determine whether or not to follow this code path.
> 
> Ok, I can buy that argument. Not sure its where I would have settled,
> but it does make sense. I'll obviously defer to Paul on what he wants
> out of style. I always assume the compiler is brilliant and write
> stupid code but your logic is sound there too.
> 
> You can/should pretend I said nothing.

You're keeping me honest and making me work for my dinner!  ;-)

- RGB

^ permalink raw reply

* [PATCH net-next] mii_bus: increase MII_BUS_ID_SIZE to 61
From: Volodymyr Bendiuga @ 2017-01-13 15:19 UTC (permalink / raw)
  To: f.fainelli, netdev, volodymyr.bendiuga; +Cc: Magnus Öberg

From: Volodymyr Bendiuga <volodymyr.bendiuga@westermo.se>

Some bus names are pretty long and do not fit into 20 chars.

Signed-off-by: Volodymyr Bendiuga <volodymyr.bendiuga@westermo.se>
Signed-off-by: Magnus Öberg <magnus.oberg@westermo.se>
---
 include/linux/phy.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/phy.h b/include/linux/phy.h
index feb8a98..b67f94d 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -162,7 +162,7 @@ static inline const char *phy_modes(phy_interface_t interface)
  * Need to be a little smaller than phydev->dev.bus_id to leave room
  * for the ":%02x"
  */
-#define MII_BUS_ID_SIZE	(20 - 3)
+#define MII_BUS_ID_SIZE	(64 - 3)
 
 /* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
    IEEE 802.3ae clause 45 addressing mode used by 10GIGE phy chips. */
-- 
2.7.4

^ permalink raw reply related

* Re: Setting link down or up in software
From: Mason @ 2017-01-13 15:17 UTC (permalink / raw)
  To: Zefir Kurtisi, netdev
  Cc: Mans Rullgard, Florian Fainelli, Andrew Lunn, Thibaud Cornic
In-Reply-To: <0273a4ad-46f7-d7b9-a206-6bd713e6165e@neratec.com>

On 13/01/2017 10:20, Zefir Kurtisi wrote:
> On 01/12/2017 04:16 PM, Mason wrote:
>> On 12/01/2017 14:05, Mason wrote:
>>
>>> I'm wondering what are the semantics of calling
>>>
>>> 	ip link set dev eth0 down
>>>
>>> I was expecting that to somehow instruct the device's ethernet driver
>>> to shut everything down, have the PHY tell the peer that it's going
>>> away, maybe even put the PHY in some low-power mode, etc.
>>>
>>> But it doesn't seem to be doing any of that on my HW.
>>>
>>> So what exactly is it supposed to do?
>>>
>>>
>>> And on top of that, I am seeing random occurrences of
>>>
>>> 	nb8800 26000.ethernet eth0: Link is Down
>>>
>>> Sometimes it is printed immediately.
>>> Sometimes it is printed as soon as I run "ip link set dev eth0 up" (?!)
>>> Sometimes it is not printed at all.
>>>
>>> I find this erratic behavior very confusing.
>>>
>>> Is it the symptom of some deeper bug?
>>
>> Here's an example of "Link is Down" printed when I set link up:
>>
>> At [   62.750220] I run ip link set dev eth0 down
>> Then leave the system idle for 10 minutes.
>> At [  646.263041] I run ip link set dev eth0 up
>> At [  647.364079] it prints "Link is Down"
>> At [  649.417434] it prints "Link is Up - 1Gbps/Full - flow control rx/tx"
>>
>> I think whether I set up the PHY to use interrupts or polling
>> does have an influence on the weirdness I observe.
>>
>> AFAICT, changing the interface flags is done in dev_change_flags
>> which calls __dev_change_flags and __dev_notify_flags
>>
>> Is one of these supposed to call the device driver through a
>> callback at some point?
>>
>> How/when is the phy_state_machine notified of the change in
>> interface flags?
>>
>> Regards.
>>
> Hm, reminds me of something at my side that I recently fixed with [1]. For me it
> was pulling the cable got randomly unnoticed at PHY layer - but might be related.
> 
> Do you by chance have some component that polls the link states over the ethtool
> interface very often (like once per second)? At my side it was a snmpd agent that
> pro-actively updated the interface states every second and with that 'stole' the
> link change information from the phy link state machine. What you need to have to
> run in such a failing situation is:
> 1) an ETH driver that updates link status in ethtool GSET path (e.g. dsa does)
> 2) some component that continuously polls states via ethtool GSET
> 
> 
> Cheers,
> Zefir
> 
> 
> [1] https://patchwork.ozlabs.org/patch/711839/

Hello Zefir,

Thanks for the insightful comment.

This is a minimal buildroot system, with no frills, and not much running.
There definitely is no SNMP daemon running, but I can't be 100% sure that
busybox isn't polling the link state once in a while. (It's unlikely.)

I'm surprised that there are still bugs lurking in the phy state machine,
I expected this to be a "solved problem", but I suppose power management
has broken many assumptions that were once safe...

By the way, I did come across code paths where phy->state was read or
written without taking the lock. Isn't that never supposed to happen?

Regards.

^ permalink raw reply

* Re: [PATCH V2] audit: log 32-bit socketcalls
From: Eric Paris @ 2017-01-13 15:18 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: netdev, linux-kernel, linux-audit, Kangkook Jee, Paul Moore,
	Steve Grubb
In-Reply-To: <20170113150637.GB3087@madcap2.tricolour.ca>

On Fri, 2017-01-13 at 10:06 -0500, Richard Guy Briggs wrote:
> On 2017-01-13 09:42, Eric Paris wrote:
> > On Fri, 2017-01-13 at 04:51 -0500, Richard Guy Briggs wrote:


> > > diff --git a/include/linux/audit.h b/include/linux/audit.h
> > > index 9d4443f..43d8003 100644
> > > --- a/include/linux/audit.h
> > > +++ b/include/linux/audit.h
> > > @@ -387,6 +387,18 @@ static inline int audit_socketcall(int
> > > nargs,
> > > unsigned long *args)
> > >  		return __audit_socketcall(nargs, args);
> > >  	return 0;
> > >  }
> > > +static inline int audit_socketcall_compat(int nargs, u32 *args)
> > > +{
> > > +	if (unlikely(!audit_dummy_context())) {
> > 
> > I've always hated these likely/unlikely. Mostly because I think
> > they
> > are so often wrong. I believe this says that you compiled audit in
> > but
> > you expect it to be explicitly disabled. While that is (recently)
> > true
> > in Fedora I highly doubt that's true on the vast majority of
> > systems
> > that have audit compiled in.
> 
> It has been argued that audit should have pretty much no performance
> impact if it is not in use and that if it is, we're willing to take
> the
> more significant overhead of the rest of the code for the sake of one
> test to determine whether or not to follow this code path.

Ok, I can buy that argument. Not sure its where I would have settled,
but it does make sense. I'll obviously defer to Paul on what he wants
out of style. I always assume the compiler is brilliant and write
stupid code but your logic is sound there too.

You can/should pretend I said nothing.

^ permalink raw reply

* Re: [PATCH V2] audit: log 32-bit socketcalls
From: Richard Guy Briggs @ 2017-01-13 15:06 UTC (permalink / raw)
  To: Eric Paris
  Cc: netdev, linux-kernel, linux-audit, Kangkook Jee, Paul Moore,
	Steve Grubb
In-Reply-To: <1484318543.5300.1.camel@redhat.com>

On 2017-01-13 09:42, Eric Paris wrote:
> On Fri, 2017-01-13 at 04:51 -0500, Richard Guy Briggs wrote:
> > 32-bit socketcalls were not being logged by audit on x86_64 systems.
> > Log them.  This is basically a duplicate of the call from
> > net/socket.c:sys_socketcall(), but it addresses the impedance
> > mismatch
> > between 32-bit userspace process and 64-bit kernel audit.
> > 
> > See: https://github.com/linux-audit/audit-kernel/issues/14
> > 
> > Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> > 
> > --
> > v2:
> >    Move work to audit_socketcall_compat() and use
> > audit_dummy_context().
> > ---
> >  include/linux/audit.h |   16 ++++++++++++++++
> >  net/compat.c          |   15 +++++++++++++--
> >  2 files changed, 29 insertions(+), 2 deletions(-)
> > 
> > diff --git a/include/linux/audit.h b/include/linux/audit.h
> > index 9d4443f..43d8003 100644
> > --- a/include/linux/audit.h
> > +++ b/include/linux/audit.h
> > @@ -387,6 +387,18 @@ static inline int audit_socketcall(int nargs,
> > unsigned long *args)
> >  		return __audit_socketcall(nargs, args);
> >  	return 0;
> >  }
> > +static inline int audit_socketcall_compat(int nargs, u32 *args)
> > +{
> > +	if (unlikely(!audit_dummy_context())) {
> 
> I've always hated these likely/unlikely. Mostly because I think they
> are so often wrong. I believe this says that you compiled audit in but
> you expect it to be explicitly disabled. While that is (recently) true
> in Fedora I highly doubt that's true on the vast majority of systems
> that have audit compiled in.

It has been argued that audit should have pretty much no performance
impact if it is not in use and that if it is, we're willing to take the
more significant overhead of the rest of the code for the sake of one
test to determine whether or not to follow this code path.  The audit
subsystem isn't everyone's favourite baby so not making performance
worse for non-audit-users might help play nice in the community.  I did
contemplate Hanlon's Razor when wondering if this call had been left out
to avoid thunking complications or overhead.

In this case, compat users are less likely to raise a stink about
performance issues, so this situation is not particularly critical.

> I think all of the likely/unlikely need to just be abandoned, but at
> least don't add more? It certainly wouldn't be the first time I was
> wrong, and I haven't profiled it. But the function would definitely
> look better if coded

This is a seperate issue and I agree about simply bailing early rather
than putting the rest of the function in one conditional.  Given the
scoping though, the local variables aren't needed to be allocated in the
unlikely case, but I'm sure the compiler optimizer knows better than we
do how to make this go fast...

In both cases, I thought there was value in making
audit_socketcall_compat() as similar in logic to audit_socketcall() as
possible to make them easier to maintain.

Is either issue a cause for patch respin?  If so, I'll want to normalize
the two functions for consistency.

> static inline int audit_socketcall_compat(int nargs, u32 *args)
> {
>     if (audit_cummy_context()) {
>         return 0
>     }
>     int i;
>     unsigned long a[AUDITSC_ARGS];
> 
>     [...]
> }
> 
> > +		int i;
> > +		unsigned long a[AUDITSC_ARGS];
> > +
> > +		for (i=0; i<nargs; i++)
> > +			a[i] = (unsigned long)args[i];
> > +		return __audit_socketcall(nargs, a);
> > +	}
> > +	return 0;
> > +}
> >  static inline int audit_sockaddr(int len, void *addr)
> >  {
> >  	if (unlikely(!audit_dummy_context()))
> > @@ -513,6 +525,10 @@ static inline int audit_socketcall(int nargs,
> > unsigned long *args)
> >  {
> >  	return 0;
> >  }
> > +static inline int audit_socketcall_compat(int nargs, u32 *args)
> > +{
> > +	return 0;
> > +}
> >  static inline void audit_fd_pair(int fd1, int fd2)
> >  { }
> >  static inline int audit_sockaddr(int len, void *addr)
> > diff --git a/net/compat.c b/net/compat.c
> > index 1cd2ec0..f0404d4 100644
> > --- a/net/compat.c
> > +++ b/net/compat.c
> > @@ -22,6 +22,7 @@
> >  #include <linux/filter.h>
> >  #include <linux/compat.h>
> >  #include <linux/security.h>
> > +#include <linux/audit.h>
> >  #include <linux/export.h>
> >  
> >  #include <net/scm.h>
> > @@ -781,14 +782,24 @@ COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd,
> > struct compat_mmsghdr __user *, mmsg,
> >  
> >  COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
> >  {
> > +	unsigned int len;
> >  	int ret;
> > -	u32 a[6];
> > +	u32 a[AUDITSC_ARGS];
> >  	u32 a0, a1;
> >  
> >  	if (call < SYS_SOCKET || call > SYS_SENDMMSG)
> >  		return -EINVAL;
> > -	if (copy_from_user(a, args, nas[call]))
> > +	len = nas[call];
> > +	if (len > sizeof(a))
> > +		return -EINVAL;
> > +
> > +	if (copy_from_user(a, args, len))
> >  		return -EFAULT;
> > +
> > +	ret = audit_socketcall_compat(len/sizeof(a[0]), a);
> > +	if (ret)
> > +		return ret;
> > +
> >  	a0 = a[0];
> >  	a1 = a[1];
> >  

- RGB

--
Richard Guy Briggs <rgb@redhat.com>
Kernel Security Engineering, Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635

^ permalink raw reply

* Re: [PATCH] rtlwifi: rtl8192ee: New firmware from Realtek
From: Kyle McMartin @ 2017-01-13 15:03 UTC (permalink / raw)
  To: Larry Finger
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, Troy Tan,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-firmware-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <20161217185054.15017-1-Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>

On Sat, Dec 17, 2016 at 12:50:54PM -0600, Larry Finger wrote:
> -Info: Taken from Realtek version rtl_92ce_92se_92de_8723ae_88ee_8723be_92ee_linux_mac80211_0017.1224.2013
> +Info: Initial version taken from Realtek version
> +      rtl_92ce_92se_92de_8723ae_88ee_8723be_92ee_linux_mac80211_0017.1224.2013
> +      Updated Jan. 14, 2015 with file added by Realtek to
> +      http://github.com/lwfinger/rtlwifi_new.git.
>  File: rtlwifi/rtl8192eefw.bin
>  

Uh, did something weird happen here? This patch was applied in 2015. ;-)

cheers, Kyle

^ permalink raw reply

* resend: tcp: performance issue with fastopen connections (mss > window)
From: Alexey Kodanev @ 2017-01-13 15:01 UTC (permalink / raw)
  To: David Miller, Eric Dumazet; +Cc: netdev, Vasily Isaenko

Hi,

Got the issue when running LTP/netstress test on localhost with mss
greater than the send window advertised by client (right after 3WHS).
Here is the testscenario that can reproduce this:

TCP client is sending 32 bytes request, TCP server replies with 65KB answer.
net.ipv4.tcp_fastopen set to 3. Also notethat first TCP Fastopen connection
processed without delay as tcp_send_mss()setshalf of the window size
to the'size_goal' inside tcp_sendmsg().

Though on the 2nd and subsequent connections:

    < S  seq 0:0 win 43690 options [mss 65495 wscale 7
         tfo cookie ac6246a51d5422fc] length 32
    > S.seq 0:0ack 1win 43690 options [mss 65495wscale 7] length 0
    <.  ack 1 win 342 length 0

Inside tcp_sendmsg(), tcp_send_mss() returns 65483 in 'mss_now',as well as
in 'size_goal'. This results the segment not queued for transmition
until all
data copied from userbuffer. Then, inside  __tcp_push_pending_frames() it
breaks on send window test,continue with the check probe timer, thus
introducing 200ms delay here.

Fragmentationoccurs in tcp_write_wakeup()...

+0.2> P. seq 1:43777 ack 1 win 342 length 43776
     <  . ack 43777, win 1365 length 0
     > P. seq 43777:65001 ack 1 win 342 optionslength 21224
     ...


Not sure what is the right fix for this, I guess we could limit size_goal
to the current window or mss, what is currently less, e.g:

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4a04496..3d3bd97 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -860,7 +860,12 @@ static unsigned int tcp_xmit_size_goal(struct sock
*sk, u32 mss_now,
                size_goal = tp->gso_segs * mss_now;
        }

-       return max(size_goal, mss_now);
+       size_goal = max(size_goal, mss_now);
+
+       if (tp->snd_wnd > TCP_MSS_DEFAULT)
+               return min(tp->snd_wnd, size_goal);
+
+       return size_goal;
 }

 static int tcp_send_mss(struct sock *sk, int *size_goal, int flags)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 1d5331a..0ac133f 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2445,7 +2445,7 @@ void tcp_push_one(struct sock *sk, unsigned int
mss_now)
 {
        struct sk_buff *skb = tcp_send_head(sk);

-       BUG_ON(!skb || skb->len < mss_now);
+       BUG_ON(!skb);

        tcp_write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, sk->sk_allocation);
 }


Any ideas?

Best regards,
Alexey

^ permalink raw reply related

* Re: tcp: performance issue with fastopen connections (mss > window)
From: Alexey Kodanev @ 2017-01-13 14:58 UTC (permalink / raw)
  To: David Miller, Eric Dumazet; +Cc: netdev, Vasily Isaenko
In-Reply-To: <5878E166.8080800@oracle.com>

On 13.01.2017 17:17, Alexey Kodanev wrote:
> Hi,
>
> Got the issue when running LTP/netstress test on localhost with mss
> greater than the send window advertised by client (right after 3WHS).
> Here is the testscenario that can reproduce this:

Please ignore this message with 'flowed' format. Will resend.

Thanks,
Alexey

^ permalink raw reply

* [PATCH net v1 1/1] tipc: allocate user memory with GFP_KERNEL flag
From: Parthasarathy Bhuvaragan @ 2017-01-13 14:46 UTC (permalink / raw)
  To: netdev, ying.xue; +Cc: jon.maloy, tipc-discussion

Until now, we allocate memory always with GFP_ATOMIC flag.
When the system is under memory pressure and a user tries to send,
the send fails due to low memory. However, the user application
can wait for free memory if we allocate it using GFP_KERNEL flag.

In this commit, we use allocate memory with GFP_KERNEL for all user
allocation.

Reported-by: Rune Torgersen <runet@innovsys.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
 net/tipc/discover.c   |  4 ++--
 net/tipc/link.c       |  2 +-
 net/tipc/msg.c        | 16 ++++++++--------
 net/tipc/msg.h        |  2 +-
 net/tipc/name_distr.c |  2 +-
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 6b109a808d4c..02462d67d191 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -169,7 +169,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
 
 	/* Send response, if necessary */
 	if (respond && (mtyp == DSC_REQ_MSG)) {
-		rskb = tipc_buf_acquire(MAX_H_SIZE);
+		rskb = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
 		if (!rskb)
 			return;
 		tipc_disc_init_msg(net, rskb, DSC_RESP_MSG, bearer);
@@ -278,7 +278,7 @@ int tipc_disc_create(struct net *net, struct tipc_bearer *b,
 	req = kmalloc(sizeof(*req), GFP_ATOMIC);
 	if (!req)
 		return -ENOMEM;
-	req->buf = tipc_buf_acquire(MAX_H_SIZE);
+	req->buf = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
 	if (!req->buf) {
 		kfree(req);
 		return -ENOMEM;
diff --git a/net/tipc/link.c b/net/tipc/link.c
index b758ca8b2f79..b0f8646e0631 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1384,7 +1384,7 @@ void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
 			msg_set_seqno(hdr, seqno++);
 		pktlen = msg_size(hdr);
 		msg_set_size(&tnlhdr, pktlen + INT_H_SIZE);
-		tnlskb = tipc_buf_acquire(pktlen + INT_H_SIZE);
+		tnlskb = tipc_buf_acquire(pktlen + INT_H_SIZE, GFP_ATOMIC);
 		if (!tnlskb) {
 			pr_warn("%sunable to send packet\n", link_co_err);
 			return;
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index a22be502f1bd..ab02d0742476 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -58,12 +58,12 @@ static unsigned int align(unsigned int i)
  * NOTE: Headroom is reserved to allow prepending of a data link header.
  *       There may also be unrequested tailroom present at the buffer's end.
  */
-struct sk_buff *tipc_buf_acquire(u32 size)
+struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp)
 {
 	struct sk_buff *skb;
 	unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
 
-	skb = alloc_skb_fclone(buf_size, GFP_ATOMIC);
+	skb = alloc_skb_fclone(buf_size, gfp);
 	if (skb) {
 		skb_reserve(skb, BUF_HEADROOM);
 		skb_put(skb, size);
@@ -95,7 +95,7 @@ struct sk_buff *tipc_msg_create(uint user, uint type,
 	struct tipc_msg *msg;
 	struct sk_buff *buf;
 
-	buf = tipc_buf_acquire(hdr_sz + data_sz);
+	buf = tipc_buf_acquire(hdr_sz + data_sz, GFP_ATOMIC);
 	if (unlikely(!buf))
 		return NULL;
 
@@ -261,7 +261,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
 
 	/* No fragmentation needed? */
 	if (likely(msz <= pktmax)) {
-		skb = tipc_buf_acquire(msz);
+		skb = tipc_buf_acquire(msz, GFP_KERNEL);
 		if (unlikely(!skb))
 			return -ENOMEM;
 		skb_orphan(skb);
@@ -282,7 +282,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
 	msg_set_importance(&pkthdr, msg_importance(mhdr));
 
 	/* Prepare first fragment */
-	skb = tipc_buf_acquire(pktmax);
+	skb = tipc_buf_acquire(pktmax, GFP_KERNEL);
 	if (!skb)
 		return -ENOMEM;
 	skb_orphan(skb);
@@ -313,7 +313,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
 			pktsz = drem + INT_H_SIZE;
 		else
 			pktsz = pktmax;
-		skb = tipc_buf_acquire(pktsz);
+		skb = tipc_buf_acquire(pktsz, GFP_KERNEL);
 		if (!skb) {
 			rc = -ENOMEM;
 			goto error;
@@ -448,7 +448,7 @@ bool tipc_msg_make_bundle(struct sk_buff **skb,  struct tipc_msg *msg,
 	if (msz > (max / 2))
 		return false;
 
-	_skb = tipc_buf_acquire(max);
+	_skb = tipc_buf_acquire(max, GFP_ATOMIC);
 	if (!_skb)
 		return false;
 
@@ -496,7 +496,7 @@ bool tipc_msg_reverse(u32 own_node,  struct sk_buff **skb, int err)
 
 	/* Never return SHORT header; expand by replacing buffer if necessary */
 	if (msg_short(hdr)) {
-		*skb = tipc_buf_acquire(BASIC_H_SIZE + dlen);
+		*skb = tipc_buf_acquire(BASIC_H_SIZE + dlen, GFP_ATOMIC);
 		if (!*skb)
 			goto exit;
 		memcpy((*skb)->data + BASIC_H_SIZE, msg_data(hdr), dlen);
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 850ae0e469f5..f07b51e3f6f1 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -818,7 +818,7 @@ static inline bool msg_is_reset(struct tipc_msg *hdr)
 	return (msg_user(hdr) == LINK_PROTOCOL) && (msg_type(hdr) == RESET_MSG);
 }
 
-struct sk_buff *tipc_buf_acquire(u32 size);
+struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp);
 bool tipc_msg_validate(struct sk_buff *skb);
 bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, int err);
 void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index c1cfd92de17a..23f8899e0f8c 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -69,7 +69,7 @@ static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size,
 					 u32 dest)
 {
 	struct tipc_net *tn = net_generic(net, tipc_net_id);
-	struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size);
+	struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size, GFP_ATOMIC);
 	struct tipc_msg *msg;
 
 	if (buf != NULL) {
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

^ permalink raw reply related

* [PATCH net-next] afs: Conditionalise a new unused variable
From: David Howells @ 2017-01-13 14:46 UTC (permalink / raw)
  To: netdev; +Cc: dhowells, linux-afs, linux-kernel

From: Arnd Bergmann <arnd@arndb.de>

The bulk readpages support introduced a harmless warning:

fs/afs/file.c: In function 'afs_readpages_page_done':
fs/afs/file.c:270:20: error: unused variable 'vnode' [-Werror=unused-variable]

This adds an #ifdef to match the user of that variable.  The user of the
variable has to be conditional because it accesses a member of a struct
that is also conditional.

Fixes: 91b467e0a3f5 ("afs: Make afs_readpages() fetch data in bulk")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/afs/file.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/afs/file.c b/fs/afs/file.c
index 82897a78abc7..ba7b71fba34b 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -267,7 +267,9 @@ static int afs_readpage(struct file *file, struct page *page)
  */
 static void afs_readpages_page_done(struct afs_call *call, struct afs_read *req)
 {
+#ifdef CONFIG_AFS_FSCACHE
 	struct afs_vnode *vnode = call->reply;
+#endif
 	struct page *page = req->pages[req->index];
 
 	req->pages[req->index] = NULL;

^ permalink raw reply related

* Re: [PATCH V2] audit: log 32-bit socketcalls
From: Eric Paris @ 2017-01-13 14:42 UTC (permalink / raw)
  To: Richard Guy Briggs, netdev, linux-kernel, linux-audit
  Cc: Kangkook Jee, Paul Moore, Steve Grubb
In-Reply-To: <dd937da01da72da9277e44ed79abd1f4618c14c5.1484297765.git.rgb@redhat.com>

On Fri, 2017-01-13 at 04:51 -0500, Richard Guy Briggs wrote:
> 32-bit socketcalls were not being logged by audit on x86_64 systems.
> Log them.  This is basically a duplicate of the call from
> net/socket.c:sys_socketcall(), but it addresses the impedance
> mismatch
> between 32-bit userspace process and 64-bit kernel audit.
> 
> See: https://github.com/linux-audit/audit-kernel/issues/14
> 
> Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> 
> --
> v2:
>    Move work to audit_socketcall_compat() and use
> audit_dummy_context().
> ---
>  include/linux/audit.h |   16 ++++++++++++++++
>  net/compat.c          |   15 +++++++++++++--
>  2 files changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index 9d4443f..43d8003 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -387,6 +387,18 @@ static inline int audit_socketcall(int nargs,
> unsigned long *args)
>  		return __audit_socketcall(nargs, args);
>  	return 0;
>  }
> +static inline int audit_socketcall_compat(int nargs, u32 *args)
> +{
> +	if (unlikely(!audit_dummy_context())) {

I've always hated these likely/unlikely. Mostly because I think they
are so often wrong. I believe this says that you compiled audit in but
you expect it to be explicitly disabled. While that is (recently) true
in Fedora I highly doubt that's true on the vast majority of systems
that have audit compiled in.

I think all of the likely/unlikely need to just be abandoned, but at
least don't add more? It certainly wouldn't be the first time I was
wrong, and I haven't profiled it. But the function would definitely
look better if coded

static inline int audit_socketcall_compat(int nargs, u32 *args)
{
    if (audit_cummy_context()) {
        return 0
    }
    int i;
    unsigned long a[AUDITSC_ARGS];

    [...]
}

> +		int i;
> +		unsigned long a[AUDITSC_ARGS];
> +
> +		for (i=0; i<nargs; i++)
> +			a[i] = (unsigned long)args[i];
> +		return __audit_socketcall(nargs, a);
> +	}
> +	return 0;
> +}
>  static inline int audit_sockaddr(int len, void *addr)
>  {
>  	if (unlikely(!audit_dummy_context()))
> @@ -513,6 +525,10 @@ static inline int audit_socketcall(int nargs,
> unsigned long *args)
>  {
>  	return 0;
>  }
> +static inline int audit_socketcall_compat(int nargs, u32 *args)
> +{
> +	return 0;
> +}
>  static inline void audit_fd_pair(int fd1, int fd2)
>  { }
>  static inline int audit_sockaddr(int len, void *addr)
> diff --git a/net/compat.c b/net/compat.c
> index 1cd2ec0..f0404d4 100644
> --- a/net/compat.c
> +++ b/net/compat.c
> @@ -22,6 +22,7 @@
>  #include <linux/filter.h>
>  #include <linux/compat.h>
>  #include <linux/security.h>
> +#include <linux/audit.h>
>  #include <linux/export.h>
>  
>  #include <net/scm.h>
> @@ -781,14 +782,24 @@ COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd,
> struct compat_mmsghdr __user *, mmsg,
>  
>  COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
>  {
> +	unsigned int len;
>  	int ret;
> -	u32 a[6];
> +	u32 a[AUDITSC_ARGS];
>  	u32 a0, a1;
>  
>  	if (call < SYS_SOCKET || call > SYS_SENDMMSG)
>  		return -EINVAL;
> -	if (copy_from_user(a, args, nas[call]))
> +	len = nas[call];
> +	if (len > sizeof(a))
> +		return -EINVAL;
> +
> +	if (copy_from_user(a, args, len))
>  		return -EFAULT;
> +
> +	ret = audit_socketcall_compat(len/sizeof(a[0]), a);
> +	if (ret)
> +		return ret;
> +
>  	a0 = a[0];
>  	a1 = a[1];
>  

^ permalink raw reply

* [PATCH] net: phy: dp83867: allow RGMII_TXID/RGMII_RXID interface types
From: Murali Karicheri @ 2017-01-13 14:32 UTC (permalink / raw)
  To: robh+dt, mark.rutland, f.fainelli, netdev, devicetree,
	linux-kernel, nsekhar

Currently dp83867 driver returns error if phy interface type
PHY_INTERFACE_MODE_RGMII_RXID is used to set the rx only internal
delay. Similarly issue happens for PHY_INTERFACE_MODE_RGMII_TXID.
Fix this by checking also the interface type if a particular delay
value is missing in the phy dt bindings. Also update the DT document
accordingly.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
 - I had sent this earlier and some how it didn't get through and
   I haven't seen any comment for this. So sending this again.
 - Applies to master.

 Documentation/devicetree/bindings/net/ti,dp83867.txt | 6 ++++--
 drivers/net/phy/dp83867.c                            | 8 ++++++--
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/ti,dp83867.txt b/Documentation/devicetree/bindings/net/ti,dp83867.txt
index 85bf945..afe9630 100644
--- a/Documentation/devicetree/bindings/net/ti,dp83867.txt
+++ b/Documentation/devicetree/bindings/net/ti,dp83867.txt
@@ -3,9 +3,11 @@
 Required properties:
 	- reg - The ID number for the phy, usually a small integer
 	- ti,rx-internal-delay - RGMII Receive Clock Delay - see dt-bindings/net/ti-dp83867.h
-		for applicable values
+		for applicable values. Required only if interface type is
+		PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_RXID
 	- ti,tx-internal-delay - RGMII Transmit Clock Delay - see dt-bindings/net/ti-dp83867.h
-		for applicable values
+		for applicable values. Required only if interface type is
+		PHY_INTERFACE_MODE_RGMII_ID or PHY_INTERFACE_MODE_RGMII_TXID
 	- ti,fifo-depth - Transmitt FIFO depth- see dt-bindings/net/ti-dp83867.h
 		for applicable values
 
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index e84ae08..ca1b462 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -132,12 +132,16 @@ static int dp83867_of_init(struct phy_device *phydev)
 
 	ret = of_property_read_u32(of_node, "ti,rx-internal-delay",
 				   &dp83867->rx_id_delay);
-	if (ret)
+	if (ret &&
+	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+	     phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
 		return ret;
 
 	ret = of_property_read_u32(of_node, "ti,tx-internal-delay",
 				   &dp83867->tx_id_delay);
-	if (ret)
+	if (ret &&
+	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+	     phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID))
 		return ret;
 
 	return of_property_read_u32(of_node, "ti,fifo-depth",
-- 
1.9.1

^ permalink raw reply related

* tcp: performance issue with fastopen connections (mss > window)
From: Alexey Kodanev @ 2017-01-13 14:17 UTC (permalink / raw)
  To: David Miller, Eric Dumazet; +Cc: netdev, Vasily Isaenko

Hi,

Got the issue when running LTP/netstress test on localhost with mss
greater than the send window advertised by client (right after 3WHS).
Here is the testscenario that can reproduce this:

TCP client is sending 32 bytes request, TCP server replies with 65KB answer.
net.ipv4.tcp_fastopen set to 3. Also notethat the first TCP Fastopen
connectionprocessed without delay as tcp_send_mss()setshalf of the window
sizeto the'size_goal' inside tcp_sendmsg().

Though on the 2nd and subsequent connections:

< S  seq 0:0 win 43690 options [mss 65495 wscale 7
          tfo cookie ac6246a51d5422fc] length 32
 > S.seq 0:0ack 1win 43690 options [mss 65495wscale 7] length 0
<.ack 1 win 342 length 0

Inside tcp_sendmsg(), tcp_send_mss() returns 65483 in 'mss_now',as well as
in 'size_goal'. This results the segment not queued for transmition 
until all
data copied from userbuffer. Then, inside  __tcp_push_pending_frames() it
breaks on send window test,continue with the check probe timer, thus
introducing 200ms delay here.

Fragmentationoccurs in tcp_write_wakeup()...

+0.2> P. seq 1:43777 ack 1 win 342 length 43776
<. ack 43777, win 1365 length 0
      > P. seq 43777:65001 ack 1 win 342 optionslength 21224
      ...


Not sure what is the right fix for this, I guess we could limit 'size_goal'
to the current window or mss, what is currently less, e.g:

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4a04496..3d3bd97 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -860,7 +860,12 @@ static unsigned int tcp_xmit_size_goal(struct sock 
*sk, u32 mss_now,
                 size_goal = tp->gso_segs * mss_now;
         }

-       return max(size_goal, mss_now);
+       size_goal = max(size_goal, mss_now);
+
+       if (tp->snd_wnd > TCP_MSS_DEFAULT)
+               return min(tp->snd_wnd, size_goal);
+
+       return size_goal;
  }

  static int tcp_send_mss(struct sock *sk, int *size_goal, int flags)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 1d5331a..0ac133f 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2445,7 +2445,7 @@ void tcp_push_one(struct sock *sk, unsigned int 
mss_now)
  {
         struct sk_buff *skb = tcp_send_head(sk);

-       BUG_ON(!skb || skb->len < mss_now);
+       BUG_ON(!skb);

         tcp_write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, sk->sk_allocation);
  }


Any ideas?

Thanks,
Alexey

^ permalink raw reply related

* Re: [PATCH net-next v2 08/10] net: dsa: Add support for platform data
From: Andrew Lunn @ 2017-01-13 14:11 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev, Jason Cooper, Sebastian Hesselbarth, Gregory Clement,
	Russell King, Vivien Didelot, David S. Miller,
	moderated list:ARM SUB-ARCHITECTURES, open list, gregkh
In-Reply-To: <20170112034121.27697-9-f.fainelli@gmail.com>

>  static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev)
>  {
> +	struct dsa_chip_data *pdata = dev->platform_data;
>  	struct device_node *np = dev->of_node;
>  	struct dsa_switch_tree *dst;
>  	struct device_node *ports;
>  	u32 tree, index;
>  	int i, err;
>  
> -	err = dsa_parse_member_dn(np, &tree, &index);
> -	if (err)
> -		return err;
> +	if (np) {
> +		err = dsa_parse_member_dn(np, &tree, &index);
> +		if (err)
> +			return err;
>  
> -	ports = dsa_get_ports(ds, np);
> -	if (IS_ERR(ports))
> -		return PTR_ERR(ports);
> +		ports = dsa_get_ports(ds, np);
> +		if (IS_ERR(ports))
> +			return PTR_ERR(ports);
>  
> -	err = dsa_parse_ports_dn(ports, ds);
> -	if (err)
> -		return err;
> +		err = dsa_parse_ports_dn(ports, ds);
> +		if (err)
> +			return err;
> +	} else {
> +		err = dsa_parse_member(pdata, &tree, &index);

Hi Florian

Maybe it is hiding, but i don't see anywhere you check that pdata !=
NULL.

At least for x86 platforms, i don't expect we are booting using
platform data like ARM systems used to do. I think it is more likely a
glue module will be loaded. It looks up the MDIO bus and appends a
platform data to an MDIO device. The switch driver then needs to load
and use the platform data. But if things happen in a different order,
it could be the switch driver probes before the glue driver, meaning
pdata is NULL.

Do we even want to return -EPROBE_DEFERED?

      Andrew

^ permalink raw reply

* [PATCH] xfrm: state: fix potential null pointer dereference on afinfo
From: Colin King @ 2017-01-13 14:07 UTC (permalink / raw)
  To: Steffen Klassert, Herbert Xu, David S . Miller, netdev; +Cc: linux-kernel

From: Colin Ian King <colin.king@canonical.com>

afinfo is being null checked before a call afinfo->init_tempsel
so afinfo may be potentially null. ifinfo may still be null in
the case were it is not updated when family == tmpl->encap_family,
hence we may hit a null pointer dereference in the call to
afinfo->init_temprop.

Fix this by adding a null ptr check before calling init_temprop.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 net/xfrm/xfrm_state.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index a62097e..5083418 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -656,7 +656,8 @@ xfrm_init_tempstate(struct xfrm_state *x, const struct flowi *fl,
 		if (!afinfo)
 			return;
 	}
-	afinfo->init_temprop(x, tmpl, daddr, saddr);
+	if (afinfo)
+		afinfo->init_temprop(x, tmpl, daddr, saddr);
 }
 
 static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark,
-- 
2.10.2

^ permalink raw reply related

* Re: [PATCH net-next v2 08/10] net: dsa: Add support for platform data
From: Andrew Lunn @ 2017-01-13 14:04 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: netdev, Jason Cooper, Sebastian Hesselbarth, Gregory Clement,
	Russell King, Vivien Didelot, David S. Miller,
	moderated list:ARM SUB-ARCHITECTURES, open list, gregkh
In-Reply-To: <20170112034121.27697-9-f.fainelli@gmail.com>

> index cd91070b5467..d326fc4afad7 100644
> --- a/net/dsa/dsa2.c
> +++ b/net/dsa/dsa2.c
> @@ -81,17 +81,23 @@ static void dsa_dst_del_ds(struct dsa_switch_tree *dst,
>  
>  static bool dsa_port_is_valid(struct dsa_port *port)
>  {
> -	return !!port->dn;
> +	return !!(port->dn || port->name);
>  }
  
Does this clash with Viviens recent change to make names optional and
have the kernel assign it?

I suppose you could use an name of "eth%d"? Is it worth adding a
comment to the platform data structure?

	Andrew

^ permalink raw reply

* Re: [3/5] ath10k: Remove unused wmi_p2p_noa_descriptor 'noa' in wmi-tlv
From: Kalle Valo @ 2017-01-13 14:01 UTC (permalink / raw)
  To: Kirtika Ruchandani
  Cc: Arnd Bergmann, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA, Raja Mani, Michal Kazior
In-Reply-To: <99d0ff42e57d5f62560e72d926b4d69d5d7c418b.1479974100.git.kirtika-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

Kirtika Ruchandani <kirtika.ruchandani-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Commit ca996ec56608 (ath10k: implement wmi-tlv backend)
> introduced ath10k_wmi_tlv_op_gen_vdev_start() where
> 'struct wmi_p2p_noa_descriptor *noa' is defined and set but not used.
> Compiling with W=1 gives the following warning, fix it.
> drivers/net/wireless/ath/ath10k/wmi-tlv.c: In function ‘ath10k_wmi_tlv_op_gen_vdev_start’:
> drivers/net/wireless/ath/ath10k/wmi-tlv.c:1647:33: warning: variable ‘noa’ set but not used [-Wunused-but-set-variable]
> 
> Fixes: ca996ec56608 ("ath10k: implement wmi-tlv backend")
> Cc: Michal Kazior <michal.kazior-++hxYGjEMp0AvxtiuMwx3w@public.gmane.org>
> Cc: Kalle Valo <kvalo-A+ZNKFmMK5xy9aJCnZT0Uw@public.gmane.org>
> Signed-off-by: Kirtika Ruchandani <kirtika-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

No response to Michal's comment by the author

Patch set to Changes Requested.

-- 
https://patchwork.kernel.org/patch/9444937/

Documentation about submitting wireless patches and checking status
from patchwork:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply

* Re: [PATCH net-next] net/mlx5e: Support bpf_xdp_adjust_head()
From: Saeed Mahameed @ 2017-01-13 13:58 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: Linux Netdev List, Saeed Mahameed, Tariq Toukan, Kernel Team
In-Reply-To: <20170112232546.GA1595@kafai-mba.local>

On Fri, Jan 13, 2017 at 1:25 AM, Martin KaFai Lau <kafai@fb.com> wrote:
> On Thu, Jan 12, 2017 at 03:10:30PM +0200, Saeed Mahameed wrote:
>> On Thu, Jan 12, 2017 at 4:09 AM, Martin KaFai Lau <kafai@fb.com> wrote:
>> > This patch adds bpf_xdp_adjust_head() support to mlx5e.
>>
>> Hi Martin, Thanks for the patch !
>>
>> you can find some comments below.
>>
>> >
>> > 1. rx_headroom is added to struct mlx5e_rq.  It uses
>> >    an existing 4 byte hole in the struct.
>> > 2. The adjusted data length is checked against
>> >    MLX5E_XDP_MIN_INLINE and MLX5E_SW2HW_MTU(rq->netdev->mtu).
>> > 3. The macro MLX5E_SW2HW_MTU is moved from en_main.c to en.h.
>> >    MLX5E_HW2SW_MTU is also moved to en.h for symmetric reason
>> >    but it is not a must.
>> >
>> > Signed-off-by: Martin KaFai Lau <kafai@fb.com>
>> > ---
>> >  drivers/net/ethernet/mellanox/mlx5/core/en.h      |  4 ++
>> >  drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 18 +++----
>> >  drivers/net/ethernet/mellanox/mlx5/core/en_rx.c   | 63 ++++++++++++++---------
>> >  3 files changed, 51 insertions(+), 34 deletions(-)
>> >
>> > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
>> > index a473cea10c16..0d9dd860a295 100644
>> > --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
>> > +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
>> > @@ -51,6 +51,9 @@
>> >
>> >  #define MLX5_SET_CFG(p, f, v) MLX5_SET(create_flow_group_in, p, f, v)
>> >
>> > +#define MLX5E_HW2SW_MTU(hwmtu) ((hwmtu) - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN))
>> > +#define MLX5E_SW2HW_MTU(swmtu) ((swmtu) + (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN))
>> > +
>> >  #define MLX5E_MAX_NUM_TC       8
>> >
>> >  #define MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE                0x6
>> > @@ -369,6 +372,7 @@ struct mlx5e_rq {
>> >
>> >         unsigned long          state;
>> >         int                    ix;
>> > +       u16                    rx_headroom;
>> >
>> >         struct mlx5e_rx_am     am; /* Adaptive Moderation */
>> >         struct bpf_prog       *xdp_prog;
>> > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
>> > index f74ba73c55c7..aba3691e0919 100644
>> > --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
>> > +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
>> > @@ -343,9 +343,6 @@ static void mlx5e_disable_async_events(struct mlx5e_priv *priv)
>> >         synchronize_irq(mlx5_get_msix_vec(priv->mdev, MLX5_EQ_VEC_ASYNC));
>> >  }
>> >
>> > -#define MLX5E_HW2SW_MTU(hwmtu) (hwmtu - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN))
>> > -#define MLX5E_SW2HW_MTU(swmtu) (swmtu + (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN))
>> > -
>> >  static inline int mlx5e_get_wqe_mtt_sz(void)
>> >  {
>> >         /* UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes.
>> > @@ -534,9 +531,13 @@ static int mlx5e_create_rq(struct mlx5e_channel *c,
>> >                 goto err_rq_wq_destroy;
>> >         }
>> >
>> > -       rq->buff.map_dir = DMA_FROM_DEVICE;
>> > -       if (rq->xdp_prog)
>> > +       if (rq->xdp_prog) {
>> >                 rq->buff.map_dir = DMA_BIDIRECTIONAL;
>> > +               rq->rx_headroom = XDP_PACKET_HEADROOM;
>> > +       } else {
>> > +               rq->buff.map_dir = DMA_FROM_DEVICE;
>> > +               rq->rx_headroom = MLX5_RX_HEADROOM;
>> > +       }
>> >
>> >         switch (priv->params.rq_wq_type) {
>> >         case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
>> > @@ -586,7 +587,7 @@ static int mlx5e_create_rq(struct mlx5e_channel *c,
>> >                 byte_count = rq->buff.wqe_sz;
>> >
>> >                 /* calc the required page order */
>> > -               frag_sz = MLX5_RX_HEADROOM +
>> > +               frag_sz = rq->rx_headroom +
>> >                           byte_count /* packet data */ +
>> >                           SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>> >                 frag_sz = SKB_DATA_ALIGN(frag_sz);
>> > @@ -3153,11 +3154,6 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
>> >         bool reset, was_opened;
>> >         int i;
>> >
>> > -       if (prog && prog->xdp_adjust_head) {
>> > -               netdev_err(netdev, "Does not support bpf_xdp_adjust_head()\n");
>> > -               return -EOPNOTSUPP;
>> > -       }
>> > -
>> >         mutex_lock(&priv->state_lock);
>> >
>> >         if ((netdev->features & NETIF_F_LRO) && prog) {
>> > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
>> > index 0e2fb3ed1790..914e00132e08 100644
>> > --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
>> > +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
>> > @@ -264,7 +264,7 @@ int mlx5e_alloc_rx_wqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix)
>> >         if (unlikely(mlx5e_page_alloc_mapped(rq, di)))
>> >                 return -ENOMEM;
>> >
>> > -       wqe->data.addr = cpu_to_be64(di->addr + MLX5_RX_HEADROOM);
>> > +       wqe->data.addr = cpu_to_be64(di->addr + rq->rx_headroom);
>> >         return 0;
>> >  }
>> >
>> > @@ -646,8 +646,7 @@ static inline void mlx5e_xmit_xdp_doorbell(struct mlx5e_sq *sq)
>> >
>> >  static inline void mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
>> >                                         struct mlx5e_dma_info *di,
>> > -                                       unsigned int data_offset,
>> > -                                       int len)
>> > +                                       const struct xdp_buff *xdp)
>> >  {
>> >         struct mlx5e_sq          *sq   = &rq->channel->xdp_sq;
>> >         struct mlx5_wq_cyc       *wq   = &sq->wq;
>> > @@ -659,9 +658,17 @@ static inline void mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
>> >         struct mlx5_wqe_eth_seg  *eseg = &wqe->eth;
>> >         struct mlx5_wqe_data_seg *dseg;
>> >
>> > +       ptrdiff_t data_offset = xdp->data - xdp->data_hard_start;
>> >         dma_addr_t dma_addr  = di->addr + data_offset + MLX5E_XDP_MIN_INLINE;
>> > -       unsigned int dma_len = len - MLX5E_XDP_MIN_INLINE;
>> > -       void *data           = page_address(di->page) + data_offset;
>> > +       unsigned int dma_len = xdp->data_end - xdp->data;
>> > +
>> > +       if (unlikely(dma_len < MLX5E_XDP_MIN_INLINE ||
>>
>> I don't think this can happen, MLX5E_XDP_MIN_INLINE is 18 bytes and
>> should not get bigger in the future,
>> Also i don't think it is possible for XDP prog to xmit packets smaller
>> than 18 bytes, let's remove this
> The bpf_xdp_adjust_head() only checks for a min of ETH_HLEN which is 14.
> Hence, <18 bytes is still possible here.
>
>>
>> > +                    MLX5E_SW2HW_MTU(rq->netdev->mtu) < dma_len)) {
>> > +               rq->stats.xdp_drop++;
>> > +               mlx5e_page_release(rq, di, true);
>> > +               return;
>> > +       }
>> > +       dma_len -= MLX5E_XDP_MIN_INLINE;
>>
>> Move this to after the below sanity check, it is better to separate
>> logic from pre-conditions
> Will do.
>
>>
>> >
>> >         if (unlikely(!mlx5e_sq_has_room_for(sq, MLX5E_XDP_TX_WQEBBS))) {
>> >                 if (sq->db.xdp.doorbell) {
>> > @@ -680,7 +687,7 @@ static inline void mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
>> >         memset(wqe, 0, sizeof(*wqe));
>> >
>> >         /* copy the inline part */
>> > -       memcpy(eseg->inline_hdr_start, data, MLX5E_XDP_MIN_INLINE);
>> > +       memcpy(eseg->inline_hdr_start, xdp->data, MLX5E_XDP_MIN_INLINE);
>> >         eseg->inline_hdr_sz = cpu_to_be16(MLX5E_XDP_MIN_INLINE);
>> >
>> >         dseg = (struct mlx5_wqe_data_seg *)cseg + (MLX5E_XDP_TX_DS_COUNT - 1);
>> > @@ -706,22 +713,16 @@ static inline void mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
>> >  static inline bool mlx5e_xdp_handle(struct mlx5e_rq *rq,
>> >                                     const struct bpf_prog *prog,
>> >                                     struct mlx5e_dma_info *di,
>> > -                                   void *data, u16 len)
>> > +                                   struct xdp_buff *xdp)
>> >  {
>> > -       struct xdp_buff xdp;
>> >         u32 act;
>> >
>> > -       if (!prog)
>> > -               return false;
>> > -
>> > -       xdp.data = data;
>> > -       xdp.data_end = xdp.data + len;
>> > -       act = bpf_prog_run_xdp(prog, &xdp);
>> > +       act = bpf_prog_run_xdp(prog, xdp);
>> >         switch (act) {
>> >         case XDP_PASS:
>> >                 return false;
>> >         case XDP_TX:
>> > -               mlx5e_xmit_xdp_frame(rq, di, MLX5_RX_HEADROOM, len);
>> > +               mlx5e_xmit_xdp_frame(rq, di, xdp);
>> >                 return true;
>> >         default:
>> >                 bpf_warn_invalid_xdp_action(act);
>> > @@ -737,18 +738,19 @@ static inline
>> >  struct sk_buff *skb_from_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
>> >                              u16 wqe_counter, u32 cqe_bcnt)
>> >  {
>> > +       const struct bpf_prog *xdp_prog;
>> >         struct mlx5e_dma_info *di;
>> >         struct sk_buff *skb;
>> >         void *va, *data;
>> > -       bool consumed;
>> > +       u16 rx_headroom = rq->rx_headroom;
>> >
>> >         di             = &rq->dma_info[wqe_counter];
>> >         va             = page_address(di->page);
>> > -       data           = va + MLX5_RX_HEADROOM;
>> > +       data           = va + rx_headroom;
>> >
>> >         dma_sync_single_range_for_cpu(rq->pdev,
>> >                                       di->addr,
>> > -                                     MLX5_RX_HEADROOM,
>> > +                                     rx_headroom,
>> >                                       rq->buff.wqe_sz,
>> >                                       DMA_FROM_DEVICE);
>> >         prefetch(data);
>> > @@ -760,11 +762,26 @@ struct sk_buff *skb_from_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
>> >         }
>> >
>> >         rcu_read_lock();
>> > -       consumed = mlx5e_xdp_handle(rq, READ_ONCE(rq->xdp_prog), di, data,
>> > -                                   cqe_bcnt);
>> > +       xdp_prog = READ_ONCE(rq->xdp_prog);
>> > +       if (xdp_prog) {
>> > +               struct xdp_buff xdp;
>> > +               bool consumed;
>> > +
>> > +               xdp.data = data;
>> > +               xdp.data_end = xdp.data + cqe_bcnt;
>> > +               xdp.data_hard_start = va;
>> > +
>> > +               consumed = mlx5e_xdp_handle(rq, xdp_prog, di, &xdp);
>> > +
>> > +               if (consumed) {
>> > +                       rcu_read_unlock();
>> > +                       return NULL; /* page/packet was consumed by XDP */
>> > +               }
>> > +
>> > +               rx_headroom = xdp.data - xdp.data_hard_start;
>> > +               cqe_bcnt = xdp.data_end - xdp.data;
>> > +       }
>>
>> This whole new logic belongs to mlx5e_xdp_handle, I would like to keep
>> xdp related code in one place.
>>
>> move the xdp_buff initialization back to there and keep the xdp_prog
>> check in mlx5e_xdp_handle;
>> +      xdp_prog = READ_ONCE(rq->xdp_prog);
>> +       if (!xdp_prog)
>> +                    return false
>>
>> you can remove "const struct bpf_prog *prog" parameter from
>> mlx5e_xdp_handle and take it directly from rq.
>>
>> if you need va for xdp_buff you can pass it as a paramter to
>> mlx5e_xdp_handle  as well:
>> mlx5e_xdp_handle(rq, di, va, data, cqe_bcnt);
>> Make sense ?
> I moved them because xdp.data could be adjusted which then
> rx_headroom and cqe_bcnt have to be adjusted accordingly
> in skb_from_cqe() also.
>
> I understand your point.  After another quick thought,
> the adjusted xdp.data is the only one that we want in skb_from_cqe().
> I will try to make mlx5e_xdp_handle() to return the adjusted xdp.data
> instead of bool.
>

hmm, You also need the adjusted cqe_bcnt! this will make
mlx5e_xdp_handle stuffed with parameters,

what if, in skb_from_cqe we warp data, rx_headroom and cqe_bcnt in one struct.

struct mlx5e_rx_buff {
void *data;
u6 headroom;
u32 bcnt;
}

initialize it at the start of skb_from_cqe:

struct mlx5e_rx_buff rxb;

rxb.headroom = rq->headroom;
rxb.data = va + rxb.headroom;
rxb.bcnt = cqe_bcnt;

pass it to mlx5e_xdp_handle(rq, di, va, &rxb) in case xdp_prog is ON
and rxb needs adjustment.

At the end use it to build the SKB:
skb = build_skb(va, RQ_PAGE_SIZE(rq));
skb_reserve(skb, rxb.headroom);
skb_put(skb, rxb.bcnt);

Thanks,
Saeed.

> Thanks,
> --Martin
>
>>
>> >         rcu_read_unlock();
>> > -       if (consumed)
>> > -               return NULL; /* page/packet was consumed by XDP */
>> >
>> >         skb = build_skb(va, RQ_PAGE_SIZE(rq));
>> >         if (unlikely(!skb)) {
>> > @@ -777,7 +794,7 @@ struct sk_buff *skb_from_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
>> >         page_ref_inc(di->page);
>> >         mlx5e_page_release(rq, di, true);
>> >
>> > -       skb_reserve(skb, MLX5_RX_HEADROOM);
>> > +       skb_reserve(skb, rx_headroom);
>> >         skb_put(skb, cqe_bcnt);
>> >
>> >         return skb;
>> > --
>> > 2.5.1
>> >

^ permalink raw reply

* pull-request: mac80211 2017-01-13
From: Johannes Berg @ 2017-01-13 13:55 UTC (permalink / raw)
  To: David Miller
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA

Hi Dave,

Here's another update for the current cycle. Some of those
patches have been sitting in our tree and I haven't been
pulling them out quickly enough - will try to do better...

Please pull and let me know if there's any problem.

Thanks,
johannes



The following changes since commit 03430fa10b99e95e3a15eb7c00978fb1652f3b24:

  Merge branch 'bcm_sf2-fixes' (2017-01-08 22:01:22 -0500)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git tags/mac80211-for-davem-2017-01-13

for you to fetch changes up to dbef53621116474bb883f76f0ba6b7640bc42332:

  mac80211: prevent skb/txq mismatch (2017-01-13 14:47:21 +0100)

----------------------------------------------------------------
We have a number of fixes, in part because I was late
in actually sending them out - will try to do better in
the future:
 * handle VHT opmode properly when hostapd is controlling
   full station state
 * two fixes for minimum channel width in mac80211
 * don't leave SMPS set to junk in HT capabilities
 * fix headroom when forwarding mesh packets, recently
   broken by another fix that failed to take into account
   frame encryption
 * fix the TID in null-data packets indicating EOSP (end
   of service period) in U-APSD
 * prevent attempting to use (and then failing which
   results in crashes) TXQs on stations that aren't added
   to the driver yet

----------------------------------------------------------------
Beni Lev (1):
      cfg80211: consider VHT opmode on station update

Cedric Izoard (1):
      mac80211: Fix headroom allocation when forwarding mesh pkt

Emmanuel Grumbach (1):
      mac80211: fix the TID on NDPs sent as EOSP carrier

Felix Fietkau (1):
      mac80211: initialize SMPS field in HT capabilities

Johannes Berg (3):
      mac80211: implement multicast forwarding on fast-RX path
      mac80211: calculate min channel width correctly
      mac80211: recalculate min channel width on VHT opmode changes

Michal Kazior (1):
      mac80211: prevent skb/txq mismatch

 include/uapi/linux/nl80211.h |  4 +++-
 net/mac80211/chan.c          |  3 ---
 net/mac80211/iface.c         | 21 +++++++++++++++++++++
 net/mac80211/main.c          | 13 +++++++++----
 net/mac80211/rate.c          |  2 ++
 net/mac80211/rx.c            | 38 +++++++++++++++++++++-----------------
 net/mac80211/sta_info.c      |  4 ++--
 net/mac80211/tx.c            | 17 +++++++----------
 net/mac80211/vht.c           |  4 +++-
 net/wireless/nl80211.c       | 15 +++++++++++++++
 10 files changed, 83 insertions(+), 38 deletions(-)

^ permalink raw reply

* [PATCH ipsec-next] xfrm: fix possible null deref in xfrm_init_tempstate
From: Florian Westphal @ 2017-01-13 13:55 UTC (permalink / raw)
  To: netdev; +Cc: dan.carpenter, Florian Westphal

Dan reports following smatch warning:
 net/xfrm/xfrm_state.c:659
 error: we previously assumed 'afinfo' could be null (see line 651)

 649  struct xfrm_state_afinfo *afinfo = xfrm_state_afinfo_get_rcu(family);
 651  if (afinfo)
		...
 658  }
 659  afinfo->init_temprop(x, tmpl, daddr, saddr);

I am resonably sure afinfo cannot be NULL here.

xfrm_state4.c and state6.c are both part of ipv4/ipv6 (depends on
CONFIG_XFRM, a boolean) but even if ipv6 is a module state6.c can't
be removed (ipv6 lacks module_exit so it cannot be removed).

The only callers for xfrm6_fini that leads to state backend unregister
are error unwinding paths that can be called during ipv6 init function.

So after ipv6 module is loaded successfully the state backend cannot go
away anymore.

The family value from policy lookup path is taken from dst_entry, so
that should always be AF_INET(6).

However, since this silences the warning and avoids readers of this
code wondering about possible null deref it seems preferrable to
be defensive and just add the old check back.

Fixes: 711059b9752ad0 ("xfrm: add and use xfrm_state_afinfo_get_rcu")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index a62097e640b5..5a597dbbe564 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -648,8 +648,10 @@ xfrm_init_tempstate(struct xfrm_state *x, const struct flowi *fl,
 {
 	struct xfrm_state_afinfo *afinfo = xfrm_state_afinfo_get_rcu(family);
 
-	if (afinfo)
-		afinfo->init_tempsel(&x->sel, fl);
+	if (!afinfo)
+		return;
+
+	afinfo->init_tempsel(&x->sel, fl);
 
 	if (family != tmpl->encap_family) {
 		afinfo = xfrm_state_afinfo_get_rcu(tmpl->encap_family);
-- 
2.7.3

^ permalink raw reply related

* Re: To netlink or not to netlink, that is the question
From: Nicolas Dichtel @ 2017-01-13 13:36 UTC (permalink / raw)
  To: Johannes Berg, Jason A. Donenfeld, Dan Williams; +Cc: Stephen Hemminger, Netdev
In-Reply-To: <1484291830.19860.3.camel@sipsolutions.net>

Le 13/01/2017 à 08:17, Johannes Berg a écrit :
[snip]
> In addition to what others have said - netlink typically includes (and
> has helpers to do so) a generation counter that's updated whenever this
> list changes, and included in each message, so if userspace really
> cares (often not) it can retry the dump until the system was idle
> enough to get a consistent snapshot.
Look at NLM_F_DUMP_INTR to get details.

> 
> It also looks to me like your existing API isn't even compat-safe due
> to u64 alignment (e.g. in wgpeer), proving once again that ioctl is a
> bad idea.
+1


Regards,
Nicolas

^ permalink raw reply


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