Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next v1 21/21] amd-xgbe: Add support for a KR redriver
From: Tom Lendacky @ 2016-11-03 13:31 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, David Miller
In-Reply-To: <20161103132744.3437.27332.stgit@tlendack-t1.amdoffice.net>

This patch provides support for the presence of a KR redriver chip in
between the device PCS and an external PHY.  When a redriver chip is
present the device must perform clause 73 auto-negotiation in order to
set the redriver chip for the downstream connection.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
 drivers/net/ethernet/amd/xgbe/xgbe-common.h |   10 +
 drivers/net/ethernet/amd/xgbe/xgbe-mdio.c   |   45 ++-
 drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c |    7 
 drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c |  427 +++++++++++++++++++++++++--
 drivers/net/ethernet/amd/xgbe/xgbe.h        |    6 
 5 files changed, 458 insertions(+), 37 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index ecd4f4d..5b7ba25 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -1062,6 +1062,16 @@
 #define XP_PROP_4_MUX_ADDR_LO_WIDTH		3
 #define XP_PROP_4_MUX_CHAN_INDEX		4
 #define XP_PROP_4_MUX_CHAN_WIDTH		3
+#define XP_PROP_4_REDRV_ADDR_INDEX		16
+#define XP_PROP_4_REDRV_ADDR_WIDTH		7
+#define XP_PROP_4_REDRV_IF_INDEX		23
+#define XP_PROP_4_REDRV_IF_WIDTH		1
+#define XP_PROP_4_REDRV_LANE_INDEX		24
+#define XP_PROP_4_REDRV_LANE_WIDTH		3
+#define XP_PROP_4_REDRV_MODEL_INDEX		28
+#define XP_PROP_4_REDRV_MODEL_WIDTH		3
+#define XP_PROP_4_REDRV_PRESENT_INDEX		31
+#define XP_PROP_4_REDRV_PRESENT_WIDTH		1
 
 /* I2C Control register offsets */
 #define IC_CON					0x0000
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
index 622675a..0ecae70 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
@@ -179,6 +179,7 @@ static void xgbe_an_enable_interrupts(struct xgbe_prv_data *pdata)
 {
 	switch (pdata->an_mode) {
 	case XGBE_AN_MODE_CL73:
+	case XGBE_AN_MODE_CL73_REDRV:
 		xgbe_an73_enable_interrupts(pdata);
 		break;
 	case XGBE_AN_MODE_CL37:
@@ -254,6 +255,10 @@ static void xgbe_kx_1000_mode(struct xgbe_prv_data *pdata)
 
 static void xgbe_sfi_mode(struct xgbe_prv_data *pdata)
 {
+	/* If a KR re-driver is present, change to KR mode instead */
+	if (pdata->kr_redrv)
+		return xgbe_kr_mode(pdata);
+
 	/* Disable KR training */
 	xgbe_an73_disable_kr_training(pdata);
 
@@ -433,6 +438,7 @@ static void xgbe_an_restart(struct xgbe_prv_data *pdata)
 {
 	switch (pdata->an_mode) {
 	case XGBE_AN_MODE_CL73:
+	case XGBE_AN_MODE_CL73_REDRV:
 		xgbe_an73_restart(pdata);
 		break;
 	case XGBE_AN_MODE_CL37:
@@ -448,6 +454,7 @@ static void xgbe_an_disable(struct xgbe_prv_data *pdata)
 {
 	switch (pdata->an_mode) {
 	case XGBE_AN_MODE_CL73:
+	case XGBE_AN_MODE_CL73_REDRV:
 		xgbe_an73_disable(pdata);
 		break;
 	case XGBE_AN_MODE_CL37:
@@ -687,6 +694,7 @@ static irqreturn_t xgbe_an_isr(int irq, void *data)
 
 	switch (pdata->an_mode) {
 	case XGBE_AN_MODE_CL73:
+	case XGBE_AN_MODE_CL73_REDRV:
 		xgbe_an73_isr(pdata);
 		break;
 	case XGBE_AN_MODE_CL37:
@@ -895,6 +903,7 @@ static void xgbe_an_state_machine(struct work_struct *work)
 
 	switch (pdata->an_mode) {
 	case XGBE_AN_MODE_CL73:
+	case XGBE_AN_MODE_CL73_REDRV:
 		xgbe_an73_state_machine(pdata);
 		break;
 	case XGBE_AN_MODE_CL37:
@@ -910,16 +919,18 @@ static void xgbe_an_state_machine(struct work_struct *work)
 
 static void xgbe_an37_init(struct xgbe_prv_data *pdata)
 {
-	unsigned int reg;
+	unsigned int advertising, reg;
+
+	advertising = pdata->phy_if.phy_impl.an_advertising(pdata);
 
 	/* Set up Advertisement register */
 	reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE);
-	if (pdata->phy.advertising & ADVERTISED_Pause)
+	if (advertising & ADVERTISED_Pause)
 		reg |= 0x100;
 	else
 		reg &= ~0x100;
 
-	if (pdata->phy.advertising & ADVERTISED_Asym_Pause)
+	if (advertising & ADVERTISED_Asym_Pause)
 		reg |= 0x80;
 	else
 		reg &= ~0x80;
@@ -954,11 +965,13 @@ static void xgbe_an37_init(struct xgbe_prv_data *pdata)
 
 static void xgbe_an73_init(struct xgbe_prv_data *pdata)
 {
-	unsigned int reg;
+	unsigned int advertising, reg;
+
+	advertising = pdata->phy_if.phy_impl.an_advertising(pdata);
 
 	/* Set up Advertisement register 3 first */
 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
-	if (pdata->phy.advertising & ADVERTISED_10000baseR_FEC)
+	if (advertising & ADVERTISED_10000baseR_FEC)
 		reg |= 0xc000;
 	else
 		reg &= ~0xc000;
@@ -967,13 +980,13 @@ static void xgbe_an73_init(struct xgbe_prv_data *pdata)
 
 	/* Set up Advertisement register 2 next */
 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
-	if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full)
+	if (advertising & ADVERTISED_10000baseKR_Full)
 		reg |= 0x80;
 	else
 		reg &= ~0x80;
 
-	if ((pdata->phy.advertising & ADVERTISED_1000baseKX_Full) ||
-	    (pdata->phy.advertising & ADVERTISED_2500baseX_Full))
+	if ((advertising & ADVERTISED_1000baseKX_Full) ||
+	    (advertising & ADVERTISED_2500baseX_Full))
 		reg |= 0x20;
 	else
 		reg &= ~0x20;
@@ -982,12 +995,12 @@ static void xgbe_an73_init(struct xgbe_prv_data *pdata)
 
 	/* Set up Advertisement register 1 last */
 	reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
-	if (pdata->phy.advertising & ADVERTISED_Pause)
+	if (advertising & ADVERTISED_Pause)
 		reg |= 0x400;
 	else
 		reg &= ~0x400;
 
-	if (pdata->phy.advertising & ADVERTISED_Asym_Pause)
+	if (advertising & ADVERTISED_Asym_Pause)
 		reg |= 0x800;
 	else
 		reg &= ~0x800;
@@ -1006,6 +1019,7 @@ static void xgbe_an_init(struct xgbe_prv_data *pdata)
 	pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata);
 	switch (pdata->an_mode) {
 	case XGBE_AN_MODE_CL73:
+	case XGBE_AN_MODE_CL73_REDRV:
 		xgbe_an73_init(pdata);
 		break;
 	case XGBE_AN_MODE_CL37:
@@ -1149,10 +1163,15 @@ static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)
 	if (ret)
 		return ret;
 
-	if (pdata->phy.autoneg != AUTONEG_ENABLE)
-		return xgbe_phy_config_fixed(pdata);
+	if (pdata->phy.autoneg != AUTONEG_ENABLE) {
+		ret = xgbe_phy_config_fixed(pdata);
+		if (ret || !pdata->kr_redrv)
+			return ret;
 
-	netif_dbg(pdata, link, pdata->netdev, "AN PHY configuration\n");
+		netif_dbg(pdata, link, pdata->netdev, "AN redriver support\n");
+	} else {
+		netif_dbg(pdata, link, pdata->netdev, "AN PHY configuration\n");
+	}
 
 	/* Disable auto-negotiation interrupt */
 	disable_irq(pdata->an_irq);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c
index 6c64d11..c75edca 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c
@@ -295,6 +295,11 @@ static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
 	return mode;
 }
 
+static unsigned int xgbe_phy_an_advertising(struct xgbe_prv_data *pdata)
+{
+	return pdata->phy.advertising;
+}
+
 static int xgbe_phy_an_config(struct xgbe_prv_data *pdata)
 {
 	/* Nothing uniquely required for an configuration */
@@ -831,6 +836,8 @@ void xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *phy_if)
 
 	phy_impl->an_config		= xgbe_phy_an_config;
 
+	phy_impl->an_advertising	= xgbe_phy_an_advertising;
+
 	phy_impl->an_outcome		= xgbe_phy_an_outcome;
 
 	phy_impl->kr_training_pre	= xgbe_phy_kr_training_pre;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
index 180e70e..2a134e6 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
@@ -277,6 +277,26 @@ enum xgbe_mdio_reset {
 	XGBE_MDIO_RESET_MAX,
 };
 
+/* Re-driver related definitions */
+enum xgbe_phy_redrv_if {
+	XGBE_PHY_REDRV_IF_MDIO = 0,
+	XGBE_PHY_REDRV_IF_I2C,
+	XGBE_PHY_REDRV_IF_MAX,
+};
+
+enum xgbe_phy_redrv_model {
+	XGBE_PHY_REDRV_MODEL_4223 = 0,
+	XGBE_PHY_REDRV_MODEL_4227,
+	XGBE_PHY_REDRV_MODEL_MAX,
+};
+
+enum xgbe_phy_redrv_mode {
+	XGBE_PHY_REDRV_MODE_CX = 5,
+	XGBE_PHY_REDRV_MODE_SR = 9,
+};
+
+#define XGBE_PHY_REDRV_MODE_REG	0x12b0
+
 /* PHY related configuration information */
 struct xgbe_phy_data {
 	enum xgbe_port_mode port_mode;
@@ -327,6 +347,13 @@ struct xgbe_phy_data {
 	enum xgbe_mdio_reset mdio_reset;
 	unsigned int mdio_reset_addr;
 	unsigned int mdio_reset_gpio;
+
+	/* Re-driver support */
+	unsigned int redrv;
+	unsigned int redrv_if;
+	unsigned int redrv_addr;
+	unsigned int redrv_lane;
+	unsigned int redrv_model;
 };
 
 /* I2C, MDIO and GPIO lines are muxed, so only one device at a time */
@@ -346,6 +373,68 @@ static int xgbe_phy_i2c_xfer(struct xgbe_prv_data *pdata,
 	return pdata->i2c_if.i2c_xfer(pdata, i2c_op);
 }
 
+static int xgbe_phy_redrv_write(struct xgbe_prv_data *pdata, unsigned int reg,
+				unsigned int val)
+{
+	struct xgbe_phy_data *phy_data = pdata->phy_data;
+	struct xgbe_i2c_op i2c_op;
+	__be16 *redrv_val;
+	u8 redrv_data[5], csum;
+	unsigned int i, retry;
+	int ret;
+
+	/* High byte of register contains read/write indicator */
+	redrv_data[0] = ((reg >> 8) & 0xff) << 1;
+	redrv_data[1] = reg & 0xff;
+	redrv_val = (__be16 *)&redrv_data[2];
+	*redrv_val = cpu_to_be16(val);
+
+	/* Calculate 1 byte checksum */
+	csum = 0;
+	for (i = 0; i < 4; i++) {
+		csum += redrv_data[i];
+		if (redrv_data[i] > csum)
+			csum++;
+	}
+	redrv_data[4] = ~csum;
+
+	retry = 1;
+again1:
+	i2c_op.cmd = XGBE_I2C_CMD_WRITE;
+	i2c_op.target = phy_data->redrv_addr;
+	i2c_op.len = sizeof(redrv_data);
+	i2c_op.buf = redrv_data;
+	ret = xgbe_phy_i2c_xfer(pdata, &i2c_op);
+	if (ret) {
+		if ((ret == -EAGAIN) && retry--)
+			goto again1;
+
+		return ret;
+	}
+
+	retry = 1;
+again2:
+	i2c_op.cmd = XGBE_I2C_CMD_READ;
+	i2c_op.target = phy_data->redrv_addr;
+	i2c_op.len = 1;
+	i2c_op.buf = redrv_data;
+	ret = xgbe_phy_i2c_xfer(pdata, &i2c_op);
+	if (ret) {
+		if ((ret == -EAGAIN) && retry--)
+			goto again2;
+
+		return ret;
+	}
+
+	if (redrv_data[0] != 0xff) {
+		netif_dbg(pdata, drv, pdata->netdev,
+			  "Redriver write checksum error\n");
+		ret = -EIO;
+	}
+
+	return ret;
+}
+
 static int xgbe_phy_i2c_write(struct xgbe_prv_data *pdata, unsigned int target,
 			      void *val, unsigned int val_len)
 {
@@ -1144,38 +1233,49 @@ static void xgbe_phy_sfp_detect(struct xgbe_prv_data *pdata)
 	xgbe_put_comm_ownership(pdata);
 }
 
-static enum xgbe_mode xgbe_phy_an37_sgmii_outcome(struct xgbe_prv_data *pdata)
+static void xgbe_phy_phydev_flowctrl(struct xgbe_prv_data *pdata)
 {
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
-	enum xgbe_mode mode;
+	u16 lcl_adv = 0, rmt_adv = 0;
+	u8 fc;
 
-	pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
-	pdata->phy.lp_advertising |= ADVERTISED_TP;
+	pdata->phy.tx_pause = 0;
+	pdata->phy.rx_pause = 0;
 
-	if (pdata->phy.pause_autoneg && phy_data->phydev) {
-		/* Flow control is obtained from the attached PHY */
-		u16 lcl_adv = 0, rmt_adv = 0;
-		u8 fc;
+	if (!phy_data->phydev)
+		return;
 
-		pdata->phy.tx_pause = 0;
-		pdata->phy.rx_pause = 0;
+	if (phy_data->phydev->advertising & ADVERTISED_Pause)
+		lcl_adv |= ADVERTISE_PAUSE_CAP;
+	if (phy_data->phydev->advertising & ADVERTISED_Asym_Pause)
+		lcl_adv |= ADVERTISE_PAUSE_ASYM;
 
-		if (phy_data->phydev->advertising & ADVERTISED_Pause)
-			lcl_adv |= ADVERTISE_PAUSE_CAP;
-		if (phy_data->phydev->advertising & ADVERTISED_Asym_Pause)
-			lcl_adv |= ADVERTISE_PAUSE_ASYM;
+	if (phy_data->phydev->pause) {
+		pdata->phy.lp_advertising |= ADVERTISED_Pause;
+		rmt_adv |= LPA_PAUSE_CAP;
+	}
+	if (phy_data->phydev->asym_pause) {
+		pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause;
+		rmt_adv |= LPA_PAUSE_ASYM;
+	}
 
-		if (phy_data->phydev->pause)
-			rmt_adv |= LPA_PAUSE_CAP;
-		if (phy_data->phydev->asym_pause)
-			rmt_adv |= LPA_PAUSE_ASYM;
+	fc = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
+	if (fc & FLOW_CTRL_TX)
+		pdata->phy.tx_pause = 1;
+	if (fc & FLOW_CTRL_RX)
+		pdata->phy.rx_pause = 1;
+}
 
-		fc = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
-		if (fc & FLOW_CTRL_TX)
-			pdata->phy.tx_pause = 1;
-		if (fc & FLOW_CTRL_RX)
-			pdata->phy.rx_pause = 1;
-	}
+static enum xgbe_mode xgbe_phy_an37_sgmii_outcome(struct xgbe_prv_data *pdata)
+{
+	enum xgbe_mode mode;
+
+	pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
+	pdata->phy.lp_advertising |= ADVERTISED_TP;
+
+	/* Use external PHY to determine flow control */
+	if (pdata->phy.pause_autoneg)
+		xgbe_phy_phydev_flowctrl(pdata);
 
 	switch (pdata->an_status & XGBE_SGMII_AN_LINK_SPEED) {
 	case XGBE_SGMII_AN_LINK_SPEED_100:
@@ -1249,6 +1349,83 @@ static enum xgbe_mode xgbe_phy_an37_outcome(struct xgbe_prv_data *pdata)
 	return mode;
 }
 
+static enum xgbe_mode xgbe_phy_an73_redrv_outcome(struct xgbe_prv_data *pdata)
+{
+	struct xgbe_phy_data *phy_data = pdata->phy_data;
+	enum xgbe_mode mode;
+	unsigned int ad_reg, lp_reg;
+
+	pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
+	pdata->phy.lp_advertising |= ADVERTISED_Backplane;
+
+	/* Use external PHY to determine flow control */
+	if (pdata->phy.pause_autoneg)
+		xgbe_phy_phydev_flowctrl(pdata);
+
+	/* Compare Advertisement and Link Partner register 2 */
+	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
+	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
+	if (lp_reg & 0x80)
+		pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full;
+	if (lp_reg & 0x20)
+		pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full;
+
+	ad_reg &= lp_reg;
+	if (ad_reg & 0x80) {
+		switch (phy_data->port_mode) {
+		case XGBE_PORT_MODE_BACKPLANE:
+			mode = XGBE_MODE_KR;
+			break;
+		default:
+			mode = XGBE_MODE_SFI;
+			break;
+		}
+	} else if (ad_reg & 0x20) {
+		switch (phy_data->port_mode) {
+		case XGBE_PORT_MODE_BACKPLANE:
+			mode = XGBE_MODE_KX_1000;
+			break;
+		case XGBE_PORT_MODE_1000BASE_X:
+			mode = XGBE_MODE_X;
+			break;
+		case XGBE_PORT_MODE_SFP:
+			switch (phy_data->sfp_base) {
+			case XGBE_SFP_BASE_1000_T:
+				if (phy_data->phydev &&
+				    (phy_data->phydev->speed == SPEED_100))
+					mode = XGBE_MODE_SGMII_100;
+				else
+					mode = XGBE_MODE_SGMII_1000;
+				break;
+			case XGBE_SFP_BASE_1000_SX:
+			case XGBE_SFP_BASE_1000_LX:
+			case XGBE_SFP_BASE_1000_CX:
+			default:
+				mode = XGBE_MODE_X;
+				break;
+			}
+			break;
+		default:
+			if (phy_data->phydev &&
+			    (phy_data->phydev->speed == SPEED_100))
+				mode = XGBE_MODE_SGMII_100;
+			else
+				mode = XGBE_MODE_SGMII_1000;
+			break;
+		}
+	} else {
+		mode = XGBE_MODE_UNKNOWN;
+	}
+
+	/* Compare Advertisement and Link Partner register 3 */
+	ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
+	lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
+	if (lp_reg & 0xc000)
+		pdata->phy.lp_advertising |= ADVERTISED_10000baseR_FEC;
+
+	return mode;
+}
+
 static enum xgbe_mode xgbe_phy_an73_outcome(struct xgbe_prv_data *pdata)
 {
 	enum xgbe_mode mode;
@@ -1311,6 +1488,8 @@ static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
 	switch (pdata->an_mode) {
 	case XGBE_AN_MODE_CL73:
 		return xgbe_phy_an73_outcome(pdata);
+	case XGBE_AN_MODE_CL73_REDRV:
+		return xgbe_phy_an73_redrv_outcome(pdata);
 	case XGBE_AN_MODE_CL37:
 		return xgbe_phy_an37_outcome(pdata);
 	case XGBE_AN_MODE_CL37_SGMII:
@@ -1320,6 +1499,63 @@ static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
 	}
 }
 
+static unsigned int xgbe_phy_an_advertising(struct xgbe_prv_data *pdata)
+{
+	struct xgbe_phy_data *phy_data = pdata->phy_data;
+	unsigned int advertising;
+
+	/* Without a re-driver, just return current advertising */
+	if (!phy_data->redrv)
+		return pdata->phy.advertising;
+
+	/* With the KR re-driver we need to advertise a single speed */
+	advertising = pdata->phy.advertising;
+	advertising &= ~ADVERTISED_1000baseKX_Full;
+	advertising &= ~ADVERTISED_10000baseKR_Full;
+
+	switch (phy_data->port_mode) {
+	case XGBE_PORT_MODE_BACKPLANE:
+		advertising |= ADVERTISED_10000baseKR_Full;
+		break;
+	case XGBE_PORT_MODE_BACKPLANE_2500:
+		advertising |= ADVERTISED_1000baseKX_Full;
+		break;
+	case XGBE_PORT_MODE_1000BASE_T:
+	case XGBE_PORT_MODE_1000BASE_X:
+	case XGBE_PORT_MODE_NBASE_T:
+		advertising |= ADVERTISED_1000baseKX_Full;
+		break;
+	case XGBE_PORT_MODE_10GBASE_T:
+		if (phy_data->phydev &&
+		    (phy_data->phydev->speed == SPEED_10000))
+			advertising |= ADVERTISED_10000baseKR_Full;
+		else
+			advertising |= ADVERTISED_1000baseKX_Full;
+		break;
+	case XGBE_PORT_MODE_10GBASE_R:
+		advertising |= ADVERTISED_10000baseKR_Full;
+		break;
+	case XGBE_PORT_MODE_SFP:
+		switch (phy_data->sfp_base) {
+		case XGBE_SFP_BASE_1000_T:
+		case XGBE_SFP_BASE_1000_SX:
+		case XGBE_SFP_BASE_1000_LX:
+		case XGBE_SFP_BASE_1000_CX:
+			advertising |= ADVERTISED_1000baseKX_Full;
+			break;
+		default:
+			advertising |= ADVERTISED_10000baseKR_Full;
+			break;
+		}
+		break;
+	default:
+		advertising |= ADVERTISED_10000baseKR_Full;
+		break;
+	}
+
+	return advertising;
+}
+
 static int xgbe_phy_an_config(struct xgbe_prv_data *pdata)
 {
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
@@ -1364,6 +1600,10 @@ static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata)
 {
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 
+	/* A KR re-driver will always require CL73 AN */
+	if (phy_data->redrv)
+		return XGBE_AN_MODE_CL73_REDRV;
+
 	switch (phy_data->port_mode) {
 	case XGBE_PORT_MODE_BACKPLANE:
 		return XGBE_AN_MODE_CL73;
@@ -1386,6 +1626,61 @@ static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata)
 	}
 }
 
+static int xgbe_phy_set_redrv_mode_mdio(struct xgbe_prv_data *pdata,
+					enum xgbe_phy_redrv_mode mode)
+{
+	struct xgbe_phy_data *phy_data = pdata->phy_data;
+	u16 redrv_reg, redrv_val;
+
+	redrv_reg = XGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
+	redrv_val = (u16)mode;
+
+	return pdata->hw_if.write_ext_mii_regs(pdata, phy_data->redrv_addr,
+					       redrv_reg, redrv_val);
+}
+
+static int xgbe_phy_set_redrv_mode_i2c(struct xgbe_prv_data *pdata,
+				       enum xgbe_phy_redrv_mode mode)
+{
+	struct xgbe_phy_data *phy_data = pdata->phy_data;
+	unsigned int redrv_reg;
+	int ret;
+
+	/* Calculate the register to write */
+	redrv_reg = XGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
+
+	ret = xgbe_phy_redrv_write(pdata, redrv_reg, mode);
+
+	return ret;
+}
+
+static void xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata)
+{
+	struct xgbe_phy_data *phy_data = pdata->phy_data;
+	enum xgbe_phy_redrv_mode mode;
+	int ret;
+
+	if (!phy_data->redrv)
+		return;
+
+	mode = XGBE_PHY_REDRV_MODE_CX;
+	if ((phy_data->port_mode == XGBE_PORT_MODE_SFP) &&
+	    (phy_data->sfp_base != XGBE_SFP_BASE_1000_CX) &&
+	    (phy_data->sfp_base != XGBE_SFP_BASE_10000_CR))
+		mode = XGBE_PHY_REDRV_MODE_SR;
+
+	ret = xgbe_phy_get_comm_ownership(pdata);
+	if (ret)
+		return;
+
+	if (phy_data->redrv_if)
+		xgbe_phy_set_redrv_mode_i2c(pdata, mode);
+	else
+		xgbe_phy_set_redrv_mode_mdio(pdata, mode);
+
+	xgbe_put_comm_ownership(pdata);
+}
+
 static void xgbe_phy_start_ratechange(struct xgbe_prv_data *pdata)
 {
 	if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
@@ -1457,6 +1752,8 @@ static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata)
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 	unsigned int s0;
 
+	xgbe_phy_set_redrv_mode(pdata);
+
 	xgbe_phy_start_ratechange(pdata);
 
 	/* 10G/SFI */
@@ -1492,6 +1789,8 @@ static void xgbe_phy_x_mode(struct xgbe_prv_data *pdata)
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 	unsigned int s0;
 
+	xgbe_phy_set_redrv_mode(pdata);
+
 	xgbe_phy_start_ratechange(pdata);
 
 	/* 1G/X */
@@ -1516,6 +1815,8 @@ static void xgbe_phy_sgmii_1000_mode(struct xgbe_prv_data *pdata)
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 	unsigned int s0;
 
+	xgbe_phy_set_redrv_mode(pdata);
+
 	xgbe_phy_start_ratechange(pdata);
 
 	/* 1G/SGMII */
@@ -1540,6 +1841,8 @@ static void xgbe_phy_sgmii_100_mode(struct xgbe_prv_data *pdata)
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 	unsigned int s0;
 
+	xgbe_phy_set_redrv_mode(pdata);
+
 	xgbe_phy_start_ratechange(pdata);
 
 	/* 1G/SGMII */
@@ -1564,6 +1867,8 @@ static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata)
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 	unsigned int s0;
 
+	xgbe_phy_set_redrv_mode(pdata);
+
 	xgbe_phy_start_ratechange(pdata);
 
 	/* 10G/KR */
@@ -1588,6 +1893,8 @@ static void xgbe_phy_kx_2500_mode(struct xgbe_prv_data *pdata)
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 	unsigned int s0;
 
+	xgbe_phy_set_redrv_mode(pdata);
+
 	xgbe_phy_start_ratechange(pdata);
 
 	/* 2.5G/KX */
@@ -1612,6 +1919,8 @@ static void xgbe_phy_kx_1000_mode(struct xgbe_prv_data *pdata)
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 	unsigned int s0;
 
+	xgbe_phy_set_redrv_mode(pdata);
+
 	xgbe_phy_start_ratechange(pdata);
 
 	/* 1G/KX */
@@ -2232,6 +2541,30 @@ static int xgbe_phy_mdio_reset(struct xgbe_prv_data *pdata)
 	return ret;
 }
 
+static bool xgbe_phy_redrv_error(struct xgbe_phy_data *phy_data)
+{
+	if (!phy_data->redrv)
+		return false;
+
+	if (phy_data->redrv_if >= XGBE_PHY_REDRV_IF_MAX)
+		return true;
+
+	switch (phy_data->redrv_model) {
+	case XGBE_PHY_REDRV_MODEL_4223:
+		if (phy_data->redrv_lane > 3)
+			return true;
+		break;
+	case XGBE_PHY_REDRV_MODEL_4227:
+		if (phy_data->redrv_lane > 1)
+			return true;
+		break;
+	default:
+		return true;
+	}
+
+	return false;
+}
+
 static int xgbe_phy_mdio_reset_setup(struct xgbe_prv_data *pdata)
 {
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
@@ -2481,6 +2814,20 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
 		dev_dbg(pdata->dev, "mdio addr=%u\n", phy_data->mdio_addr);
 	}
 
+	reg = XP_IOREAD(pdata, XP_PROP_4);
+	phy_data->redrv = XP_GET_BITS(reg, XP_PROP_4, REDRV_PRESENT);
+	phy_data->redrv_if = XP_GET_BITS(reg, XP_PROP_4, REDRV_IF);
+	phy_data->redrv_addr = XP_GET_BITS(reg, XP_PROP_4, REDRV_ADDR);
+	phy_data->redrv_lane = XP_GET_BITS(reg, XP_PROP_4, REDRV_LANE);
+	phy_data->redrv_model = XP_GET_BITS(reg, XP_PROP_4, REDRV_MODEL);
+	if (phy_data->redrv && netif_msg_probe(pdata)) {
+		dev_dbg(pdata->dev, "redrv present\n");
+		dev_dbg(pdata->dev, "redrv i/f=%u\n", phy_data->redrv_if);
+		dev_dbg(pdata->dev, "redrv addr=%#x\n", phy_data->redrv_addr);
+		dev_dbg(pdata->dev, "redrv lane=%u\n", phy_data->redrv_lane);
+		dev_dbg(pdata->dev, "redrv model=%u\n", phy_data->redrv_model);
+	}
+
 	/* Validate the connection requested */
 	if (xgbe_phy_conn_type_mismatch(pdata)) {
 		dev_err(pdata->dev, "phy mode/connection mismatch (%#x/%#x)\n",
@@ -2499,6 +2846,13 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
 	if (ret)
 		return ret;
 
+	/* Validate the re-driver information */
+	if (xgbe_phy_redrv_error(phy_data)) {
+		dev_err(pdata->dev, "phy re-driver settings error\n");
+		return -EINVAL;
+	}
+	pdata->kr_redrv = phy_data->redrv;
+
 	/* Indicate current mode is unknown */
 	phy_data->cur_mode = XGBE_MODE_UNKNOWN;
 
@@ -2651,6 +3005,29 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
 		dev_dbg(pdata->dev, "phy supported=%#x\n",
 			pdata->phy.supported);
 
+	if ((phy_data->conn_type & XGBE_CONN_TYPE_MDIO) &&
+	    (phy_data->phydev_mode != XGBE_MDIO_MODE_NONE)) {
+		ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->mdio_addr,
+						    phy_data->phydev_mode);
+		if (ret) {
+			dev_err(pdata->dev,
+				"mdio port/clause not compatible (%d/%u)\n",
+				phy_data->mdio_addr, phy_data->phydev_mode);
+			return -EINVAL;
+		}
+	}
+
+	if (phy_data->redrv && !phy_data->redrv_if) {
+		ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->redrv_addr,
+						    XGBE_MDIO_MODE_CL22);
+		if (ret) {
+			dev_err(pdata->dev,
+				"redriver mdio port not compatible (%u)\n",
+				phy_data->redrv_addr);
+			return -EINVAL;
+		}
+	}
+
 	/* Register for driving external PHYs */
 	mii = devm_mdiobus_alloc(pdata->dev);
 	if (!mii) {
@@ -2700,5 +3077,7 @@ void xgbe_init_function_ptrs_phy_v2(struct xgbe_phy_if *phy_if)
 
 	phy_impl->an_config		= xgbe_phy_an_config;
 
+	phy_impl->an_advertising	= xgbe_phy_an_advertising;
+
 	phy_impl->an_outcome		= xgbe_phy_an_outcome;
 }
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index f3cbdb4..d821d1e 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -508,6 +508,7 @@ enum xgbe_xpcs_access {
 
 enum xgbe_an_mode {
 	XGBE_AN_MODE_CL73 = 0,
+	XGBE_AN_MODE_CL73_REDRV,
 	XGBE_AN_MODE_CL37,
 	XGBE_AN_MODE_CL37_SGMII,
 	XGBE_AN_MODE_NONE,
@@ -807,6 +808,9 @@ struct xgbe_phy_impl_if {
 	/* Configure auto-negotiation settings */
 	int (*an_config)(struct xgbe_prv_data *);
 
+	/* Set/override auto-negotiation advertisement settings */
+	unsigned int (*an_advertising)(struct xgbe_prv_data *);
+
 	/* Process results of auto-negotiation */
 	enum xgbe_mode (*an_outcome)(struct xgbe_prv_data *);
 
@@ -1124,6 +1128,8 @@ struct xgbe_prv_data {
 	unsigned long link_check;
 	struct completion mdio_complete;
 
+	unsigned int kr_redrv;
+
 	char an_name[IFNAMSIZ + 32];
 	struct workqueue_struct *an_workqueue;
 

^ permalink raw reply related

* RE: [PATCH net-next v1 02/21] amd-xgbe: Prepare for priority-based FIFO allocation
From: Mintz, Yuval @ 2016-11-03 13:51 UTC (permalink / raw)
  To: Tom Lendacky, netdev@vger.kernel.org; +Cc: Florian Fainelli, David Miller
In-Reply-To: <20161103132804.3437.40002.stgit@tlendack-t1.amdoffice.net>

> +static void xgbe_calculate_equal_fifo(unsigned int fifo_size,
> +				      unsigned int queue_count,
> +				      unsigned int *fifo)
> +{
...
> +
> +	return;
>  }

No need for explicit return.


^ permalink raw reply

* Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
From: Christoph Hellwig @ 2016-11-03 14:14 UTC (permalink / raw)
  To: Alexander Duyck
  Cc: linux-mm, akpm, netdev, linux-kernel, Konrad Rzeszutek Wilk
In-Reply-To: <20161102111211.79519.39931.stgit@ahduyck-blue-test.jf.intel.com>

On Wed, Nov 02, 2016 at 07:12:31AM -0400, Alexander Duyck wrote:
> There are no users for swiotlb_map_sg or swiotlb_unmap_sg so we might as
> well just drop them.

FYI, I sent the same patch already on Sep, 11 and Konrad already ACKed
it:

https://lkml.org/lkml/2016/9/11/112
https://lkml.org/lkml/2016/9/16/474

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: bpf: kernel BUG in htab_elem_free
From: Dmitry Vyukov @ 2016-11-03 14:15 UTC (permalink / raw)
  To: Alexei Starovoitov, netdev, Daniel Borkmann; +Cc: LKML, syzkaller
In-Reply-To: <CACT4Y+YUWArFF=6VGJvzTEr7C7E323gOCno7fyw36xBYC7MH=w@mail.gmail.com>

On Wed, Nov 2, 2016 at 11:14 PM, Dmitry Vyukov <dvyukov@google.com> wrote:
> Here we go.
>
> The following program triggers kernel BUG in htab_elem_free.
> On commit 0c183d92b20b5c84ca655b45ef57b3318b83eb9e (Oct 31).
> Run as "while true; do ./a.out; done".
>
> ------------[ cut here ]------------
> kernel BUG at mm/slub.c:3866!
> invalid opcode: 0000 [#1] SMP KASAN
> Modules linked in:
> CPU: 1 PID: 1542 Comm: kworker/1:2 Not tainted 4.9.0-rc3+ #20
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> Workqueue: events bpf_map_free_deferred
> task: ffff88003b9c0040 task.stack: ffff88003cb70000
> RIP: 0010:[<ffffffff814c9f00>]  [<ffffffff814c9f00>] kfree+0x140/0x1a0
> RSP: 0018:ffff88003cb77c50  EFLAGS: 00010246
> RAX: ffffea0000fb0aa0 RBX: ffff88003ec2a1a8 RCX: 0000000000000000
> RDX: 0000000000000000 RSI: 1ffff10007b50401 RDI: ffff88003ec2a1a8
> RBP: ffff88003cb77c70 R08: 0000000000021800 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000000 R12: ffffea0000fb0a80
> R13: ffffffff81392bcb R14: 0000000000000000 R15: ffff88003ec2a1a8
> FS:  0000000000000000(0000) GS:ffff88003ed00000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00000000205d7000 CR3: 0000000037d29000 CR4: 00000000000006e0
> Stack:
>  dffffc0000000000 ffff88003da82008 ffff88003b75bb88 0000000000000000
>  ffff88003cb77ce0 ffffffff81392bcb ffffffff81acf4f8 ffff88003b75bc04
>  ffff88003b75bbe0 ffffed00076eb772 ffff88003b75bb90 000000003cb77ce0
> Call Trace:
>  [<     inline     >] htab_elem_free kernel/bpf/hashtab.c:388
>  [<     inline     >] delete_all_elements kernel/bpf/hashtab.c:690
>  [<ffffffff81392bcb>] htab_map_free+0x30b/0x470 kernel/bpf/hashtab.c:711
>  [<ffffffff8137e9dc>] bpf_map_free_deferred+0xac/0xd0 kernel/bpf/syscall.c:97
>  [<ffffffff8114f937>] process_one_work+0x8a7/0x1300 kernel/workqueue.c:2096
>  [<ffffffff8115047d>] worker_thread+0xed/0x14e0 kernel/workqueue.c:2230
>  [<ffffffff811619dc>] kthread+0x1ec/0x260 kernel/kthread.c:209
>  [<ffffffff82fa78c5>] ret_from_fork+0x25/0x30 arch/x86/entry/entry_64.S:433
> Code: 83 c4 18 48 89 da 4c 89 ee ff d0 49 8b 04 24 48 85 c0 75 e6 e9
> e9 fe ff ff 49 8b 04 24 f6 c4 40 75 0b 49 8b 44 24 20 a8 01 75 02 <0f>
> 0b 48 89 df e8 56 35 00 00 49 8b 04 24 31 f6 f6 c4 40 74 05
> RIP  [<     inline     >] PageCompound ./include/linux/page-flags.h:157
> RIP  [<ffffffff814c9f00>] kfree+0x140/0x1a0 mm/slub.c:3866
>  RSP <ffff88003cb77c50>
> ---[ end trace 1dc58d6aeb2596aa ]---
> ==================================================================
> BUG: KASAN: stack-out-of-bounds in complete+0x68/0x70 at addr ffff88003cb77ed8
> Read of size 4 by task kworker/1:2/1542
> page:ffffea0000f2ddc0 count:0 mapcount:0 mapping:          (null) index:0x0
> flags: 0x100000000000000()
> page dumped because: kasan: bad access detected
> CPU: 1 PID: 1542 Comm: kworker/1:2 Tainted: G      D         4.9.0-rc3+ #20
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>  ffff88003cb77ce0 ffffffff81acf609 ffffed000796efdb ffffed000796efdb
>  0000000000000004 0000000000000000 ffff88003cb77d60 ffffffff814cdbfb
>  ffff88003c8d97c8 dffffc0000000000 ffffffff811dd038 0000000000000097
> Call Trace:
>  [<     inline     >] __dump_stack lib/dump_stack.c:15
>  [<ffffffff81acf609>] dump_stack+0x83/0xba lib/dump_stack.c:51
>  [<     inline     >] kasan_report_error mm/kasan/report.c:204
>  [<ffffffff814cdbfb>] kasan_report+0x4cb/0x500 mm/kasan/report.c:303
>  [<ffffffff814cdc84>] __asan_report_load4_noabort+0x14/0x20
> mm/kasan/report.c:328
>  [<ffffffff811dd038>] complete+0x68/0x70 kernel/sched/completion.c:34
>  [<     inline     >] complete_vfork_done kernel/fork.c:1030
>  [<ffffffff810fa8c2>] mm_release+0x222/0x3f0 kernel/fork.c:1114
>  [<     inline     >] exit_mm kernel/exit.c:467
>  [<ffffffff8110b501>] do_exit+0x3a1/0x2960 kernel/exit.c:815
>  [<ffffffff82fa8b97>] rewind_stack_do_exit+0x17/0x20
> arch/x86/entry/entry_64.S:1526
> Memory state around the buggy address:
>  ffff88003cb77d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>  ffff88003cb77e00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f4 f4 f4
>>ffff88003cb77e80: f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 00 00 f4 f4
>                                                     ^
>  ffff88003cb77f00: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
>  ffff88003cb77f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> ==================================================================
> BUG: unable to handle kernel
> paging request at ffffffffffffffd8
> IP: [<ffffffff81163c5d>] kthread_data+0x4d/0x70 kernel/kthread.c:137
> PGD 360d067 [   48.581115] PUD 360f067
> PMD 0 [   48.581840]
> Oops: 0000 [#2] SMP KASAN
> Modules linked in:
> CPU: 1 PID: 1542 Comm: kworker/1:2 Tainted: G    B D         4.9.0-rc3+ #20
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> task: ffff88003b9c0040 task.stack: ffff88003cb70000
> RIP: 0010:[<ffffffff81163c5d>]  [<ffffffff81163c5d>] kthread_data+0x4d/0x70
> RSP: 0018:ffff88003cb77c78  EFLAGS: 00010046
> RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
> RDX: 1ffffffffffffffb RSI: ffff88003b9c00c0 RDI: ffffffffffffffd8
> RBP: ffff88003cb77c80 R08: ffff88003ed20a48 R09: ffff88003ed20a40
> R10: 0000000000000000 R11: 0000000000000000 R12: ffff88003ed20980
> R13: ffff88003b9c0040 R14: ffff88003b9c0094 R15: 0000000000000040
> FS:  0000000000000000(0000) GS:ffff88003ed00000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000000000028 CR3: 000000000360c000 CR4: 00000000000006e0
> Stack:
>  ffff88003b9c0040 ffff88003cb77ca0 ffffffff81155e77 0000000000020980
>  ffff88003ed20980 ffff88003cb77db8 ffffffff82f9b1a2 0000000000000000
>  ffff88003ddd2670 00ff88003ddd2640 ffff88003ed211f8 1ffff1000796ef9e
> Call Trace:
>  [<ffffffff81155e77>] wq_worker_sleeping+0x17/0x210 kernel/workqueue.c:876
>  [<ffffffff82f9b1a2>] __schedule+0xc62/0x1730 kernel/sched/core.c:3380
>  [<ffffffff8118c781>] do_task_dead+0x81/0xa0 kernel/sched/core.c:3431
>  [<ffffffff8110c7f8>] do_exit+0x1698/0x2960 kernel/exit.c:885
>  [<ffffffff82fa8b97>] rewind_stack_do_exit+0x17/0x20
> arch/x86/entry/entry_64.S:1526
> Code: c1 ea 03 80 3c 02 00 75 29 48 8b 9b 30 05 00 00 48 b8 00 00 00
> 00 00 fc ff df 48 8d 7b d8 48 89 fa 48 c1 ea 03 80 3c 02 00 75 0e <48>
> 8b 43 d8 5b 5d c3 e8 27 a0 36 00 eb d0 e8 20 a0 36 00 eb eb
> RIP  [<ffffffff81163c5d>] kthread_data+0x4d/0x70 kernel/kthread.c:137
>  RSP <ffff88003cb77c78>
> CR2: ffffffffffffffd8
> ---[ end trace 1dc58d6aeb2596ab ]---
> Fixing recursive fault but reboot is needed!
>
>
> // autogenerated by syzkaller (http://github.com/google/syzkaller)
>
> #ifndef __NR_bpf
> #define __NR_bpf 321
> #endif
>
> #include <fcntl.h>
> #include <pthread.h>
> #include <signal.h>
> #include <stddef.h>
> #include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/ioctl.h>
> #include <sys/stat.h>
> #include <sys/syscall.h>
> #include <sys/types.h>
> #include <unistd.h>
>
> long r[14];
> void* thr(void* arg)
> {
>   switch ((long)arg) {
>   case 0:
>     r[0] =
>         syscall(__NR_mmap, 0x20000000ul, 0x16000ul, 0x3ul,
>                         0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0);
>     break;
>   case 1:
>     (*(uint32_t*)0x20011000 = (uint32_t)0x1);
>     (*(uint32_t*)0x20011004 = (uint32_t)0x8);
>     (*(uint32_t*)0x20011008 = (uint32_t)0x3);
>     (*(uint32_t*)0x2001100c = (uint32_t)0x1);
>     (*(uint32_t*)0x20011010 = (uint32_t)0x1);
>     r[6] = syscall(__NR_bpf, 0x0ul, 0x20011000ul, 0x14ul, 0, 0,
>                            0, 0, 0, 0);
>     break;
>   case 2:
>     (*(uint32_t*)0x20013000 = r[6]);
>     (*(uint64_t*)0x20013008 = (uint64_t)0x20013fb3);
>     (*(uint64_t*)0x20013010 = (uint64_t)0x20012ff1);
>     (*(uint64_t*)0x20013018 = (uint64_t)0x0);
>     (memcpy(
>         (void*)0x20013fb3,
>         "\x3e\x51\x32\xbe\xd5\x24\x20\xb2\x50\x7a\x4d\xb5\xec\xb3\x8f"
>         "\x65\x7f\xac\x61\x9a\xf0\x29\x3f\x77\x07\x2f\x2f\x60\xe9\x78"
>         "\xc5\x79\x45\x16\x67\xf6\x64\xb4\xd5\xb2\x11\x88\x5f\x4f\x32"
>         "\xba\xa8\x80\x8f\x7a\xea\x01\x1d\xe4\x08\xa4\x65\x73\x07\x91"
>         "\x48\xd5\xc3\xf2\xc4\x08\x29\x8f\x88\x95\xc3\xd5\xf6\x86\x0f"
>         "\x42\xab\x05\xf7\xfa\x2b\x12\x78\xb3\x4d\x17\x8c\x27\x57\x8b"
>         "\x79\xdc\x4f\x8a\x7a\xf5\x8c\x8a\xc2\x18\x03\xa0\xf9\x5f\x7a",
>         105));
>     (memcpy(
>         (void*)0x20012ff1,
>         "\xb1\xb0\x4b\x14\x9e\xfa\xbc\xb2\xaf\x4b\x4a\x02\xbc\x9b\xc5",
>         15));
>     r[13] = syscall(__NR_bpf, 0x2ul, 0x20013000ul, 0x20ul, 0, 0,
>                             0, 0, 0, 0);
>     break;
>   }
>   return 0;
> }
>
> int main()
> {
>   long i;
>   pthread_t th[6];
>
>   memset(r, -1, sizeof(r));
>   srand(getpid());
>   for (i = 0; i < 3; i++) {
>     pthread_create(&th[i], 0, thr, (void*)i);
>     usleep(10000);
>   }
>   for (i = 0; i < 3; i++) {
>     pthread_create(&th[3 + i], 0, thr, (void*)i);
>     if (rand() % 2)
>       usleep(rand() % 10000);
>   }
>   usleep(100000);
>   return 0;
> }


Sometimes it crashes with "unable to handle kernel paging request" :

BUG: unable to handle kernel paging request at ffffeb83fffec020
IP: [<     inline     >] virt_to_head_page include/linux/mm.h:555
IP: [<ffffffff814c9e15>] kfree+0x55/0x1a0 mm/slub.c:3864
PGD 0 [ 1103.309066]
Oops: 0000 [#1] SMP KASAN
Dumping ftrace buffer:
   (ftrace buffer empty)
Modules linked in:
CPU: 3 PID: 5460 Comm: kworker/3:3 Not tainted 4.9.0-rc3+ #20
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Workqueue: events bpf_map_free_deferred
task: ffff8800676b6e40 task.stack: ffff880067680000
RIP: 0010:[<ffffffff814c9e15>]  [<     inline     >] virt_to_head_page
include/linux/mm.h:555
RIP: 0010:[<ffffffff814c9e15>]  [<ffffffff814c9e15>] kfree+0x55/0x1a0
mm/slub.c:3864
RSP: 0018:ffff880067687c50  EFLAGS: 00010286
RAX: ffffea0000000000 RBX: ffffe8ffffb00748 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 1ffff1000db56cb5 RDI: ffffe8ffffb00748
RBP: ffff880067687c70 R08: 0000000000003400 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: ffffeb83fffec000
R13: ffffffff81392bcb R14: 0000000000000000 R15: ffffe8ffffb00748
FS:  0000000000000000(0000) GS:ffff88006e500000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffeb83fffec020 CR3: 000000003d24f000 CR4: 00000000000006e0
DR0: 0000000000000007 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000600
Stack:
 dffffc0000000000 ffff88006dab65a8 ffff88006d0490c8 0000000000000000
 ffff880067687ce0 ffffffff81392bcb ffffffff81acf4f8 ffff88006d049144
 ffff88006d049120 ffffed000da0921a ffff88006d0490d0 0000000067687ce0
Call Trace:
 [<     inline     >] htab_elem_free kernel/bpf/hashtab.c:388
 [<     inline     >] delete_all_elements kernel/bpf/hashtab.c:690
 [<ffffffff81392bcb>] htab_map_free+0x30b/0x470 kernel/bpf/hashtab.c:711
 [<ffffffff8137e9dc>] bpf_map_free_deferred+0xac/0xd0 kernel/bpf/syscall.c:97
 [<ffffffff8114f937>] process_one_work+0x8a7/0x1300 kernel/workqueue.c:2096
 [<ffffffff8115047d>] worker_thread+0xed/0x14e0 kernel/workqueue.c:2230
 [<ffffffff811619dc>] kthread+0x1ec/0x260 kernel/kthread.c:209
 [<ffffffff82fa78c5>] ret_from_fork+0x25/0x30 arch/x86/entry/entry_64.S:433
Code: 48 01 d8 0f 82 53 01 00 00 49 bc 00 00 00 80 ff 77 00 00 49 01
c4 48 b8 00 00 00 00 00 ea ff ff 49 c1 ec 0c 49 c1 e4 06 49 01 c4 <49>
8b 44 24 20 48 8d 50 ff a8 01 4c 0f 45 e2 49 8b 54 24 20 48
RIP  [<     inline     >] virt_to_head_page include/linux/mm.h:555
RIP  [<ffffffff814c9e15>] kfree+0x55/0x1a0 mm/slub.c:3864
 RSP <ffff880067687c50>
CR2: ffffeb83fffec020
---[ end trace 9271605118c02ee3 ]---
Kernel panic - not syncing: Fatal exception
Dumping ftrace buffer:
   (ftrace buffer empty)
Kernel Offset: disabled
reboot: cpu_has_vmx: ecx=80a02021 1

^ permalink raw reply

* Re: [PATCH net-next v2 0/5] bpf: BPF for lightweight tunnel encapsulation
From: Thomas Graf @ 2016-11-03 14:16 UTC (permalink / raw)
  To: Hannes Frederic Sowa
  Cc: Tom Herbert, David S. Miller, Alexei Starovoitov, Daniel Borkmann,
	roopa, netdev
In-Reply-To: <7ac775f4-4638-3bd0-f6f8-e54c7d26e8d8@stressinduktion.org>

On 2 November 2016 at 04:48, Hannes Frederic Sowa
<hannes@stressinduktion.org> wrote:
> On Wed, Nov 2, 2016, at 00:07, Tom Herbert wrote:
>> On the other hand, I'm not really sure how to implement for this level
>> of performance this in LWT+BPF either. It seems like one way to do
>> that would be to create a program each destination and set it each
>> host. As you point out would create a million different programs which
>> doesn't seem manageable. I don't think the BPF map works either since
>> that implies we need a lookup (?). It seems like what we need is one
>> program but allow it to be parameterized with per destination
>> information saved in the route (LWT structure).
>
> Yes, that is my proposal. Just using the dst entry as meta-data (which
> can actually also be an ID for the network namespace the packet is
> coming from).

I have no objection to doing this on top of this series.

> My concern with using BPF is that the rest of the kernel doesn't really
> see the semantics and can't optimize or cache at specific points,
> because the kernel cannot introspect what the BPF program does (for
> metadata manipulation, one can e.g. specifiy that the program is "pure",
> and always provides the same output for some specified given input, thus
> things can be cached and memorized, but that framework seems very hard
> to build).

So you want to reintroduce a routing cache? Each packet needs to pass
through the BPF program anyway for accounting purposes. This is not
just about getting the packets out the right nexthop in the fastest
possible way.

> I also fear this becomes a kernel by-pass:
>
> It might be very hard e.g. to apply NFT/netfilter to such packets, if
> e.g. a redirect happens suddenly and packet flow is diverted from the
> one the user sees currently based on the interfaces and routing tables.

The LWT xmit hook is after the POST_ROUTING hook. The input and output
hook cannot redirect and output will become read-only just like input
already is. We are not bypassing anything. Please stop throwing the
word bypass around. This is just a false claim.

> That's why I am in favor of splitting this patchset down and allow the
> policies that should be expressed by BPF programs being applied to the
> specific subsystems (I am not totally against a generic BPF hook in
> input or output of the protocol engines). E.g. can we deal with static
> rewriting of L2 addresses in the neighbor cache? We already provide a
> fast header cache for L2 data which might be used here?

Split what? What policies?

I have two primary use cases for this:
1) Traffic into local containers: Containers are only supposed to do
L3, all L2 traffic is dropped for security reasons. The L2 header for
any packets in and out of the container is fixed and does not require
any sort of resolving. I in order to feed packets from the local host
into the containers, a route with the container prefix is set up. It
points to a nexthop address which appears behind a veth pair. A BPF
program is listening at tc ingress on the veth pair and will enforce
policies and do accounting. It requires very ugly hacks because Linux
does not like to do forwarding to an address which is considered
local. It works but it is a hack.

What I want to do instead is to run the BPF program for the route
directly, apply the policies, do accounting, push the fixed dummy L2
header and redirect it to the container. If someone has netfilter
rules installed, they will still apply. Nothing is hidden.

2) For external traffic that is coming in. We have a BPF program
listening on tc ingress which matches on the destination address on
all incoming traffic. If the packet is a for a container, we perform
the same actions as above. In this case we are bypassing the routing
table. This is ugly. What I want to do instead is to have the
container prefix invoke the BPF program so all packets have a route
lookup performed and netfilter filtering performed, only after that,
the BPF program is invoked exclusively for the packets destined for
local containers. Yes, it would be possible to redirect into a
temporary veth again and listen on that but it again requires to fake
a L2 segment which is just unnecessary and slow.

This is not hiding anything and it is not bypassing anything.

^ permalink raw reply

* Re: [PATCH net-next v1 17/21] amd-xgbe: Add I2C support for determining SFP media types
From: Andrew Lunn @ 2016-11-03 14:28 UTC (permalink / raw)
  To: Tom Lendacky; +Cc: netdev, Florian Fainelli, David Miller
In-Reply-To: <20161103133036.3437.71231.stgit@tlendack-t1.amdoffice.net>

On Thu, Nov 03, 2016 at 08:30:36AM -0500, Tom Lendacky wrote:
> Add support to initialize and use the I2C controller within the hardware
> in order to determine the SFP media type that is installed.

Hi Tom

Did you see the work Russell King did for phylink?

https://lwn.net/Articles/667055/

Rather than doing your own proprietary i2c infrastructure, use the
standard Linux i2c infrastructure. The SFP modules are then just
normal i2c devices on a normal i2c bus. The work Russell did can then
access them, export them to user space, get the PHY modes correctly
setup, etc.

       Andrew

^ permalink raw reply

* Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
From: Konrad Rzeszutek Wilk @ 2016-11-03 14:29 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Alexander Duyck, linux-mm, akpm, netdev, linux-kernel
In-Reply-To: <20161103141446.GA29720@infradead.org>

On Thu, Nov 03, 2016 at 07:14:46AM -0700, Christoph Hellwig wrote:
> On Wed, Nov 02, 2016 at 07:12:31AM -0400, Alexander Duyck wrote:
> > There are no users for swiotlb_map_sg or swiotlb_unmap_sg so we might as
> > well just drop them.
> 
> FYI, I sent the same patch already on Sep, 11 and Konrad already ACKed
> it:
> 
> https://lkml.org/lkml/2016/9/11/112
> https://lkml.org/lkml/2016/9/16/474

Somehow I thought you wanted to put them through your tree (which
is why I acked them).

I can take them and also the first couple of Alexander through
my tree. Or if it makes it simpler - they can go through the -mm tree?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH net-next v2 1/1] driver: veth: Refine the statistics codes of veth driver
From: Eric Dumazet @ 2016-11-03 14:31 UTC (permalink / raw)
  To: Gao Feng
  Cc: David S. Miller, Cong Wang, Vijay Pandurangan, Evan Jones, pabeni,
	Linux Kernel Network Developers
In-Reply-To: <CA+6hz4r9zkPp7-mG7b98ocPvjTiheSnEBMjffSkLXD1MM-aMtg@mail.gmail.com>

On Thu, 2016-11-03 at 21:39 +0800, Gao Feng wrote:
> Hi Eric,
> 
> On Thu, Nov 3, 2016 at 9:30 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > On Thu, 2016-11-03 at 21:03 +0800, fgao@ikuai8.com wrote:
> >> From: Gao Feng <fgao@ikuai8.com>
> >>
> >> The dropped count of veth is located in struct veth_priv, but other
> >> statistics like packets and bytes are in another struct pcpu_vstats.
> >> Now keep these three counters in the same struct.
> >>
> >> Signed-off-by: Gao Feng <fgao@ikuai8.com>
> >> ---
> >>  v2: Use right "peer" instead of "dev";
> >>  v1: Initial version
> >
> > May I ask : Why ?
> 
> Just because I think statistics should be in the same struct.

That is not a good reason then.

> 
> >
> > We did that because there was no point making per-cpu requirements
> > bigger, for a counter that is hardly ever updated.
> >
> > Do you have a real case where performance dropping packets in a driver
> > is needed ?
> 
> No, I haven't met the performance issue now.

OK then kill this patch.

> 
> >
> > At some point we will have to stop dumb percpu explosion, when we have
> > 128+ cores per host. Folding all these percpu counters is taking a lot
> > of time too.
> >
> >
> >
> Ok, I get it. It is designed specially to put the dropped counter as
> atomic counter, not percpu.
> But I have one question that when put the counters as percpu, and when not?

Because the regular fast path needs to be fast ?

Try to _use_ veth without these percpu stats and be prepared to be
shocked.

^ permalink raw reply

* Re: [PATCH net-next v2 1/1] driver: veth: Refine the statistics codes of veth driver
From: Gao Feng @ 2016-11-03 14:38 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S. Miller, Cong Wang, Vijay Pandurangan, Evan Jones, pabeni,
	Linux Kernel Network Developers
In-Reply-To: <1478183516.7065.440.camel@edumazet-glaptop3.roam.corp.google.com>

On Thu, Nov 3, 2016 at 10:31 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Thu, 2016-11-03 at 21:39 +0800, Gao Feng wrote:
>> Hi Eric,
>>
>> On Thu, Nov 3, 2016 at 9:30 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>> > On Thu, 2016-11-03 at 21:03 +0800, fgao@ikuai8.com wrote:
>> >> From: Gao Feng <fgao@ikuai8.com>
>> >>
>> >> The dropped count of veth is located in struct veth_priv, but other
>> >> statistics like packets and bytes are in another struct pcpu_vstats.
>> >> Now keep these three counters in the same struct.
>> >>
>> >> Signed-off-by: Gao Feng <fgao@ikuai8.com>
>> >> ---
>> >>  v2: Use right "peer" instead of "dev";
>> >>  v1: Initial version
>> >
>> > May I ask : Why ?
>>
>> Just because I think statistics should be in the same struct.
>
> That is not a good reason then.

Because other net devices put the statistics together.
Take tun/tap as example, it is a virtual device, but its all
statistics are percpu including dropped.

Regards
Feng

>
>>
>> >
>> > We did that because there was no point making per-cpu requirements
>> > bigger, for a counter that is hardly ever updated.
>> >
>> > Do you have a real case where performance dropping packets in a driver
>> > is needed ?
>>
>> No, I haven't met the performance issue now.
>
> OK then kill this patch.
>
>>
>> >
>> > At some point we will have to stop dumb percpu explosion, when we have
>> > 128+ cores per host. Folding all these percpu counters is taking a lot
>> > of time too.
>> >
>> >
>> >
>> Ok, I get it. It is designed specially to put the dropped counter as
>> atomic counter, not percpu.
>> But I have one question that when put the counters as percpu, and when not?
>
> Because the regular fast path needs to be fast ?
>
> Try to _use_ veth without these percpu stats and be prepared to be
> shocked.
>
>
>

^ permalink raw reply

* Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
From: Christoph Hellwig @ 2016-11-03 14:45 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: Christoph Hellwig, Alexander Duyck, linux-mm, akpm, netdev,
	linux-kernel
In-Reply-To: <20161103142952.GJ28691@localhost.localdomain>

On Thu, Nov 03, 2016 at 10:29:52AM -0400, Konrad Rzeszutek Wilk wrote:
> Somehow I thought you wanted to put them through your tree (which
> is why I acked them).
> 
> I can take them and also the first couple of Alexander through
> my tree. Or if it makes it simpler - they can go through the -mm tree?

I don't have a tree for it, so I kinda expected you to pick it up.
But I'm also fine with you just Acking the version from Alex and having
him funnel it through whatever tree he wants to get his patches in
through.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* [PATCH 08/25] net/dev: Convert to hotplug state machine
From: Sebastian Andrzej Siewior @ 2016-11-03 14:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: rt, Sebastian Andrzej Siewior, David S. Miller, netdev,
	Thomas Gleixner
In-Reply-To: <20161103145021.28528-1-bigeasy@linutronix.de>

Install the callbacks via the state machine.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/cpuhotplug.h |  1 +
 net/core/dev.c             | 16 ++++++----------
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 31c58f6ec3c6..394eb7ed53be 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -36,6 +36,7 @@ enum cpuhp_state {
 	CPUHP_PERCPU_CNT_DEAD,
 	CPUHP_RADIX_DEAD,
 	CPUHP_PAGE_ALLOC_DEAD,
+	CPUHP_NET_DEV_DEAD,
 	CPUHP_WORKQUEUE_PREP,
 	CPUHP_POWER_NUMA_PREPARE,
 	CPUHP_HRTIMERS_PREPARE,
diff --git a/net/core/dev.c b/net/core/dev.c
index 4bc19a164ba5..71693729bdd5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7947,18 +7947,13 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
 }
 EXPORT_SYMBOL_GPL(dev_change_net_namespace);
 
-static int dev_cpu_callback(struct notifier_block *nfb,
-			    unsigned long action,
-			    void *ocpu)
+static int dev_cpu_dead(unsigned int oldcpu)
 {
 	struct sk_buff **list_skb;
 	struct sk_buff *skb;
-	unsigned int cpu, oldcpu = (unsigned long)ocpu;
+	unsigned int cpu;
 	struct softnet_data *sd, *oldsd;
 
-	if (action != CPU_DEAD && action != CPU_DEAD_FROZEN)
-		return NOTIFY_OK;
-
 	local_irq_disable();
 	cpu = smp_processor_id();
 	sd = &per_cpu(softnet_data, cpu);
@@ -8008,10 +8003,9 @@ static int dev_cpu_callback(struct notifier_block *nfb,
 		input_queue_head_incr(oldsd);
 	}
 
-	return NOTIFY_OK;
+	return 0;
 }
 
-
 /**
  *	netdev_increment_features - increment feature set by one
  *	@all: current feature set
@@ -8345,7 +8339,9 @@ static int __init net_dev_init(void)
 	open_softirq(NET_TX_SOFTIRQ, net_tx_action);
 	open_softirq(NET_RX_SOFTIRQ, net_rx_action);
 
-	hotcpu_notifier(dev_cpu_callback, 0);
+	rc = cpuhp_setup_state_nocalls(CPUHP_NET_DEV_DEAD, "net/dev:dead",
+				       NULL, dev_cpu_dead);
+	WARN_ON(rc < 0);
 	dst_subsys_init();
 	rc = 0;
 out:
-- 
2.10.2

^ permalink raw reply related

* [PATCH 09/25] net/flowcache: Convert to hotplug state machine
From: Sebastian Andrzej Siewior @ 2016-11-03 14:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: rt, Sebastian Andrzej Siewior, David S. Miller, Steffen Klassert,
	Herbert Xu, netdev, Thomas Gleixner
In-Reply-To: <20161103145021.28528-1-bigeasy@linutronix.de>

Install the callbacks via the state machine. Use multi state support to avoid
custom list handling for the multiple instances.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: netdev@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/cpuhotplug.h |  1 +
 include/net/flow.h         |  1 +
 include/net/flowcache.h    |  2 +-
 net/core/flow.c            | 60 ++++++++++++++++++++--------------------------
 net/xfrm/xfrm_policy.c     |  1 +
 5 files changed, 30 insertions(+), 35 deletions(-)

diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 394eb7ed53be..86b940f19df8 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -56,6 +56,7 @@ enum cpuhp_state {
 	CPUHP_ARM_SHMOBILE_SCU_PREPARE,
 	CPUHP_SH_SH3X_PREPARE,
 	CPUHP_BLK_MQ_PREPARE,
+	CPUHP_NET_FLOW_PREPARE,
 	CPUHP_TIMERS_DEAD,
 	CPUHP_NOTF_ERR_INJ_PREPARE,
 	CPUHP_MIPS_SOC_PREPARE,
diff --git a/include/net/flow.h b/include/net/flow.h
index 035aa7716967..2e386bd6ee63 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -239,6 +239,7 @@ struct flow_cache_object *flow_cache_lookup(struct net *net,
 					    void *ctx);
 int flow_cache_init(struct net *net);
 void flow_cache_fini(struct net *net);
+void flow_cache_hp_init(void);
 
 void flow_cache_flush(struct net *net);
 void flow_cache_flush_deferred(struct net *net);
diff --git a/include/net/flowcache.h b/include/net/flowcache.h
index c8f665ec6e0d..9caf3bfc8d2d 100644
--- a/include/net/flowcache.h
+++ b/include/net/flowcache.h
@@ -17,7 +17,7 @@ struct flow_cache_percpu {
 struct flow_cache {
 	u32				hash_shift;
 	struct flow_cache_percpu __percpu *percpu;
-	struct notifier_block		hotcpu_notifier;
+	struct hlist_node		node;
 	int				low_watermark;
 	int				high_watermark;
 	struct timer_list		rnd_timer;
diff --git a/net/core/flow.c b/net/core/flow.c
index 3937b1b68d5b..841fd7f87b30 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -419,28 +419,20 @@ static int flow_cache_cpu_prepare(struct flow_cache *fc, int cpu)
 	return 0;
 }
 
-static int flow_cache_cpu(struct notifier_block *nfb,
-			  unsigned long action,
-			  void *hcpu)
+static int flow_cache_cpu_up_prep(unsigned int cpu, struct hlist_node *node)
 {
-	struct flow_cache *fc = container_of(nfb, struct flow_cache,
-						hotcpu_notifier);
-	int res, cpu = (unsigned long) hcpu;
+	struct flow_cache *fc = hlist_entry_safe(node, struct flow_cache, node);
+
+	return flow_cache_cpu_prepare(fc, cpu);
+}
+
+static int flow_cache_cpu_dead(unsigned int cpu, struct hlist_node *node)
+{
+	struct flow_cache *fc = hlist_entry_safe(node, struct flow_cache, node);
 	struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu);
 
-	switch (action) {
-	case CPU_UP_PREPARE:
-	case CPU_UP_PREPARE_FROZEN:
-		res = flow_cache_cpu_prepare(fc, cpu);
-		if (res)
-			return notifier_from_errno(res);
-		break;
-	case CPU_DEAD:
-	case CPU_DEAD_FROZEN:
-		__flow_cache_shrink(fc, fcp, 0);
-		break;
-	}
-	return NOTIFY_OK;
+	__flow_cache_shrink(fc, fcp, 0);
+	return 0;
 }
 
 int flow_cache_init(struct net *net)
@@ -467,18 +459,8 @@ int flow_cache_init(struct net *net)
 	if (!fc->percpu)
 		return -ENOMEM;
 
-	cpu_notifier_register_begin();
-
-	for_each_online_cpu(i) {
-		if (flow_cache_cpu_prepare(fc, i))
-			goto err;
-	}
-	fc->hotcpu_notifier = (struct notifier_block){
-		.notifier_call = flow_cache_cpu,
-	};
-	__register_hotcpu_notifier(&fc->hotcpu_notifier);
-
-	cpu_notifier_register_done();
+	if (cpuhp_state_add_instance(CPUHP_NET_FLOW_PREPARE, &fc->node))
+		goto err;
 
 	setup_timer(&fc->rnd_timer, flow_cache_new_hashrnd,
 		    (unsigned long) fc);
@@ -494,8 +476,6 @@ int flow_cache_init(struct net *net)
 		fcp->hash_table = NULL;
 	}
 
-	cpu_notifier_register_done();
-
 	free_percpu(fc->percpu);
 	fc->percpu = NULL;
 
@@ -509,7 +489,8 @@ void flow_cache_fini(struct net *net)
 	struct flow_cache *fc = &net->xfrm.flow_cache_global;
 
 	del_timer_sync(&fc->rnd_timer);
-	unregister_hotcpu_notifier(&fc->hotcpu_notifier);
+
+	cpuhp_state_remove_instance_nocalls(CPUHP_NET_FLOW_PREPARE, &fc->node);
 
 	for_each_possible_cpu(i) {
 		struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, i);
@@ -521,3 +502,14 @@ void flow_cache_fini(struct net *net)
 	fc->percpu = NULL;
 }
 EXPORT_SYMBOL(flow_cache_fini);
+
+void __init flow_cache_hp_init(void)
+{
+	int ret;
+
+	ret = cpuhp_setup_state_multi(CPUHP_NET_FLOW_PREPARE,
+				      "net/flow:prepare",
+				      flow_cache_cpu_up_prep,
+				      flow_cache_cpu_dead);
+	WARN_ON(ret < 0);
+}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index fd6986634e6f..4a8eff11bdad 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3111,6 +3111,7 @@ static struct pernet_operations __net_initdata xfrm_net_ops = {
 
 void __init xfrm_init(void)
 {
+	flow_cache_hp_init();
 	register_pernet_subsys(&xfrm_net_ops);
 	seqcount_init(&xfrm_policy_hash_generation);
 	xfrm_input_init();
-- 
2.10.2

^ permalink raw reply related

* Re: [PATCH net-next v1 02/21] amd-xgbe: Prepare for priority-based FIFO allocation
From: Tom Lendacky @ 2016-11-03 14:50 UTC (permalink / raw)
  To: Mintz, Yuval, netdev@vger.kernel.org; +Cc: Florian Fainelli, David Miller
In-Reply-To: <BL2PR07MB23065CE0C48D76AB76E78ACF8DA30@BL2PR07MB2306.namprd07.prod.outlook.com>

On 11/03/2016 08:51 AM, Mintz, Yuval wrote:
>> +static void xgbe_calculate_equal_fifo(unsigned int fifo_size,
>> +				      unsigned int queue_count,
>> +				      unsigned int *fifo)
>> +{
> ...
>> +
>> +	return;
>>  }
> 
> No need for explicit return.
> 

Ok, if there's feedback that requires a v2 I'll remove the return,
otherwise I plan to submit a checkpatch cleanup series as a follow-up
to fix some of the new warnings issued by the newer version of
checkpatch.

Thanks,
Tom

^ permalink raw reply

* Re: [PATCH net-next v2 0/5] bpf: BPF for lightweight tunnel encapsulation
From: Hannes Frederic Sowa @ 2016-11-03 14:52 UTC (permalink / raw)
  To: Thomas Graf
  Cc: David S. Miller, Alexei Starovoitov, Daniel Borkmann, Tom Herbert,
	roopa, netdev
In-Reply-To: <CACby=pnSX15XGuKBcw2FJkLz_qZt6XE+JS4ySN1Z6OZ=+w_eoQ@mail.gmail.com>

On 02.11.2016 23:54, Thomas Graf wrote:
> On 1 November 2016 at 16:12, Hannes Frederic Sowa
> <hannes@stressinduktion.org> wrote:
>> On 01.11.2016 21:59, Thomas Graf wrote:
>>>> Dumping and verifying which routes get used might actually already be
>>>> quite complex on its own. Thus my fear.
>>>
>>> We even have an API to query which route is used for a tuple. What
>>> else would you like to see?
>>
>> I am not sure here. Some ideas I had were to allow tcpdump (pf_packet)
>> sockets sniff at interfaces and also gather and dump the metadata to
>> user space (this would depend on bpf programs only doing the
>> modifications in metadata and not in the actual packet).
> 
> Not sure I understand. Why does this depend on BPF?

It doesn't. My hope was, if BPF merely tries to modify meta-data, we can
provide better debugging tools as if we mangle the packet directly.

>> Or maybe just tracing support (without depending on the eBPF program
>> developer to have added debugging in the BPF program).
> 
> Absolutely in favour of that.
> 
>>> This will be addressed with signing AFAIK.
>>
>> This sounds a bit unrealistic. Signing lots of small programs can be a
>> huge burden to the entity doing the signing (if it is not on the same
>> computer). And as far as I understood the programs should be generated
>> dynamically?
> 
> Right, for generated programs, a hash is a better fit and still sufficient.
> 
>>> Would it help if we allow to store the original source used for
>>> bytecode generation. What would make it clear which program was used.
>>
>> I would also be fine with just a strong hash of the bytecode, so the
>> program can be identified accurately. Maybe helps with deduplication
>> later on, too. ;)
> 
> OK, I think we all already agreed on doing this.
> 
>> Even though I read through the patchset I am not absolutely sure which
>> problem it really solves. Especially because lots of things can be done
>> already at the ingress vs. egress interface (I looked at patch 4 but I
>> am not sure how realistic they are).
> 
> Filtering at egress requires to attach the BPF program to all
> potential outgoing interface and then pass every single packet through
> the program whereas with LWT BPF, I'm only taking the cost where
> actually needed.

I do certainly see this point as a big plus. I definitely also thought
about this a lot when thinking about how flower can/should be used with
multiple interfaces and how to keep its flow tables synchronized.

>>> I also don't see how this could possibly scale if all packets must go
>>> through a single BPF program. The overhead will be tremendous if you
>>> only want to filter a couple of prefixes.
>>
>> In case of hash table lookup it should be fast. llvm will probably also
>> generate jump table for a few 100 ip addresses, no? Additionally the
>> routing table lookup could be not done at all.
> 
> Why would I want to accept the overhead if I simply avoid it? Just
> parsing the header and doing the hash lookup will add cost, cost for
> each packet.

That is true, but in case you are outside of the namespace, you still
have to calculate the cost of doing the FIB lookup for the BPF program
each time, too.

E.g. given the lookup cost in a hash for a netnwork namespace pointer
vs. the cost of doing a FIB lookup to get a program that does a specific
transformation sounds at least in the big O-notiation to be in a better
place. ;)

If you have to do both anyway, probably your patchset will perform
better, I agree.

Bye,
Hannes

^ permalink raw reply

* Re: [PATCH net-next v1 17/21] amd-xgbe: Add I2C support for determining SFP media types
From: Tom Lendacky @ 2016-11-03 15:01 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, Florian Fainelli, David Miller
In-Reply-To: <20161103142815.GB1768@lunn.ch>

On 11/03/2016 09:28 AM, Andrew Lunn wrote:
> On Thu, Nov 03, 2016 at 08:30:36AM -0500, Tom Lendacky wrote:
>> Add support to initialize and use the I2C controller within the hardware
>> in order to determine the SFP media type that is installed.
> 
> Hi Tom

Hi Andrew

> 
> Did you see the work Russell King did for phylink?
> 
> https://lwn.net/Articles/667055/
> 
> Rather than doing your own proprietary i2c infrastructure, use the
> standard Linux i2c infrastructure. The SFP modules are then just
> normal i2c devices on a normal i2c bus. The work Russell did can then
> access them, export them to user space, get the PHY modes correctly
> setup, etc.

There are a couple of things about this. Russel's work isn't part of
the kernel yet so I can't make use of it.  Additionally, the I2C device
is integrated into the IP of the network device with register addresses
being offsets of the network device BAR so I'm not sure how I would go
about getting it setup in order to use the i2c infrastructure.

Thanks,
Tom

> 
>        Andrew
> 

^ permalink raw reply

* RE: [mm PATCH v2 01/26] swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
From: Duyck, Alexander H @ 2016-11-03 15:02 UTC (permalink / raw)
  To: Christoph Hellwig, Konrad Rzeszutek Wilk
  Cc: linux-mm@kvack.org, akpm@linux-foundation.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20161103144532.GA14340@infradead.org>

> -----Original Message-----
> From: Christoph Hellwig [mailto:hch@infradead.org]
> Sent: Thursday, November 3, 2016 7:46 AM
> To: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Cc: Christoph Hellwig <hch@infradead.org>; Duyck, Alexander H
> <alexander.h.duyck@intel.com>; linux-mm@kvack.org; akpm@linux-
> foundation.org; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [mm PATCH v2 01/26] swiotlb: Drop unused functions
> swiotlb_map_sg and swiotlb_unmap_sg
> 
> On Thu, Nov 03, 2016 at 10:29:52AM -0400, Konrad Rzeszutek Wilk wrote:
> > Somehow I thought you wanted to put them through your tree (which is
> > why I acked them).
> >
> > I can take them and also the first couple of Alexander through my
> > tree. Or if it makes it simpler - they can go through the -mm tree?
> 
> I don't have a tree for it, so I kinda expected you to pick it up.
> But I'm also fine with you just Acking the version from Alex and having him
> funnel it through whatever tree he wants to get his patches in through.

For the first 3 patches in my series I am fine with them being pulled into the swiotlb tree.  So if you want to pull Christoph's two patches, and then drop my duplicate patch and instead pull the next 2 I could submit a v3 of my series without the swiotlb patches in it.

At this point I have redone my series so that I technically don't have anything with a hard dependency on the DMA_ATTR_SKIP_CPU_SYNC actually doing anything yet.  My plan is to get this all into Linus's tree first via whatever tree I can get these patches pulled into and once I have all that I will start updating drivers in net-next.

Thanks.

- Alex

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH net-next v2 1/1] driver: veth: Refine the statistics codes of veth driver
From: Eric Dumazet @ 2016-11-03 15:07 UTC (permalink / raw)
  To: Gao Feng
  Cc: David S. Miller, Cong Wang, Vijay Pandurangan, Evan Jones, pabeni,
	Linux Kernel Network Developers
In-Reply-To: <CA+6hz4owi2WgeGWd98=8d=Q5DBPY4_ZtYAOgcM1V_0+OU8UHrw@mail.gmail.com>

On Thu, 2016-11-03 at 22:38 +0800, Gao Feng wrote:

> Because other net devices put the statistics together.
> Take tun/tap as example, it is a virtual device, but its all
> statistics are percpu including dropped.

Take a look at 2681128f0ced8aa4e66f221197e183cc16d244fe
("veth: reduce stat overhead")

Feel free to fix tun/tap, not bloat veth and undo my work,
without knowing why it was done this way.

Thanks.

^ permalink raw reply

* Re: [PATCH net-next v2 1/1] driver: veth: Refine the statistics codes of veth driver
From: Gao Feng @ 2016-11-03 15:13 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S. Miller, Cong Wang, Vijay Pandurangan, Evan Jones, pabeni,
	Linux Kernel Network Developers
In-Reply-To: <1478185643.7065.446.camel@edumazet-glaptop3.roam.corp.google.com>

Hi Eric,

On Thu, Nov 3, 2016 at 11:07 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Thu, 2016-11-03 at 22:38 +0800, Gao Feng wrote:
>
>> Because other net devices put the statistics together.
>> Take tun/tap as example, it is a virtual device, but its all
>> statistics are percpu including dropped.
>
> Take a look at 2681128f0ced8aa4e66f221197e183cc16d244fe
> ("veth: reduce stat overhead")
>
> Feel free to fix tun/tap, not bloat veth and undo my work,
> without knowing why it was done this way.
>
> Thanks.
>
>

Thanks your detail explanations.

Best Regards
Feng

^ permalink raw reply

* Re: [PATCH net-next v1 17/21] amd-xgbe: Add I2C support for determining SFP media types
From: Andrew Lunn @ 2016-11-03 15:18 UTC (permalink / raw)
  To: Tom Lendacky; +Cc: netdev, Florian Fainelli, David Miller
In-Reply-To: <1af561af-65e2-8422-1901-d4b1c317ad12@amd.com>

> There are a couple of things about this. Russel's work isn't part of
> the kernel yet so I can't make use of it.

Well, you could guide it into the kernel. Part of it has already made
the way in. And i know of other platforms which would benefit from it.

> Additionally, the I2C device is integrated into the IP of the
> network device with register addresses being offsets of the network
> device BAR so I'm not sure how I would go about getting it setup in
> order to use the i2c infrastructure.

Have you looked at the core i2c stuff? All you need is an
i2c_algorithim structure:

http://lxr.free-electrons.com/source/include/linux/i2c.h#L407

and an i2c_adaptor structure:

http://lxr.free-electrons.com/source/include/linux/i2c.h#L532

and then you can call i2c_add_adapter() to register your i2c bus with
the i2c core. Embedded such an i2c driver inside another driver is not
a problem.

  Andrew

^ permalink raw reply

* Re: [PATCH net-next v2 0/5] bpf: BPF for lightweight tunnel encapsulation
From: Thomas Graf @ 2016-11-03 15:20 UTC (permalink / raw)
  To: Hannes Frederic Sowa
  Cc: David S. Miller, Alexei Starovoitov, Daniel Borkmann, Tom Herbert,
	roopa, netdev
In-Reply-To: <c24f3ad9-764a-0ffa-51bf-2b42fb3ae585@stressinduktion.org>

On 3 November 2016 at 08:52, Hannes Frederic Sowa
<hannes@stressinduktion.org> wrote:
> On 02.11.2016 23:54, Thomas Graf wrote:
>> Why would I want to accept the overhead if I simply avoid it? Just
>> parsing the header and doing the hash lookup will add cost, cost for
>> each packet.
>
> That is true, but in case you are outside of the namespace, you still
> have to calculate the cost of doing the FIB lookup for the BPF program
> each time, too.
>
> E.g. given the lookup cost in a hash for a netnwork namespace pointer
> vs. the cost of doing a FIB lookup to get a program that does a specific
> transformation sounds at least in the big O-notiation to be in a better
> place. ;)
>
> If you have to do both anyway, probably your patchset will perform
> better, I agree.

Most containers are unprivileged, the route inside the container's
namespace is owned by the host and we can attach the BPF program
directly to the default route inside the container and all packets
egressing from the container will pass through it. That fib lookup is
needed anyway so we can leverage the cost of that lookup. We can drop
hostile packets early without ever going on L2 level.

^ permalink raw reply

* Re: net/netlink: global-out-of-bounds in genl_family_rcv_msg/validate_nla
From: Andrey Konovalov @ 2016-11-03 15:28 UTC (permalink / raw)
  To: Cong Wang
  Cc: David S. Miller, Nicolas Dichtel, LKML, Matti Vaittinen,
	Tycho Andersen, stephen hemminger, Tom Herbert, Florian Westphal,
	netdev
In-Reply-To: <CAM_iQpXAqgW5LxAXmHbBqppM-eo1spyOJhyCpkkZ_3J7DRUUuw@mail.gmail.com>

Hi Cong,

Yes, the last patch fixes the issue.

Tested-by: Andrey Konovalov <andreyknvl@google.com>

Thanks!

On Thu, Nov 3, 2016 at 6:29 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Wed, Nov 2, 2016 at 10:25 PM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
>> On Wed, Nov 2, 2016 at 5:25 PM, Andrey Konovalov <andreyknvl@google.com> wrote:
>>> Hi,
>>>
>>> I've got the following error report while running the syzkaller fuzzer:
>>>
>>> ==================================================================
>>> BUG: KASAN: global-out-of-bounds in validate_nla+0x49b/0x4e0 at addr
>>> ffffffff8407e3ac
>>> Read of size 2 by task a.out/3877
>>> Address belongs to variable[<        none        >]
>>> cgroupstats_cmd_get_policy+0xc/0x40 ??:?
>>
>> Seems taskstats doesn't use genetlink correctly, CGROUPSTATS_CMD_ATTR_FD
>> is not within 0~TASKSTATS_CMD_ATTR_MAX.
>>
>> I guess we need the following patch, but it certainly breaks user-space... :-/
>
>
> Wait, maybe just this one-line fix is enough:
>
> diff --git a/kernel/taskstats.c b/kernel/taskstats.c
> index b3f05ee..e6b342e 100644
> --- a/kernel/taskstats.c
> +++ b/kernel/taskstats.c
> @@ -54,7 +54,7 @@ static const struct nla_policy
> taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1
>         [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
>         [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};
>
> -static const struct nla_policy
> cgroupstats_cmd_get_policy[CGROUPSTATS_CMD_ATTR_MAX+1] = {
> +static const struct nla_policy
> cgroupstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = {
>         [CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 },
>  };

^ permalink raw reply

* Re: [PATCH 1/2] rtl8xxxu: Fix for authentication failure
From: Larry Finger @ 2016-11-03 15:39 UTC (permalink / raw)
  To: John Heenan
  Cc: Jes Sorensen, Kalle Valo, linux-wireless, netdev, linux-kernel
In-Reply-To: <CAAye0QNZYjg1NDmXmjMXNJqa7nsbvfgoX8et1g1+HT2S2O=L1w@mail.gmail.com>

On 11/03/2016 02:10 AM, John Heenan wrote:
> On 3 November 2016 at 11:00, Larry Finger <Larry.Finger@lwfinger.net> wrote:
>> On 10/30/2016 05:20 AM, John Heenan wrote:
>>>
>>> This fix enables the same sequence of init behaviour as the alternative
>>> working driver for the wireless rtl8723bu IC at
>>> https://github.com/lwfinger/rtl8723bu
>>>
>>> For exampe rtl8xxxu_init_device is now called each time
>>> userspace wpa_supplicant is executed instead of just once when
>>> modprobe is executed.
>>
>>
>> After all the trouble you have had with your patches, I would expect you to
>> use more care when composing the commit message. Note the typo in the
>> paragraph above.
>>
>
> OK, the nasty games continue and the message is not getting through.
>
> An appropriate response by a maintainer would have been to request I
> revise the code according to the way it has currently and elegantly
> revised in.

I am NOT a maintainer for this driver. I do have an interest in it, but not in 
any official capacity.

If you cannot accept constructive criticism, you are in the wrong activity. 
Please grow up!

Larry

^ permalink raw reply

* Re: net/ipv6: null-ptr-deref in inet6_bind
From: Eric Dumazet @ 2016-11-03 15:39 UTC (permalink / raw)
  To: Andrey Konovalov
  Cc: David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy, netdev, LKML, Dmitry Vyukov,
	Alexander Potapenko, Kostya Serebryany, syzkaller
In-Reply-To: <CAAeHK+y8AEQ7dM6GQa5fezgaQK+arqAfRjyVafq-K0+nqgUvGg@mail.gmail.com>

On Wed, Nov 2, 2016 at 2:14 PM, Andrey Konovalov <andreyknvl@google.com> wrote:
> Hi,
>
> I've got the following error report while running the syzkaller fuzzer:
>
> BUG: unable to handle kernel NULL pointer dereference at           (null)
> IP: [<          (null)>]           (null)
> PGD 66b6f067 [  102.549865] PUD 66c6e067
> PMD 0 [  102.549865]
> Oops: 0010 [#1] SMP KASAN
> Modules linked in:
> CPU: 0 PID: 4143 Comm: a.out Not tainted 4.9.0-rc3+ #336
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> task: ffff880066b1c200 task.stack: ffff880065b58000
> RIP: 0010:[<0000000000000000>]  [<          (null)>]           (null)
> RSP: 0018:ffff880065b5fbc0  EFLAGS: 00010246
> RAX: ffff880066b1c200 RBX: ffff88006873864a RCX: 0000000000000000
> RDX: 0000000000000001 RSI: ffff880068738640 RDI: ffff880063bd3200
> RBP: ffff880065b5fd20 R08: 1ffff1000c77a713 R09: dffffc0000000000
> R10: ffffffff844fc800 R11: 1ffff1000d0e70c9 R12: ffffffff84e7e040
> R13: ffff880068738640 R14: ffff880063bd3200 R15: ffffffff86836380
> FS:  00007f40b7acf700(0000) GS:ffff88006cc00000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000000000000 CR3: 000000006bb28000 CR4: 00000000000006f0
> Stack:
>  ffffffff83099988 ffffffff8479f7e8 ffffffff81208580 1ffff1000000000c
>  0000000041b58ab3 ffffffff8479f7e8 ffffffff81208580 ffffffff812506ed
>  0000000000000007 ffff880065b5fc18 ffffffff812506ed ffff880065b5fcd0
> Call Trace:
>  [<ffffffff832cf4fc>] inet6_bind+0x8ec/0x1020 net/ipv6/af_inet6.c:384
>  [<ffffffff82b7033c>] SYSC_bind+0x1ec/0x250 net/socket.c:1367
>  [<ffffffff82b72ae4>] SyS_bind+0x24/0x30 net/socket.c:1353
>  [<ffffffff83fc0401>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> arch/x86/entry/entry_64.S:209
> Code:  Bad RIP value.
> RIP  [<          (null)>]           (null)
>  RSP <ffff880065b5fbc0>
> CR2: 0000000000000000
> ---[ end trace b5ec698ae4926a97 ]---
> Kernel panic - not syncing: Fatal exception in interrupt
> Kernel Offset: disabled
> ---[ end Kernel panic - not syncing: Fatal exception in interrupt
>
> On commit 0c183d92b20b5c84ca655b45ef57b3318b83eb9e (Oct 31).
>
> I'm able to reproduce it with the attached program by running it as:
> $ gcc -lpthread inet6-bind-poc.c
> $ while true; do ./a.out; done
>
> Thanks!

Looks like this patch should fix it ?

Thanks !

diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 3828f94b234c..95353bdbfa7b 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -956,6 +956,7 @@ static const struct inet_connection_sock_af_ops
dccp_ipv6_mapped = {
        .getsockopt        = ipv6_getsockopt,
        .addr2sockaddr     = inet6_csk_addr2sockaddr,
        .sockaddr_len      = sizeof(struct sockaddr_in6),
+       .bind_conflict     = inet6_csk_bind_conflict,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_ipv6_setsockopt,
        .compat_getsockopt = compat_ipv6_getsockopt,

^ permalink raw reply related

* Re: [PATCH 2/2] rtl8xxxu: Fix for bogus data used to determine macpower
From: Larry Finger @ 2016-11-03 15:43 UTC (permalink / raw)
  To: Joe Perches, Jes Sorensen, John Heenan
  Cc: Kalle Valo, linux-wireless, netdev, linux-kernel
In-Reply-To: <1478162497.1924.16.camel@perches.com>

On 11/03/2016 03:41 AM, Joe Perches wrote:
> On Sun, 2016-10-30 at 19:02 -0400, Jes Sorensen wrote:
>> Code is 80 characters wide, and comments are /* */ never the ugly C++
>> crap.
>
> You might look at the recent Linus Torvalds authored commit
> 5e467652ffef (?printk: re-organize log_output() to be more legible")
> which does both of those: c99 // comments and > 80 columns.
>
> Absolutes are for zealots.

Of course, but who is going to criticize Linus? I have gently chided him when an 
untested patch of his was inserted just before the final release, and broke my 
laptop. At least the bisection was pretty quick. :)

Larry

^ permalink raw reply

* Re: [RFC] make kmemleak scan __ro_after_init section (was: Re: [PATCH 0/5] genetlink improvements)
From: Johannes Berg @ 2016-11-03 15:48 UTC (permalink / raw)
  To: Jakub Kicinski, Cong Wang
  Cc: Linux Kernel Network Developers, LKML, Catalin Marinas, linux-mm
In-Reply-To: <20161102234755.4381f528@jkicinski-Precision-T1700>

Hi,

Sorry for not chipping in earlier - LPC is taking my time.

> > > > Looks like we are missing a kfree(family->attrbuf); on error
> > > > path, but it is not related to Johannes' recent patches.

Actually, I think it *is* related to my patch - I inserted the code
there in the wrong place or so. I'll find a fix for that when I'm back
home, or you (Cong) can submit yours. It wasn't likely that this was
the problem though, since that's just an error path that should never
happen (we have <30 genl families, and a 16-bit space for their IDs)

> I realized that kmemleak is not scanning the __ro_after_init
> section...
> Following patch solves the false positives but I wonder if it's the
> right/acceptable solution.

Hah, makes sense to me, but I guess we really want Catalin to comment
:)

johannes

^ 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