Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 2/3] net: dsa: bcm_sf2: Propagate ethtool::rxnfc to CPU port
From: Florian Fainelli @ 2018-08-06 21:29 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, andrew, vivien.didelot, linville, davem
In-Reply-To: <20180806212909.21720-1-f.fainelli@gmail.com>

Allow propagating ethtool::rxnfc programming to the CPU/management port
such that it is possible for such a CPU to perform e.g: Wake-on-LAN
using filters configured by the switch. We need a tiny bit of
cooperation between the switch drivers which is able to do the full flow
matching, whereas the CPU/management port might not. The CPU/management
driver needs to return -EOPNOTSUPP to indicate an non critical error,
any other error code otherwise.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/bcm_sf2_cfp.c | 40 ++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
index 1e37b65aab93..e41ea0f3d5c7 100644
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -732,6 +732,8 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
 				struct ethtool_rx_flow_spec *fs)
 {
 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
+	s8 cpu_port = ds->ports[port].cpu_dp->index;
+	__u64 ring_cookie = fs->ring_cookie;
 	unsigned int queue_num, port_num;
 	int ret = -EINVAL;
 
@@ -748,13 +750,19 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
 	    fs->location > bcm_sf2_cfp_rule_size(priv))
 		return -EINVAL;
 
+	/* This rule is a Wake-on-LAN filter and we must specifically
+	 * target the CPU port in order for it to be working.
+	 */
+	if (ring_cookie == RX_CLS_FLOW_WAKE)
+		ring_cookie = cpu_port * SF2_NUM_EGRESS_QUEUES;
+
 	/* We do not support discarding packets, check that the
 	 * destination port is enabled and that we are within the
 	 * number of ports supported by the switch
 	 */
-	port_num = fs->ring_cookie / SF2_NUM_EGRESS_QUEUES;
+	port_num = ring_cookie / SF2_NUM_EGRESS_QUEUES;
 
-	if (fs->ring_cookie == RX_CLS_FLOW_DISC ||
+	if (ring_cookie == RX_CLS_FLOW_DISC ||
 	    !(dsa_is_user_port(ds, port_num) ||
 	      dsa_is_cpu_port(ds, port_num)) ||
 	    port_num >= priv->hw_params.num_ports)
@@ -763,7 +771,7 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
 	 * We have a small oddity where Port 6 just does not have a
 	 * valid bit here (so we substract by one).
 	 */
-	queue_num = fs->ring_cookie % SF2_NUM_EGRESS_QUEUES;
+	queue_num = ring_cookie % SF2_NUM_EGRESS_QUEUES;
 	if (port_num >= 7)
 		port_num -= 1;
 
@@ -1188,6 +1196,7 @@ static int bcm_sf2_cfp_rule_get_all(struct bcm_sf2_priv *priv,
 int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
 		      struct ethtool_rxnfc *nfc, u32 *rule_locs)
 {
+	struct net_device *p = ds->ports[port].cpu_dp->master;
 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
 	int ret = 0;
 
@@ -1214,12 +1223,20 @@ int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
 
 	mutex_unlock(&priv->cfp.lock);
 
+	/* Pass up the commands to the attached master network device */
+	if (p->ethtool_ops->get_rxnfc) {
+		ret = p->ethtool_ops->get_rxnfc(p, nfc, rule_locs);
+		if (ret == -EOPNOTSUPP)
+			ret = 0;
+	}
+
 	return ret;
 }
 
 int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port,
 		      struct ethtool_rxnfc *nfc)
 {
+	struct net_device *p = ds->ports[port].cpu_dp->master;
 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
 	int ret = 0;
 
@@ -1240,6 +1257,23 @@ int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port,
 
 	mutex_unlock(&priv->cfp.lock);
 
+	if (ret)
+		return ret;
+
+	/* Pass up the commands to the attached master network device.
+	 * This can fail, so rollback the operation if we need to.
+	 */
+	if (p->ethtool_ops->set_rxnfc) {
+		ret = p->ethtool_ops->set_rxnfc(p, nfc);
+		if (ret && ret != -EOPNOTSUPP) {
+			mutex_lock(&priv->cfp.lock);
+			bcm_sf2_cfp_rule_del(priv, port, nfc->fs.location);
+			mutex_unlock(&priv->cfp.lock);
+		} else {
+			ret = 0;
+		}
+	}
+
 	return ret;
 }
 
-- 
2.17.1

^ permalink raw reply related

* [PATCH net-next 3/3] net: systemport: Add support for WAKE_FILTER
From: Florian Fainelli @ 2018-08-06 21:29 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, andrew, vivien.didelot, linville, davem
In-Reply-To: <20180806212909.21720-1-f.fainelli@gmail.com>

The SYSTEMPORT MAC allows up to 8 filters to be programmed to wake-up
from LAN. Verify that we have up to 8 filters and program them to the
appropriate RXCHK entries to be matched (along with their masks).

We need to update the entry and exit to Wake-on-LAN mode to keep the
RXCHK engine running to match during suspend, but this is otherwise
fairly similar to Magic Packet detection.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/bcmsysport.c | 193 ++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bcmsysport.h |  11 +-
 2 files changed, 195 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 284581c9680e..ca47309d4494 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -521,7 +521,7 @@ static void bcm_sysport_get_wol(struct net_device *dev,
 	struct bcm_sysport_priv *priv = netdev_priv(dev);
 	u32 reg;
 
-	wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE;
+	wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
 	wol->wolopts = priv->wolopts;
 
 	if (!(priv->wolopts & WAKE_MAGICSECURE))
@@ -539,7 +539,7 @@ static int bcm_sysport_set_wol(struct net_device *dev,
 {
 	struct bcm_sysport_priv *priv = netdev_priv(dev);
 	struct device *kdev = &priv->pdev->dev;
-	u32 supported = WAKE_MAGIC | WAKE_MAGICSECURE;
+	u32 supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
 
 	if (!device_can_wakeup(kdev))
 		return -ENOTSUPP;
@@ -1043,7 +1043,7 @@ static int bcm_sysport_poll(struct napi_struct *napi, int budget)
 
 static void mpd_enable_set(struct bcm_sysport_priv *priv, bool enable)
 {
-	u32 reg;
+	u32 reg, bit;
 
 	reg = umac_readl(priv, UMAC_MPD_CTRL);
 	if (enable)
@@ -1051,12 +1051,32 @@ static void mpd_enable_set(struct bcm_sysport_priv *priv, bool enable)
 	else
 		reg &= ~MPD_EN;
 	umac_writel(priv, reg, UMAC_MPD_CTRL);
+
+	if (priv->is_lite)
+		bit = RBUF_ACPI_EN_LITE;
+	else
+		bit = RBUF_ACPI_EN;
+
+	reg = rbuf_readl(priv, RBUF_CONTROL);
+	if (enable)
+		reg |= bit;
+	else
+		reg &= ~bit;
+	rbuf_writel(priv, reg, RBUF_CONTROL);
 }
 
 static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv)
 {
+	u32 reg;
+
 	/* Stop monitoring MPD interrupt */
-	intrl2_0_mask_set(priv, INTRL2_0_MPD);
+	intrl2_0_mask_set(priv, INTRL2_0_MPD | INTRL2_0_BRCM_MATCH_TAG);
+
+	/* Disable RXCHK, active filters and Broadcom tag matching */
+	reg = rxchk_readl(priv, RXCHK_CONTROL);
+	reg &= ~(RXCHK_BRCM_TAG_MATCH_MASK <<
+		 RXCHK_BRCM_TAG_MATCH_SHIFT | RXCHK_EN | RXCHK_BRCM_TAG_EN);
+	rxchk_writel(priv, reg, RXCHK_CONTROL);
 
 	/* Clear the MagicPacket detection logic */
 	mpd_enable_set(priv, false);
@@ -1085,6 +1105,7 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
 	struct bcm_sysport_priv *priv = netdev_priv(dev);
 	struct bcm_sysport_tx_ring *txr;
 	unsigned int ring, ring_bit;
+	u32 reg;
 
 	priv->irq0_stat = intrl2_0_readl(priv, INTRL2_CPU_STATUS) &
 			  ~intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
@@ -1111,7 +1132,14 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
 		bcm_sysport_tx_reclaim_all(priv);
 
 	if (priv->irq0_stat & INTRL2_0_MPD)
-		netdev_info(priv->netdev, "Wake-on-LAN interrupt!\n");
+		netdev_info(priv->netdev, "Wake-on-LAN (MPD) interrupt!\n");
+
+	if (priv->irq0_stat & INTRL2_0_BRCM_MATCH_TAG) {
+		reg = rxchk_readl(priv, RXCHK_BRCM_TAG_MATCH_STATUS) &
+				  RXCHK_BRCM_TAG_MATCH_MASK;
+		netdev_info(priv->netdev,
+			    "Wake-on-LAN (filters 0x%02x) interrupt!\n", reg);
+	}
 
 	if (!priv->is_lite)
 		goto out;
@@ -2096,6 +2124,132 @@ static int bcm_sysport_stop(struct net_device *dev)
 	return 0;
 }
 
+static int bcm_sysport_rule_find(struct bcm_sysport_priv *priv,
+				 u64 location)
+{
+	unsigned int index;
+	u32 reg;
+
+	for_each_set_bit(index, priv->filters, RXCHK_BRCM_TAG_MAX) {
+		reg = rxchk_readl(priv, RXCHK_BRCM_TAG(index));
+		reg >>= RXCHK_BRCM_TAG_CID_SHIFT;
+		reg &= RXCHK_BRCM_TAG_CID_MASK;
+		if (reg == location)
+			return index;
+	}
+
+	return -EINVAL;
+}
+
+static int bcm_sysport_rule_get(struct bcm_sysport_priv *priv,
+				struct ethtool_rxnfc *nfc)
+{
+	int index;
+
+	/* This is not a rule that we know about */
+	index = bcm_sysport_rule_find(priv, nfc->fs.location);
+	if (index < 0)
+		return -EOPNOTSUPP;
+
+	nfc->fs.ring_cookie = RX_CLS_FLOW_WAKE;
+
+	return 0;
+}
+
+static int bcm_sysport_rule_set(struct bcm_sysport_priv *priv,
+				struct ethtool_rxnfc *nfc)
+{
+	unsigned int index;
+	u32 reg;
+
+	/* We cannot match locations greater than what the classification ID
+	 * permits (256 entries)
+	 */
+	if (nfc->fs.location > RXCHK_BRCM_TAG_CID_MASK)
+		return -E2BIG;
+
+	/* We cannot support flows that are not destined for a wake-up */
+	if (nfc->fs.ring_cookie != RX_CLS_FLOW_WAKE)
+		return -EOPNOTSUPP;
+
+	/* All filters are already in use, we cannot match more rules */
+	if (bitmap_weight(priv->filters, RXCHK_BRCM_TAG_MAX) ==
+	    RXCHK_BRCM_TAG_MAX)
+		return -ENOSPC;
+
+	index = find_first_zero_bit(priv->filters, RXCHK_BRCM_TAG_MAX);
+	if (index > RXCHK_BRCM_TAG_MAX)
+		return -ENOSPC;
+
+	/* Location is the classification ID, and index is the position
+	 * within one of our 8 possible filters to be programmed
+	 */
+	reg = rxchk_readl(priv, RXCHK_BRCM_TAG(index));
+	reg &= ~(RXCHK_BRCM_TAG_CID_MASK << RXCHK_BRCM_TAG_CID_SHIFT);
+	reg |= nfc->fs.location << RXCHK_BRCM_TAG_CID_SHIFT;
+	rxchk_writel(priv, reg, RXCHK_BRCM_TAG(index));
+	rxchk_writel(priv, 0xff00ffff, RXCHK_BRCM_TAG_MASK(index));
+
+	set_bit(index, priv->filters);
+
+	return 0;
+}
+
+static int bcm_sysport_rule_del(struct bcm_sysport_priv *priv,
+				u64 location)
+{
+	int index;
+
+	/* This is not a rule that we know about */
+	index = bcm_sysport_rule_find(priv, location);
+	if (index < 0)
+		return -EOPNOTSUPP;
+
+	/* No need to disable this filter if it was enabled, this will
+	 * be taken care of during suspend time by bcm_sysport_suspend_to_wol
+	 */
+	clear_bit(index, priv->filters);
+
+	return 0;
+}
+
+static int bcm_sysport_get_rxnfc(struct net_device *dev,
+				 struct ethtool_rxnfc *nfc, u32 *rule_locs)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	int ret = -EOPNOTSUPP;
+
+	switch (nfc->cmd) {
+	case ETHTOOL_GRXCLSRULE:
+		ret = bcm_sysport_rule_get(priv, nfc);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int bcm_sysport_set_rxnfc(struct net_device *dev,
+				 struct ethtool_rxnfc *nfc)
+{
+	struct bcm_sysport_priv *priv = netdev_priv(dev);
+	int ret = -EOPNOTSUPP;
+
+	switch (nfc->cmd) {
+	case ETHTOOL_SRXCLSRLINS:
+		ret = bcm_sysport_rule_set(priv, nfc);
+		break;
+	case ETHTOOL_SRXCLSRLDEL:
+		ret = bcm_sysport_rule_del(priv, nfc->fs.location);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
 static const struct ethtool_ops bcm_sysport_ethtool_ops = {
 	.get_drvinfo		= bcm_sysport_get_drvinfo,
 	.get_msglevel		= bcm_sysport_get_msglvl,
@@ -2110,6 +2264,8 @@ static const struct ethtool_ops bcm_sysport_ethtool_ops = {
 	.set_coalesce		= bcm_sysport_set_coalesce,
 	.get_link_ksettings     = phy_ethtool_get_link_ksettings,
 	.set_link_ksettings     = phy_ethtool_set_link_ksettings,
+	.get_rxnfc		= bcm_sysport_get_rxnfc,
+	.set_rxnfc		= bcm_sysport_set_rxnfc,
 };
 
 static u16 bcm_sysport_select_queue(struct net_device *dev, struct sk_buff *skb,
@@ -2434,16 +2590,39 @@ static int bcm_sysport_suspend_to_wol(struct bcm_sysport_priv *priv)
 {
 	struct net_device *ndev = priv->netdev;
 	unsigned int timeout = 1000;
+	unsigned int index, i = 0;
 	u32 reg;
 
 	/* Password has already been programmed */
 	reg = umac_readl(priv, UMAC_MPD_CTRL);
-	reg |= MPD_EN;
+	if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE))
+		reg |= MPD_EN;
 	reg &= ~PSW_EN;
 	if (priv->wolopts & WAKE_MAGICSECURE)
 		reg |= PSW_EN;
 	umac_writel(priv, reg, UMAC_MPD_CTRL);
 
+	if (priv->wolopts & WAKE_FILTER) {
+		/* Turn on ACPI matching to steal packets from RBUF */
+		reg = rbuf_readl(priv, RBUF_CONTROL);
+		if (priv->is_lite)
+			reg |= RBUF_ACPI_EN_LITE;
+		else
+			reg |= RBUF_ACPI_EN;
+		rbuf_writel(priv, reg, RBUF_CONTROL);
+
+		/* Enable RXCHK, active filters and Broadcom tag matching */
+		reg = rxchk_readl(priv, RXCHK_CONTROL);
+		reg &= ~(RXCHK_BRCM_TAG_MATCH_MASK <<
+			 RXCHK_BRCM_TAG_MATCH_SHIFT);
+		for_each_set_bit(index, priv->filters, RXCHK_BRCM_TAG_MAX) {
+			reg |= BIT(RXCHK_BRCM_TAG_MATCH_SHIFT + i);
+			i++;
+		}
+		reg |= RXCHK_EN | RXCHK_BRCM_TAG_EN;
+		rxchk_writel(priv, reg, RXCHK_CONTROL);
+	}
+
 	/* Make sure RBUF entered WoL mode as result */
 	do {
 		reg = rbuf_readl(priv, RBUF_STATUS);
@@ -2464,7 +2643,7 @@ static int bcm_sysport_suspend_to_wol(struct bcm_sysport_priv *priv)
 	umac_enable_set(priv, CMD_RX_EN, 1);
 
 	/* Enable the interrupt wake-up source */
-	intrl2_0_mask_clear(priv, INTRL2_0_MPD);
+	intrl2_0_mask_clear(priv, INTRL2_0_MPD | INTRL2_0_BRCM_MATCH_TAG);
 
 	netif_dbg(priv, wol, ndev, "entered WOL mode\n");
 
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
index cf440b91fd04..046c6c1d97fd 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.h
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h
@@ -11,6 +11,7 @@
 #ifndef __BCM_SYSPORT_H
 #define __BCM_SYSPORT_H
 
+#include <linux/bitmap.h>
 #include <linux/if_vlan.h>
 #include <linux/net_dim.h>
 
@@ -155,14 +156,18 @@ struct bcm_rsb {
 #define  RXCHK_PARSE_AUTH		(1 << 22)
 
 #define RXCHK_BRCM_TAG0			0x04
-#define RXCHK_BRCM_TAG(i)		((i) * RXCHK_BRCM_TAG0)
+#define RXCHK_BRCM_TAG(i)		((i) * 0x4 + RXCHK_BRCM_TAG0)
 #define RXCHK_BRCM_TAG0_MASK		0x24
-#define RXCHK_BRCM_TAG_MASK(i)		((i) * RXCHK_BRCM_TAG0_MASK)
+#define RXCHK_BRCM_TAG_MASK(i)		((i) * 0x4 + RXCHK_BRCM_TAG0_MASK)
 #define RXCHK_BRCM_TAG_MATCH_STATUS	0x44
 #define RXCHK_ETHERTYPE			0x48
 #define RXCHK_BAD_CSUM_CNTR		0x4C
 #define RXCHK_OTHER_DISC_CNTR		0x50
 
+#define RXCHK_BRCM_TAG_MAX		8
+#define RXCHK_BRCM_TAG_CID_SHIFT	16
+#define RXCHK_BRCM_TAG_CID_MASK		0xff
+
 /* TXCHCK offsets and defines */
 #define SYS_PORT_TXCHK_OFFSET		0x380
 #define TXCHK_PKT_RDY_THRESH		0x00
@@ -185,6 +190,7 @@ struct bcm_rsb {
 #define  RBUF_RSB_SWAP0			(1 << 22)
 #define  RBUF_RSB_SWAP1			(1 << 23)
 #define  RBUF_ACPI_EN			(1 << 23)
+#define  RBUF_ACPI_EN_LITE		(1 << 24)
 
 #define RBUF_PKT_RDY_THRESH		0x04
 
@@ -777,6 +783,7 @@ struct bcm_sysport_priv {
 
 	/* Ethtool */
 	u32			msg_enable;
+	DECLARE_BITMAP(filters, RXCHK_BRCM_TAG_MAX);
 
 	struct bcm_sysport_stats64	stats64;
 
-- 
2.17.1

^ permalink raw reply related

* Re: [PATCH net-next 2/3] net: dsa: bcm_sf2: Propagate ethtool::rxnfc to CPU port
From: Andrew Lunn @ 2018-08-06 22:32 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: netdev, vivien.didelot, linville, davem
In-Reply-To: <20180806212909.21720-4-f.fainelli@gmail.com>

>  int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
>  		      struct ethtool_rxnfc *nfc, u32 *rule_locs)
>  {
> +	struct net_device *p = ds->ports[port].cpu_dp->master;
>  	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
>  	int ret = 0;
>  
> @@ -1214,12 +1223,20 @@ int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
>  
>  	mutex_unlock(&priv->cfp.lock);

Hi Florian

I think you should be testing ret here. If you have had a real error,
you probably should be returning it, rather than overwriting it with
what ethtool returns below.

> +	/* Pass up the commands to the attached master network device */
> +	if (p->ethtool_ops->get_rxnfc) {
> +		ret = p->ethtool_ops->get_rxnfc(p, nfc, rule_locs);
> +		if (ret == -EOPNOTSUPP)
> +			ret = 0;
> +	}
> +
>  	return ret;
>  }

   Andrew

^ permalink raw reply

* Re: [PATCH net-next 2/3] net: dsa: bcm_sf2: Propagate ethtool::rxnfc to CPU port
From: Florian Fainelli @ 2018-08-06 22:37 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, vivien.didelot, linville, davem
In-Reply-To: <20180806223225.GE18350@lunn.ch>



On 08/06/2018 03:32 PM, Andrew Lunn wrote:
>>  int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
>>  		      struct ethtool_rxnfc *nfc, u32 *rule_locs)
>>  {
>> +	struct net_device *p = ds->ports[port].cpu_dp->master;
>>  	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
>>  	int ret = 0;
>>  
>> @@ -1214,12 +1223,20 @@ int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
>>  
>>  	mutex_unlock(&priv->cfp.lock);
> 
> Hi Florian
> 
> I think you should be testing ret here. If you have had a real error,
> you probably should be returning it, rather than overwriting it with
> what ethtool returns below.

Hu, right, thanks for spotting it, this is done in the set_rxnfc() part,
will submit a v2 shortly.

> 
>> +	/* Pass up the commands to the attached master network device */
>> +	if (p->ethtool_ops->get_rxnfc) {
>> +		ret = p->ethtool_ops->get_rxnfc(p, nfc, rule_locs);
>> +		if (ret == -EOPNOTSUPP)
>> +			ret = 0;
>> +	}
>> +
>>  	return ret;
>>  }
> 
>    Andrew
> 

-- 
Florian

^ permalink raw reply

* Re: e1000e driver stuck at 10Mbps after reconnection
From: Alexander Duyck @ 2018-08-06 22:45 UTC (permalink / raw)
  To: Camille Bordignon; +Cc: Jeff Kirsher, David S. Miller, intel-wired-lan, Netdev
In-Reply-To: <20180806115913.GA21556@super_plancton>

On Mon, Aug 6, 2018 at 4:59 AM, Camille Bordignon
<camille.bordignon@easymile.com> wrote:
> Hello,
>
> Recently we experienced some issues with intel NIC (I219-LM and I219-V).
> It seems that after a wire reconnection, auto-negotation "fails" and
> link speed drips to 10 Mbps.
>
> From kernel logs:
> [17616.346150] e1000e: enp0s31f6 NIC Link is Down
> [17627.003322] e1000e: enp0s31f6 NIC Link is Up 10 Mbps Full Duplex, Flow Control: None
> [17627.003325] e1000e 0000:00:1f.6 enp0s31f6: 10/100 speed: disabling TSO
>
>
> $ethtool enp0s31f6
> Settings for enp0s31f6:
>         Supported ports: [ TP ]
>         Supported link modes:   10baseT/Half 10baseT/Full
>                                 100baseT/Half 100baseT/Full
>                                 1000baseT/Full
>         Supported pause frame use: No
>         Supports auto-negotiation: Yes
>         Supported FEC modes: Not reported
>         Advertised link modes:  10baseT/Half 10baseT/Full
>                                 100baseT/Half 100baseT/Full
>                                 1000baseT/Full
>         Advertised pause frame use: No
>         Advertised auto-negotiation: Yes
>         Advertised FEC modes: Not reported
>         Speed: 10Mb/s
>         Duplex: Full
>         Port: Twisted Pair
>         PHYAD: 1
>         Transceiver: internal
>         Auto-negotiation: on
>         MDI-X: on (auto)
>         Supports Wake-on: pumbg
>         Wake-on: g
>         Current message level: 0x00000007 (7)
>                                drv probe link
>         Link detected: yes
>
>
> Notice that if disconnection last less than about 5 seconds,
> nothing wrong happens.
> And if after last failure, disconnection / connection occurs again and
> last less than 5 seconds, link speed is back to 1000 Mbps.
>
> [18075.350678] e1000e: enp0s31f6 NIC Link is Down
> [18078.716245] e1000e: enp0s31f6 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
>
> The following patch seems to fix this issue.
> However I don't clearly understand why.
>
> diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
> index 3ba0c90e7055..763c013960f1 100644
> --- a/drivers/net/ethernet/intel/e1000e/netdev.c
> +++ b/drivers/net/ethernet/intel/e1000e/netdev.c
> @@ -5069,7 +5069,7 @@ static bool e1000e_has_link(struct e1000_adapter *adapter)
>         case e1000_media_type_copper:
>                 if (hw->mac.get_link_status) {
>                         ret_val = hw->mac.ops.check_for_link(hw);
> -                       link_active = !hw->mac.get_link_status;
> +                       link_active = false;
>                 } else {
>                         link_active = true;
>                 }
>
> Maybe this is related to watchdog task.
>
> I've found out this fix by comparing with last commit that works fine :
> commit 0b76aae741abb9d16d2c0e67f8b1e766576f897d.
> However I don't know if this information is relevant.
>
> Thank you.
> Camille Bordignon

What kernel were you testing this on? I know there have been a number
of changes over the past few months in this area and it would be
useful to know exactly what code base you started out with and what
the latest version of the kernel is you have tested.

Looking over the code change the net effect of it should be to add a 2
second delay from the time the link has changed until you actually
check the speed/duplex configuration. It is possible we could be
seeing some sort of timing issue and adding the 2 second delay after
the link event is enough time for things to stabilize and detect the
link at 1000 instead of 10/100.

- Alex

^ permalink raw reply

* [net-next:master 1745/1753] drivers/net/ieee802154/mac802154_hwsim.c:39:14: sparse: incorrect type in initializer (different address spaces)
From: kbuild test robot @ 2018-08-06 23:07 UTC (permalink / raw)
  To: Alexander Aring; +Cc: kbuild-all, netdev, Stefan Schmidt

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git master
head:   de7de576eca204de9a38e2f6dafe6b7c1ddc85c1
commit: f25da51fdc381ca2863248c7060b3662632f0872 [1745/1753] ieee802154: hwsim: add replacement for fakelb
reproduce:
        # apt-get install sparse
        git checkout f25da51fdc381ca2863248c7060b3662632f0872
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> drivers/net/ieee802154/mac802154_hwsim.c:39:14: sparse: incorrect type in initializer (different address spaces) @@    expected struct list_head *next @@    got struct list_head struct list_head *next @@
   drivers/net/ieee802154/mac802154_hwsim.c:39:14:    expected struct list_head *next
   drivers/net/ieee802154/mac802154_hwsim.c:39:14:    got struct list_head [noderef] <asn:4>*<noident>
>> drivers/net/ieee802154/mac802154_hwsim.c:39:14: sparse: incorrect type in initializer (different address spaces) @@    expected struct list_head *prev @@    got struct list_head struct list_head *prev @@
   drivers/net/ieee802154/mac802154_hwsim.c:39:14:    expected struct list_head *prev
   drivers/net/ieee802154/mac802154_hwsim.c:39:14:    got struct list_head [noderef] <asn:4>*<noident>
>> drivers/net/ieee802154/mac802154_hwsim.c:799:18: sparse: incorrect type in assignment (different address spaces) @@    expected struct hwsim_pib [noderef] <asn:4>*pib @@    got  hwsim_pib [noderef] <asn:4>*pib @@
   drivers/net/ieee802154/mac802154_hwsim.c:799:18:    expected struct hwsim_pib [noderef] <asn:4>*pib
   drivers/net/ieee802154/mac802154_hwsim.c:799:18:    got struct hwsim_pib *[assigned] pib
>> drivers/net/ieee802154/mac802154_hwsim.c:801:25: sparse: incorrect type in argument 1 (different modifiers) @@    expected struct list_head *list @@    got struct lisstruct list_head *list @@
   drivers/net/ieee802154/mac802154_hwsim.c:801:25:    expected struct list_head *list
   drivers/net/ieee802154/mac802154_hwsim.c:801:25:    got struct list_head [noderef] *<noident>
>> drivers/net/ieee802154/mac802154_hwsim.c:835:9: sparse: incorrect type in argument 1 (different address spaces) @@    expected struct callback_head *head @@    got struct callback_hstruct callback_head *head @@
   drivers/net/ieee802154/mac802154_hwsim.c:835:9:    expected struct callback_head *head
   drivers/net/ieee802154/mac802154_hwsim.c:835:9:    got struct callback_head [noderef] <asn:4>*<noident>
>> drivers/net/ieee802154/mac802154_hwsim.c:113:17: sparse: incorrect type in assignment (different address spaces) @@    expected struct hwsim_pib *pib_old @@    got struct hwsim_pib struct hwsim_pib *pib_old @@
   drivers/net/ieee802154/mac802154_hwsim.c:113:17:    expected struct hwsim_pib *pib_old
   drivers/net/ieee802154/mac802154_hwsim.c:113:17:    got struct hwsim_pib [noderef] <asn:4>*pib
>> drivers/net/ieee802154/mac802154_hwsim.c:130:9: sparse: incompatible types in comparison expression (different modifiers)
>> drivers/net/ieee802154/mac802154_hwsim.c:144:33: sparse: incompatible types in comparison expression (different address spaces)
>> drivers/net/ieee802154/mac802154_hwsim.c:161:40: sparse: incorrect type in argument 2 (different address spaces) @@    expected struct list_head *head @@    got struct list_head struct list_head *head @@
   drivers/net/ieee802154/mac802154_hwsim.c:161:40:    expected struct list_head *head
   drivers/net/ieee802154/mac802154_hwsim.c:161:40:    got struct list_head [noderef] <asn:4>*<noident>
>> drivers/net/ieee802154/mac802154_hwsim.c:232:25: sparse: incorrect type in argument 1 (different modifiers) @@    expected struct list_head const *head @@    got strustruct list_head const *head @@
   drivers/net/ieee802154/mac802154_hwsim.c:232:25:    expected struct list_head const *head
   drivers/net/ieee802154/mac802154_hwsim.c:232:25:    got struct list_head [noderef] *<noident>
   drivers/net/ieee802154/mac802154_hwsim.c:243:9: sparse: incompatible types in comparison expression (different modifiers)
   drivers/net/ieee802154/mac802154_hwsim.c:260:25: sparse: incompatible types in comparison expression (different address spaces)
   drivers/net/ieee802154/mac802154_hwsim.c:460:9: sparse: incompatible types in comparison expression (different modifiers)
   drivers/net/ieee802154/mac802154_hwsim.c:515:9: sparse: incompatible types in comparison expression (different modifiers)
   drivers/net/ieee802154/mac802154_hwsim.c:573:9: sparse: incompatible types in comparison expression (different modifiers)
   drivers/net/ieee802154/mac802154_hwsim.c:695:17: sparse: incompatible types in comparison expression (different modifiers)
>> drivers/net/ieee802154/mac802154_hwsim.c:717:41: sparse: incorrect type in argument 2 (different modifiers) @@    expected struct list_head *head @@    got struct lisstruct list_head *head @@
   drivers/net/ieee802154/mac802154_hwsim.c:717:41:    expected struct list_head *head
   drivers/net/ieee802154/mac802154_hwsim.c:717:41:    got struct list_head [noderef] *<noident>
   drivers/net/ieee802154/mac802154_hwsim.c:725:41: sparse: incorrect type in argument 2 (different modifiers) @@    expected struct list_head *head @@    got struct lisstruct list_head *head @@
   drivers/net/ieee802154/mac802154_hwsim.c:725:41:    expected struct list_head *head
   drivers/net/ieee802154/mac802154_hwsim.c:725:41:    got struct list_head [noderef] *<noident>

vim +39 drivers/net/ieee802154/mac802154_hwsim.c

    38	
  > 39	static __rcu LIST_HEAD(hwsim_ifup_phys);
    40	
    41	static struct platform_device *mac802154hwsim_dev;
    42	
    43	/* MAC802154_HWSIM netlink family */
    44	static struct genl_family hwsim_genl_family;
    45	
    46	static int hwsim_radio_idx;
    47	
    48	enum hwsim_multicast_groups {
    49		HWSIM_MCGRP_CONFIG,
    50	};
    51	
    52	static const struct genl_multicast_group hwsim_mcgrps[] = {
    53		[HWSIM_MCGRP_CONFIG] = { .name = "config", },
    54	};
    55	
    56	struct hwsim_pib {
    57		u8 page;
    58		u8 channel;
    59	
    60		struct rcu_head rcu;
    61	};
    62	
    63	struct hwsim_edge_info {
    64		u8 lqi;
    65	
    66		struct rcu_head rcu;
    67	};
    68	
    69	struct hwsim_edge {
    70		struct hwsim_phy *endpoint;
    71		struct hwsim_edge_info *info;
    72	
    73		struct list_head list;
    74		struct rcu_head rcu;
    75	};
    76	
    77	struct hwsim_phy {
    78		struct ieee802154_hw *hw;
    79		u32 idx;
    80	
    81		struct hwsim_pib __rcu *pib;
    82	
    83		bool suspended;
    84		struct list_head __rcu edges;
    85	
    86		struct list_head list;
    87		struct list_head list_ifup;
    88	};
    89	
    90	static int hwsim_add_one(struct genl_info *info, struct device *dev,
    91				 bool init);
    92	static void hwsim_del(struct hwsim_phy *phy);
    93	
    94	static int hwsim_hw_ed(struct ieee802154_hw *hw, u8 *level)
    95	{
    96		*level = 0xbe;
    97	
    98		return 0;
    99	}
   100	
   101	static int hwsim_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
   102	{
   103		struct hwsim_phy *phy = hw->priv;
   104		struct hwsim_pib *pib, *pib_old;
   105	
   106		pib = kzalloc(sizeof(*pib), GFP_KERNEL);
   107		if (!pib)
   108			return -ENOMEM;
   109	
   110		pib->page = page;
   111		pib->channel = channel;
   112	
 > 113		pib_old = phy->pib;
   114		rcu_assign_pointer(phy->pib, pib);
   115		kfree_rcu(pib_old, rcu);
   116		return 0;
   117	}
   118	
   119	static int hwsim_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
   120	{
   121		struct hwsim_phy *current_phy = hw->priv;
   122		struct hwsim_pib *current_pib, *endpoint_pib;
   123		struct hwsim_edge_info *einfo;
   124		struct hwsim_edge *e;
   125	
   126		WARN_ON(current_phy->suspended);
   127	
   128		rcu_read_lock();
   129		current_pib = rcu_dereference(current_phy->pib);
 > 130		list_for_each_entry_rcu(e, &current_phy->edges, list) {
   131			/* Can be changed later in rx_irqsafe, but this is only a
   132			 * performance tweak. Received radio should drop the frame
   133			 * in mac802154 stack anyway... so we don't need to be
   134			 * 100% of locking here to check on suspended
   135			 */
   136			if (e->endpoint->suspended)
   137				continue;
   138	
   139			endpoint_pib = rcu_dereference(e->endpoint->pib);
   140			if (current_pib->page == endpoint_pib->page &&
   141			    current_pib->channel == endpoint_pib->channel) {
   142				struct sk_buff *newskb = pskb_copy(skb, GFP_ATOMIC);
   143	
 > 144				einfo = rcu_dereference(e->info);
   145				if (newskb)
   146					ieee802154_rx_irqsafe(e->endpoint->hw, newskb,
   147							      einfo->lqi);
   148			}
   149		}
   150		rcu_read_unlock();
   151	
   152		ieee802154_xmit_complete(hw, skb, false);
   153		return 0;
   154	}
   155	
   156	static int hwsim_hw_start(struct ieee802154_hw *hw)
   157	{
   158		struct hwsim_phy *phy = hw->priv;
   159	
   160		phy->suspended = false;
 > 161		list_add_rcu(&phy->list_ifup, &hwsim_ifup_phys);
   162		synchronize_rcu();
   163	
   164		return 0;
   165	}
   166	
   167	static void hwsim_hw_stop(struct ieee802154_hw *hw)
   168	{
   169		struct hwsim_phy *phy = hw->priv;
   170	
   171		phy->suspended = true;
   172		list_del_rcu(&phy->list_ifup);
   173		synchronize_rcu();
   174	}
   175	
   176	static int
   177	hwsim_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
   178	{
   179		return 0;
   180	}
   181	
   182	static const struct ieee802154_ops hwsim_ops = {
   183		.owner = THIS_MODULE,
   184		.xmit_async = hwsim_hw_xmit,
   185		.ed = hwsim_hw_ed,
   186		.set_channel = hwsim_hw_channel,
   187		.start = hwsim_hw_start,
   188		.stop = hwsim_hw_stop,
   189		.set_promiscuous_mode = hwsim_set_promiscuous_mode,
   190	};
   191	
   192	static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
   193	{
   194		return hwsim_add_one(info, &mac802154hwsim_dev->dev, false);
   195	}
   196	
   197	static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
   198	{
   199		struct hwsim_phy *phy, *tmp;
   200		s64 idx = -1;
   201	
   202		if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID])
   203			return -EINVAL;
   204	
   205		idx = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
   206	
   207		mutex_lock(&hwsim_phys_lock);
   208		list_for_each_entry_safe(phy, tmp, &hwsim_phys, list) {
   209			if (idx == phy->idx) {
   210				hwsim_del(phy);
   211				mutex_unlock(&hwsim_phys_lock);
   212				return 0;
   213			}
   214		}
   215		mutex_unlock(&hwsim_phys_lock);
   216	
   217		return -ENODEV;
   218	}
   219	
   220	static int append_radio_msg(struct sk_buff *skb, struct hwsim_phy *phy)
   221	{
   222		struct nlattr *nl_edges, *nl_edge;
   223		struct hwsim_edge_info *einfo;
   224		struct hwsim_edge *e;
   225		int ret;
   226	
   227		ret = nla_put_u32(skb, MAC802154_HWSIM_ATTR_RADIO_ID, phy->idx);
   228		if (ret < 0)
   229			return ret;
   230	
   231		rcu_read_lock();
 > 232		if (list_empty(&phy->edges)) {
   233			rcu_read_unlock();
   234			return 0;
   235		}
   236	
   237		nl_edges = nla_nest_start(skb, MAC802154_HWSIM_ATTR_RADIO_EDGES);
   238		if (!nl_edges) {
   239			rcu_read_unlock();
   240			return -ENOBUFS;
   241		}
   242	
   243		list_for_each_entry_rcu(e, &phy->edges, list) {
   244			nl_edge = nla_nest_start(skb, MAC802154_HWSIM_ATTR_RADIO_EDGE);
   245			if (!nl_edge) {
   246				rcu_read_unlock();
   247				nla_nest_cancel(skb, nl_edges);
   248				return -ENOBUFS;
   249			}
   250	
   251			ret = nla_put_u32(skb, MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID,
   252					  e->endpoint->idx);
   253			if (ret < 0) {
   254				rcu_read_unlock();
   255				nla_nest_cancel(skb, nl_edge);
   256				nla_nest_cancel(skb, nl_edges);
   257				return ret;
   258			}
   259	
   260			einfo = rcu_dereference(e->info);
   261			ret = nla_put_u8(skb, MAC802154_HWSIM_EDGE_ATTR_LQI,
   262					 einfo->lqi);
   263			if (ret < 0) {
   264				rcu_read_unlock();
   265				nla_nest_cancel(skb, nl_edge);
   266				nla_nest_cancel(skb, nl_edges);
   267				return ret;
   268			}
   269	
   270			nla_nest_end(skb, nl_edge);
   271		}
   272		rcu_read_unlock();
   273	
   274		nla_nest_end(skb, nl_edges);
   275	
   276		return 0;
   277	}
   278	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply

* [PATCH v6 4/9] cxgb4: Do not call pcie_print_link_status()
From: Alexandru Gagniuc @ 2018-08-06 23:25 UTC (permalink / raw)
  To: linux-pci, bhelgaas, jakub.kicinski
  Cc: keith.busch, alex_gagniuc, austin_bolen, shyam_iyer,
	Alexandru Gagniuc, Ariel Elior, everest-linux-l2, David S. Miller,
	Michael Chan, Ganesh Goudar, Jeff Kirsher, Tariq Toukan,
	Saeed Mahameed, Leon Romanovsky, Dirk van der Merwe, netdev,
	linux-kernel, intel-wired-lan, linux-rdma, oss-drivers
In-Reply-To: <20180806232600.25694-1-mr.nuke.me@gmail.com>

This is now done by the PCI core to warn of sub-optimal bandwidth.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index a8926e97935e..049958898c17 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -5726,9 +5726,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 			free_msix_info(adapter);
 	}
 
-	/* check for PCI Express bandwidth capabiltites */
-	pcie_print_link_status(pdev);
-
 	err = init_rss(adapter);
 	if (err)
 		goto out_free_dev;
-- 
2.17.1

^ permalink raw reply related

* [PATCH v6 9/9] nfp: Do not call pcie_print_link_status()
From: Alexandru Gagniuc @ 2018-08-06 23:25 UTC (permalink / raw)
  To: linux-pci, bhelgaas, jakub.kicinski
  Cc: keith.busch, alex_gagniuc, austin_bolen, shyam_iyer,
	Alexandru Gagniuc, Ariel Elior, everest-linux-l2, David S. Miller,
	Michael Chan, Ganesh Goudar, Jeff Kirsher, Tariq Toukan,
	Saeed Mahameed, Leon Romanovsky, Dirk van der Merwe, netdev,
	linux-kernel, intel-wired-lan, linux-rdma, oss-drivers
In-Reply-To: <20180806232600.25694-1-mr.nuke.me@gmail.com>

This is now done by the PCI core to warn of sub-optimal bandwidth.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
index 749655c329b2..0324f99bd1a7 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c
@@ -1324,7 +1324,6 @@ struct nfp_cpp *nfp_cpp_from_nfp6000_pcie(struct pci_dev *pdev)
 	/*  Finished with card initialization. */
 	dev_info(&pdev->dev,
 		 "Netronome Flow Processor NFP4000/NFP6000 PCIe Card Probe\n");
-	pcie_print_link_status(pdev);
 
 	nfp = kzalloc(sizeof(*nfp), GFP_KERNEL);
 	if (!nfp) {
-- 
2.17.1

^ permalink raw reply related

* Re: [PATCH net-next] tcp: fix the calculation of sysctl_max_tw_buckets in tcp_sk_init()
From: Yafang Shao @ 2018-08-07  1:40 UTC (permalink / raw)
  To: David Miller; +Cc: Eric Dumazet, yanhaishuang, netdev, LKML
In-Reply-To: <20180806.134116.1016660959593702560.davem@davemloft.net>

On Tue, Aug 7, 2018 at 4:41 AM, David Miller <davem@davemloft.net> wrote:
> From: Yafang Shao <laoar.shao@gmail.com>
> Date: Mon,  6 Aug 2018 19:47:00 +0800
>
>> tcp_hashinfo.ehash_mask is always an odd number, which is set in function
>> alloc_large_system_hash(). See bellow,
>>       if (_hash_mask)
>>               *_hash_mask = (1 << log2qty) - 1; <<< always odd number
>>
>> Hence the local variable 'cnt' is a even number, as a result of that it is
>> no difference to do the incrementation here.
>>
>> Maybe the compiler could also optimize it, but this code is a little ugly.
>>
>> Fix: fee83d09 ("ipv4: Namespaceify tcp_max_syn_backlog knob")
>
> The correct tag is "Fixes: "

OK

>
>> @@ -2543,7 +2543,7 @@ static int __net_init tcp_sk_init(struct net *net)
>>       net->ipv4.sysctl_tcp_tw_reuse = 2;
>>
>>       cnt = tcp_hashinfo.ehash_mask + 1;
>> -     net->ipv4.tcp_death_row.sysctl_max_tw_buckets = (cnt + 1) / 2;
>> +     net->ipv4.tcp_death_row.sysctl_max_tw_buckets = cnt / 2;
>>       net->ipv4.tcp_death_row.hashinfo = &tcp_hashinfo;
>
> This is completely harmless, and does no harm.
>

It is harmless, meanwhile, it is useless and a little ugly.

By the way,  why do we init sysctl_max_tw_buckets to
(tcp_hashinfo.ehash_mask + 1) / 2 or (tcp_hashinfo.ehash_mask + 2) / 2
?
Per my pespective, this default value is a little huge, sometimes we
have to set this value to a lower value with sysctl, otherwise it may
easily cause tcp port exhaustion issue.
So why not just init it to a lower value ?

> You aren't "fixing" anything.

^ permalink raw reply

* Re: [PATCH v4] selftests: add headers_install to lib.mk
From: Masahiro Yamada @ 2018-08-07  2:32 UTC (permalink / raw)
  To: Shuah Khan
  Cc: Anders Roxell, Michal Marek, Bamvor Zhang, brgl, Paolo Bonzini,
	Andrew Morton, Mike Rapoport, Andrea Arcangeli,
	Linux Kbuild mailing list, Linux Kernel Mailing List,
	open list:KERNEL SELFTEST FRAMEWORK, Networking
In-Reply-To: <3f332e65-0b33-9952-6aba-f9c8953a1f26@kernel.org>

2018-08-07 2:03 GMT+09:00 Shuah Khan <shuah@kernel.org>:
> Hi Anders,
>
> On 07/25/2018 10:08 AM, Anders Roxell wrote:
>> On Tue, 24 Jul 2018 at 19:11, Shuah Khan <shuah@kernel.org> wrote:
>>>
>>> On 07/23/2018 02:49 PM, Anders Roxell wrote:
>>>> On Thu, 7 Jun 2018 at 13:09, Anders Roxell <anders.roxell@linaro.org> wrote:
>>>>>
>>>>> If the kernel headers aren't installed we can't build all the tests.
>>>>> Add a new make target rule 'khdr' in the file lib.mk to generate the
>>>>> kernel headers and that gets include for every test-dir Makefile that
>>>>> includes lib.mk If the testdir in turn have its own sub-dirs the
>>>>> top_srcdir needs to be set to the linux-rootdir to be able to generate
>>>>> the kernel headers.
>>>>>
>>>>> Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
>>>>> Reviewed-by: Fathi Boudra <fathi.boudra@linaro.org>
>>>>> ---
>>>>>  Makefile                                           | 14 +-------------
>>>>>  scripts/subarch.include                            | 13 +++++++++++++
>>>>>  tools/testing/selftests/android/Makefile           |  2 +-
>>>>>  tools/testing/selftests/android/ion/Makefile       |  2 ++
>>>>>  tools/testing/selftests/futex/functional/Makefile  |  1 +
>>>>>  tools/testing/selftests/gpio/Makefile              |  7 ++-----
>>>>>  tools/testing/selftests/kvm/Makefile               |  7 ++-----
>>>>>  tools/testing/selftests/lib.mk                     | 12 ++++++++++++
>>>>>  tools/testing/selftests/net/Makefile               |  1 +
>>>>>  .../selftests/networking/timestamping/Makefile     |  1 +
>>>>>  tools/testing/selftests/vm/Makefile                |  4 ----
>>>>>  11 files changed, 36 insertions(+), 28 deletions(-)
>>>>>  create mode 100644 scripts/subarch.include
>>>>>
>>>>> diff --git a/Makefile b/Makefile
>>>>> index 6b9aea95ae3a..8050072300fa 100644
>>>>> --- a/Makefile
>>>>> +++ b/Makefile
>>>>> @@ -286,19 +286,7 @@ KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
>>>>>  KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
>>>>>  export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
>>>>>
>>>>> -# SUBARCH tells the usermode build what the underlying arch is.  That is set
>>>>> -# first, and if a usermode build is happening, the "ARCH=um" on the command
>>>>> -# line overrides the setting of ARCH below.  If a native build is happening,
>>>>> -# then ARCH is assigned, getting whatever value it gets normally, and
>>>>> -# SUBARCH is subsequently ignored.
>>>>> -
>>>>> -SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
>>>>> -                                 -e s/sun4u/sparc64/ \
>>>>> -                                 -e s/arm.*/arm/ -e s/sa110/arm/ \
>>>>> -                                 -e s/s390x/s390/ -e s/parisc64/parisc/ \
>>>>> -                                 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
>>>>> -                                 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
>>>>> -                                 -e s/riscv.*/riscv/)
>>>>> +include scripts/subarch.include
>>>
>>> What is the reason for this SUBARCH block move to to scripts/subarch.include?
>>> Is this necessary for adding headers install dependency to lib.mk?
>>
>> This is needed to create headers for cross build.
>>
>
> I am sorry for the delay on this patch. I am going to get this into 4.19.
> If anybody has objections, please let me.
>
> Anders! Will be able to rebase the patch and send me the latest. I think
> I have Acks from kvm, android, and vm so far.
>


I may be missing something about the tools/ directory,
but why isn't it like this?


kselftest: headers_install
        $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests run_tests







-- 
Best Regards
Masahiro Yamada

^ permalink raw reply

* we do the editing
From: Jason James @ 2018-08-06 14:07 UTC (permalink / raw)
  To: netdev

Want to follow up the email sent last week.
Do you have needs for photo editing?
We can edit 400 images within 24 hours.

We are working on all kinds of ecommerce photos, jewelry photos, and the
portrait images.

We do cutting out and clipping path and others, and also we provide
retouching for your photos,

You can throw us a photo and we will do testing for you to check our
quality.

Thanks,
Jason

^ permalink raw reply

* linux-next: manual merge of the net-next tree with the netfilter tree
From: Stephen Rothwell @ 2018-08-07  2:49 UTC (permalink / raw)
  To: David Miller, Networking, Pablo Neira Ayuso, NetFilter
  Cc: Linux-Next Mailing List, Linux Kernel Mailing List, Matteo Croce,
	Julian Anastasov

[-- Attachment #1: Type: text/plain, Size: 2676 bytes --]

Hi all,

Today's linux-next merge of the net-next tree got a conflict in:

  net/netfilter/ipvs/ip_vs_conn.c

between commit:

  16e98cec49a4 ("ipvs: don't show negative times in ip_vs_conn")

from the netfilter tree and commit:

  ec1b28ca9674 ("ipvs: provide just conn to ip_vs_state_name")

from the net-next tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc net/netfilter/ipvs/ip_vs_conn.c
index 615286dcf4c0,0edc62910ebf..000000000000
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@@ -1107,10 -1122,8 +1122,10 @@@ static int ip_vs_conn_seq_show(struct s
  				&cp->caddr.in6, ntohs(cp->cport),
  				&cp->vaddr.in6, ntohs(cp->vport),
  				dbuf, ntohs(cp->dport),
- 				ip_vs_state_name(cp->protocol, cp->state),
+ 				ip_vs_state_name(cp),
 -				(cp->timer.expires-jiffies)/HZ, pe_data);
 +				jiffies_delta_to_msecs(cp->timer.expires -
 +						       jiffies) / 1000,
 +				pe_data);
  		else
  #endif
  			seq_printf(seq,
@@@ -1120,10 -1133,8 +1135,10 @@@
  				ntohl(cp->caddr.ip), ntohs(cp->cport),
  				ntohl(cp->vaddr.ip), ntohs(cp->vport),
  				dbuf, ntohs(cp->dport),
- 				ip_vs_state_name(cp->protocol, cp->state),
+ 				ip_vs_state_name(cp),
 -				(cp->timer.expires-jiffies)/HZ, pe_data);
 +				jiffies_delta_to_msecs(cp->timer.expires -
 +						       jiffies) / 1000,
 +				pe_data);
  	}
  	return 0;
  }
@@@ -1173,10 -1184,9 +1188,10 @@@ static int ip_vs_conn_sync_seq_show(str
  				&cp->caddr.in6, ntohs(cp->cport),
  				&cp->vaddr.in6, ntohs(cp->vport),
  				dbuf, ntohs(cp->dport),
- 				ip_vs_state_name(cp->protocol, cp->state),
+ 				ip_vs_state_name(cp),
  				ip_vs_origin_name(cp->flags),
 -				(cp->timer.expires-jiffies)/HZ);
 +				jiffies_delta_to_msecs(cp->timer.expires -
 +						       jiffies) / 1000);
  		else
  #endif
  			seq_printf(seq,
@@@ -1186,10 -1196,9 +1201,10 @@@
  				ntohl(cp->caddr.ip), ntohs(cp->cport),
  				ntohl(cp->vaddr.ip), ntohs(cp->vport),
  				dbuf, ntohs(cp->dport),
- 				ip_vs_state_name(cp->protocol, cp->state),
+ 				ip_vs_state_name(cp),
  				ip_vs_origin_name(cp->flags),
 -				(cp->timer.expires-jiffies)/HZ);
 +				jiffies_delta_to_msecs(cp->timer.expires -
 +						       jiffies) / 1000);
  	}
  	return 0;
  }

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [pull request][net-next 00/10] Mellanox, mlx5 and devlink updates 2018-07-31
From: Jakub Kicinski @ 2018-08-07  0:49 UTC (permalink / raw)
  To: Eran Ben Elisha
  Cc: David Miller, saeedm, netdev, jiri, alexander.duyck, helgaas
In-Reply-To: <952362c1-6886-5293-bee4-267d87a79cba@mellanox.com>

On Mon, 6 Aug 2018 16:01:25 +0300, Eran Ben Elisha wrote:
> >> Hi Dave,
> >> I would like to re-state that this feature was not meant to be a generic
> >> one. This feature was added in order to resolve a HW bug which exist in
> >> a small portion of our devices.  
> > 
> > Would you mind describing the HW bug in more detail?  To a outside
> > reviewer it really looks like you're adding a feature.  What are you
> > working around?  Is the lack of full AQM on the PCIe side of the chip
> > considered a bug?  
> 
> In multiple function environment, there is an issue with buffer 
> allocation per function which may lead to starvation. 

Multi-function?  I thought you have a PF per uplink on all mlx5
silicon.  Does the problem occur in single host scenarios as well?
What if with single function the host is too slow with taking packets
off the RX ring?  Can the problem occur?  Would this feature help in
such scenario as well?

> There is an HW WA for mitigate this starvation by identifying this
> state and apply early drop/mark.

If I understand you correctly you presently have one shared buffer with
no way to place limits (quotas) on how much of it can be consumed by a
traffic for a single PF.  It remains unclear why this have not been a
problem for you until now.

To avoid the starvation you are adding AQM which is a *feature* that
may help you avoid queue build up in the NIC.  But even if you could
place quotas, why would you not expose the AQM scheme?  It looks very
useful.

> >> Those params will be used only on those current HWs and won't be in
> >> use for our future devices.  
> > 
> > I'm glad that is your plan today, however, customers may get used to
> > the simple interface you're adding now.  This means the API you are
> > adding is effectively becoming an API other drivers may need to
> > implement to keep compatibility with someone's proprietary
> > orchestration.  
> 
> This issue was refactored, thus no need to have this WA at all in
> future NICs. So I don't believe we will end up in the situation you are
> describing. It is less likely that other vendors will be facing the
> same issue and will have to support such param. it was burn out of a
> bug and not as a feature which other may follow.

Sure other vendors may have buffers quotas configurable by e.g.
devlink-sb.  But the AQM you are adding is a feature which is
potentially already supported by others.

> >> During the discussions, several alternatives where offered to be
> >> used by various members of the community. These alternatives
> >> includes TC and enhancements to PCI configuration tools.
> >>
> >> Regarding the TC, from my perspective, this is not an option as:
> >> 1) The HW mechanism handles multiple functions and therefore
> >> cannot be configured on as a regular TC  
> > 
> > Could you elaborate?  What are the multiple functions?  You seem to
> > be adding a knob to enable ECN marking and a knob for choosing
> > between some predefined slopes.  
> 
> PSB, The sloped are dynamic and enabled in a dynamic way.
> Indeed, we are adding a very specific knob for very non standard 
> specific issue which can be used in addition to standard ECN marking.
> 
> > In what way would your solution not behave like a RED offload?  
> 
> Existing Algo (RED, PIE, etc) are static, configurable. Our HW WA is 
> dynamic (dynamic slope), adjusted and auto enabled.

You mean like Adaptive RED?  The lack of documentation is making this
conversation harder to have.  What's dynamic and aggressive?  These 
are not antonyms.  Are the parameters to the algorithm configurable?

Will you not want to expose the actual threshold and adjustment values
so the customers can tweak them on their own depending on the workload?

> > With TC offload you'd also get a well-defined set of statistics, I
> > presume right now you're planning on adding a set of ethtool -S
> > counters?
> >   
> >> 2) No PF + representors modeling can be applied here, this is a
> >> MultiHost environment where one host is not aware to the other
> >> hosts, and each is running on its own pci/driver. It is a device
> >> working mode configuration.  
> > 
> > Yes, the multihost part makes it less pleasant.  But this is a
> > problem we have to tackle separately, at some point.  It's not a
> > center of attention here.  
> 
> Agree, however the multihost part makes it non-transparent if we
> chose a solution which is not based on direct vendor configuration.
> This will lead to a bad user experience.

In my experience multi-host is not a major issue in practice.  And
switchdev mode gives some visibility into statistics of others hosts 
etc., which people appreciate.

^ permalink raw reply

* for editing the photos
From: Jason James @ 2018-08-06 12:48 UTC (permalink / raw)
  To: netdev

Want to follow up the email sent last week.
Do you have needs for photo editing?
We can edit 400 images within 24 hours.

We are working on all kinds of ecommerce photos, jewelry photos, and the
portrait images.

We do cutting out and clipping path and others, and also we provide
retouching for your photos,

You can throw us a photo and we will do testing for you to check our
quality.

Thanks,
Jason

^ permalink raw reply

* check with you
From: Jason James @ 2018-08-06 14:17 UTC (permalink / raw)
  To: netdev

Want to follow up the email sent last week.
Do you have needs for photo editing?
We can edit 400 images within 24 hours.

We are working on all kinds of ecommerce photos, jewelry photos, and the
portrait images.

We do cutting out and clipping path and others, and also we provide
retouching for your photos,

You can throw us a photo and we will do testing for you to check our
quality.

Thanks,
Jason

^ permalink raw reply

* Re: [BUG] 4.18-rcX iptables regression
From: Stephen Rothwell @ 2018-08-07  3:42 UTC (permalink / raw)
  To: Bob Tracy; +Cc: linux-net, linux-kernel, NetFilter, Networking
In-Reply-To: <20180807010049.GA1345@gherkin.frus.com>

[-- Attachment #1: Type: text/plain, Size: 399 bytes --]

Hi Bob,

[Juts cc'ing the netfilter and netdev mailing lists]

On Mon, 6 Aug 2018 20:00:49 -0500 Bob Tracy <rct@gherkin.frus.com> wrote:
>
> With iptables v1.6.0 and kernel version 4.18-rc7, "iptables [-t table] -L"
> produces diagnostic output to the effect of not being able to find the table.
> Kernel version 4.17.0 and earlier work fine.
> 
> --Bob

-- 
Cheers,
Stephen Rothwell

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* [PATCH net-next] net: allow to call netif_reset_xps_queues() under cpu_read_lock
From: Andrei Vagin @ 2018-08-07  4:14 UTC (permalink / raw)
  To: David S. Miller
  Cc: Nambiar, Amritha, Michael S. Tsirkin, netdev, virtualization,
	Andrei Vagin

From: Andrei Vagin <avagin@gmail.com>

The definition of static_key_slow_inc() has cpus_read_lock in place. In the
virtio_net driver, XPS queues are initialized after setting the queue:cpu
affinity in virtnet_set_affinity() which is already protected within
cpus_read_lock. Lockdep prints a warning when we are trying to acquire
cpus_read_lock when it is already held.

This patch adds an ability to call __netif_set_xps_queue under
cpu_read_lock().

============================================
WARNING: possible recursive locking detected
4.18.0-rc3-next-20180703+ #1 Not tainted
--------------------------------------------
swapper/0/1 is trying to acquire lock:
00000000cf973d46 (cpu_hotplug_lock.rw_sem){++++}, at: static_key_slow_inc+0xe/0x20

but task is already holding lock:
00000000cf973d46 (cpu_hotplug_lock.rw_sem){++++}, at: init_vqs+0x513/0x5a0

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(cpu_hotplug_lock.rw_sem);
  lock(cpu_hotplug_lock.rw_sem);

 *** DEADLOCK ***

 May be due to missing lock nesting notation

3 locks held by swapper/0/1:
 #0: 00000000244bc7da (&dev->mutex){....}, at: __driver_attach+0x5a/0x110
 #1: 00000000cf973d46 (cpu_hotplug_lock.rw_sem){++++}, at: init_vqs+0x513/0x5a0
 #2: 000000005cd8463f (xps_map_mutex){+.+.}, at: __netif_set_xps_queue+0x8d/0xc60

Cc: "Nambiar, Amritha" <amritha.nambiar@intel.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Fixes: 8af2c06ff4b1 ("net-sysfs: Add interface for Rx queue(s) map per Tx queue")

Signed-off-by: Andrei Vagin <avagin@gmail.com>
---
 drivers/net/virtio_net.c  |  4 +++-
 include/linux/netdevice.h |  2 +-
 net/core/dev.c            | 23 +++++++++++++++++------
 net/core/net-sysfs.c      |  2 +-
 4 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 62311dde6e71..a4abcfcf26b2 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1903,9 +1903,11 @@ static void virtnet_set_affinity(struct virtnet_info *vi)
 
 	i = 0;
 	for_each_online_cpu(cpu) {
+		const unsigned long *mask = cpumask_bits(cpumask_of(cpu));
+
 		virtqueue_set_affinity(vi->rq[i].vq, cpu);
 		virtqueue_set_affinity(vi->sq[i].vq, cpu);
-		netif_set_xps_queue(vi->dev, cpumask_of(cpu), i);
+		__netif_set_xps_queue(vi->dev, mask, i, false, true);
 		i++;
 	}
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 282e2e95ad5b..124f9a00ce71 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3320,7 +3320,7 @@ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
 int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 			u16 index);
 int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
-			  u16 index, bool is_rxqs_map);
+			  u16 index, bool is_rxqs_map, bool cpuslocked);
 
 /**
  *	netif_attr_test_mask - Test a CPU or Rx queue set in a mask
diff --git a/net/core/dev.c b/net/core/dev.c
index f68122f0ab02..d6a0f64ccdd9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2176,6 +2176,7 @@ static void netif_reset_xps_queues(struct net_device *dev, u16 offset,
 	if (!static_key_false(&xps_needed))
 		return;
 
+	cpus_read_lock();
 	mutex_lock(&xps_map_mutex);
 
 	if (static_key_false(&xps_rxqs_needed)) {
@@ -2199,10 +2200,11 @@ static void netif_reset_xps_queues(struct net_device *dev, u16 offset,
 
 out_no_maps:
 	if (static_key_enabled(&xps_rxqs_needed))
-		static_key_slow_dec(&xps_rxqs_needed);
+		static_key_slow_dec_cpuslocked(&xps_rxqs_needed);
 
-	static_key_slow_dec(&xps_needed);
+	static_key_slow_dec_cpuslocked(&xps_needed);
 	mutex_unlock(&xps_map_mutex);
+	cpus_read_unlock();
 }
 
 static void netif_reset_xps_queues_gt(struct net_device *dev, u16 index)
@@ -2251,7 +2253,7 @@ static struct xps_map *expand_xps_map(struct xps_map *map, int attr_index,
 }
 
 int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
-			  u16 index, bool is_rxqs_map)
+			  u16 index, bool is_rxqs_map, bool cpuslocked)
 {
 	const unsigned long *online_mask = NULL, *possible_mask = NULL;
 	struct xps_dev_maps *dev_maps, *new_dev_maps = NULL;
@@ -2275,6 +2277,9 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 			return -EINVAL;
 	}
 
+	if (!cpuslocked)
+		cpus_read_lock();
+
 	mutex_lock(&xps_map_mutex);
 	if (is_rxqs_map) {
 		maps_sz = XPS_RXQ_DEV_MAPS_SIZE(num_tc, dev->num_rx_queues);
@@ -2317,9 +2322,9 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 	if (!new_dev_maps)
 		goto out_no_new_maps;
 
-	static_key_slow_inc(&xps_needed);
+	static_key_slow_inc_cpuslocked(&xps_needed);
 	if (is_rxqs_map)
-		static_key_slow_inc(&xps_rxqs_needed);
+		static_key_slow_inc_cpuslocked(&xps_rxqs_needed);
 
 	for (j = -1; j = netif_attrmask_next(j, possible_mask, nr_ids),
 	     j < nr_ids;) {
@@ -2427,6 +2432,8 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 
 out_no_maps:
 	mutex_unlock(&xps_map_mutex);
+	if (!cpuslocked)
+		cpus_read_unlock();
 
 	return 0;
 error:
@@ -2444,15 +2451,19 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 	}
 
 	mutex_unlock(&xps_map_mutex);
+	if (!cpuslocked)
+		cpus_read_unlock();
 
 	kfree(new_dev_maps);
 	return -ENOMEM;
 }
+EXPORT_SYMBOL_GPL(__netif_set_xps_queue);
 
 int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
 			u16 index)
 {
-	return __netif_set_xps_queue(dev, cpumask_bits(mask), index, false);
+	return __netif_set_xps_queue(dev, cpumask_bits(mask),
+						index, false, false);
 }
 EXPORT_SYMBOL(netif_set_xps_queue);
 
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 0a95bcf64cdc..06a141445d80 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1400,7 +1400,7 @@ static ssize_t xps_rxqs_store(struct netdev_queue *queue, const char *buf,
 		return err;
 	}
 
-	err = __netif_set_xps_queue(dev, mask, index, true);
+	err = __netif_set_xps_queue(dev, mask, index, true, false);
 	kfree(mask);
 	return err ? : len;
 }
-- 
2.17.1

^ permalink raw reply related

* we do the editing
From: Jason James @ 2018-08-06 14:17 UTC (permalink / raw)
  To: netdev

Want to follow up the email sent last week.
Do you have needs for photo editing?
We can edit 400 images within 24 hours.

We are working on all kinds of ecommerce photos, jewelry photos, and the
portrait images.

We do cutting out and clipping path and others, and also we provide
retouching for your photos,

You can throw us a photo and we will do testing for you to check our
quality.

Thanks,
Jason

^ permalink raw reply

* [PATCH net-next 0/2] ibmvnic: Update firmware error reporting
From: Thomas Falcon @ 2018-08-07  2:39 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, Thomas Falcon

This patch set cleans out a lot of dead code from the ibmvnic driver
and adds some more. The error ID field of the descriptor is not filled
in by firmware, so do not print it and do not use it to query for
more detailed information. Remove the unused code written for this.
Finally, update the message to print a string explainng the error
cause instead of just the error code.

Thomas Falcon (2):
  ibmvnic: Remove code to request error information
  ibmvnic: Update firmware error reporting with cause string

 drivers/net/ethernet/ibm/ibmvnic.c | 168 ++++++-------------------------------
 drivers/net/ethernet/ibm/ibmvnic.h |  33 --------
 2 files changed, 26 insertions(+), 175 deletions(-)

-- 
2.12.3

^ permalink raw reply

* [PATCH net-next 1/2] ibmvnic: Remove code to request error information
From: Thomas Falcon @ 2018-08-07  2:39 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, Thomas Falcon
In-Reply-To: <1533609599-10188-1-git-send-email-tlfalcon@linux.vnet.ibm.com>

When backing device firmware reports an error, it provides an
error ID, which is meant to be queried for more detailed error
information. Currently, however, an error ID is not provided by
the Virtual I/O server and there are not any plans to do so. For
now, it is always unfilled or zero, so request_error_information
will never be called.  Remove it.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c | 144 +------------------------------------
 drivers/net/ethernet/ibm/ibmvnic.h |  33 ---------
 2 files changed, 1 insertion(+), 176 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index ffe7acbeaa22..109e4a58efad 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -718,23 +718,6 @@ static int init_tx_pools(struct net_device *netdev)
 	return 0;
 }
 
-static void release_error_buffers(struct ibmvnic_adapter *adapter)
-{
-	struct device *dev = &adapter->vdev->dev;
-	struct ibmvnic_error_buff *error_buff, *tmp;
-	unsigned long flags;
-
-	spin_lock_irqsave(&adapter->error_list_lock, flags);
-	list_for_each_entry_safe(error_buff, tmp, &adapter->errors, list) {
-		list_del(&error_buff->list);
-		dma_unmap_single(dev, error_buff->dma, error_buff->len,
-				 DMA_FROM_DEVICE);
-		kfree(error_buff->buff);
-		kfree(error_buff);
-	}
-	spin_unlock_irqrestore(&adapter->error_list_lock, flags);
-}
-
 static void ibmvnic_napi_enable(struct ibmvnic_adapter *adapter)
 {
 	int i;
@@ -896,7 +879,6 @@ static void release_resources(struct ibmvnic_adapter *adapter)
 	release_tx_pools(adapter);
 	release_rx_pools(adapter);
 
-	release_error_buffers(adapter);
 	release_napi(adapter);
 	release_login_rsp_buffer(adapter);
 }
@@ -3843,133 +3825,16 @@ static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
 	ibmvnic_send_crq(adapter, &crq);
 }
 
-static void handle_error_info_rsp(union ibmvnic_crq *crq,
-				  struct ibmvnic_adapter *adapter)
-{
-	struct device *dev = &adapter->vdev->dev;
-	struct ibmvnic_error_buff *error_buff, *tmp;
-	unsigned long flags;
-	bool found = false;
-	int i;
-
-	if (!crq->request_error_rsp.rc.code) {
-		dev_info(dev, "Request Error Rsp returned with rc=%x\n",
-			 crq->request_error_rsp.rc.code);
-		return;
-	}
-
-	spin_lock_irqsave(&adapter->error_list_lock, flags);
-	list_for_each_entry_safe(error_buff, tmp, &adapter->errors, list)
-		if (error_buff->error_id == crq->request_error_rsp.error_id) {
-			found = true;
-			list_del(&error_buff->list);
-			break;
-		}
-	spin_unlock_irqrestore(&adapter->error_list_lock, flags);
-
-	if (!found) {
-		dev_err(dev, "Couldn't find error id %x\n",
-			be32_to_cpu(crq->request_error_rsp.error_id));
-		return;
-	}
-
-	dev_err(dev, "Detailed info for error id %x:",
-		be32_to_cpu(crq->request_error_rsp.error_id));
-
-	for (i = 0; i < error_buff->len; i++) {
-		pr_cont("%02x", (int)error_buff->buff[i]);
-		if (i % 8 == 7)
-			pr_cont(" ");
-	}
-	pr_cont("\n");
-
-	dma_unmap_single(dev, error_buff->dma, error_buff->len,
-			 DMA_FROM_DEVICE);
-	kfree(error_buff->buff);
-	kfree(error_buff);
-}
-
-static void request_error_information(struct ibmvnic_adapter *adapter,
-				      union ibmvnic_crq *err_crq)
-{
-	struct device *dev = &adapter->vdev->dev;
-	struct net_device *netdev = adapter->netdev;
-	struct ibmvnic_error_buff *error_buff;
-	unsigned long timeout = msecs_to_jiffies(30000);
-	union ibmvnic_crq crq;
-	unsigned long flags;
-	int rc, detail_len;
-
-	error_buff = kmalloc(sizeof(*error_buff), GFP_ATOMIC);
-	if (!error_buff)
-		return;
-
-	detail_len = be32_to_cpu(err_crq->error_indication.detail_error_sz);
-	error_buff->buff = kmalloc(detail_len, GFP_ATOMIC);
-	if (!error_buff->buff) {
-		kfree(error_buff);
-		return;
-	}
-
-	error_buff->dma = dma_map_single(dev, error_buff->buff, detail_len,
-					 DMA_FROM_DEVICE);
-	if (dma_mapping_error(dev, error_buff->dma)) {
-		netdev_err(netdev, "Couldn't map error buffer\n");
-		kfree(error_buff->buff);
-		kfree(error_buff);
-		return;
-	}
-
-	error_buff->len = detail_len;
-	error_buff->error_id = err_crq->error_indication.error_id;
-
-	spin_lock_irqsave(&adapter->error_list_lock, flags);
-	list_add_tail(&error_buff->list, &adapter->errors);
-	spin_unlock_irqrestore(&adapter->error_list_lock, flags);
-
-	memset(&crq, 0, sizeof(crq));
-	crq.request_error_info.first = IBMVNIC_CRQ_CMD;
-	crq.request_error_info.cmd = REQUEST_ERROR_INFO;
-	crq.request_error_info.ioba = cpu_to_be32(error_buff->dma);
-	crq.request_error_info.len = cpu_to_be32(detail_len);
-	crq.request_error_info.error_id = err_crq->error_indication.error_id;
-
-	rc = ibmvnic_send_crq(adapter, &crq);
-	if (rc) {
-		netdev_err(netdev, "failed to request error information\n");
-		goto err_info_fail;
-	}
-
-	if (!wait_for_completion_timeout(&adapter->init_done, timeout)) {
-		netdev_err(netdev, "timeout waiting for error information\n");
-		goto err_info_fail;
-	}
-
-	return;
-
-err_info_fail:
-	spin_lock_irqsave(&adapter->error_list_lock, flags);
-	list_del(&error_buff->list);
-	spin_unlock_irqrestore(&adapter->error_list_lock, flags);
-
-	kfree(error_buff->buff);
-	kfree(error_buff);
-}
-
 static void handle_error_indication(union ibmvnic_crq *crq,
 				    struct ibmvnic_adapter *adapter)
 {
 	struct device *dev = &adapter->vdev->dev;
 
-	dev_err(dev, "Firmware reports %serror id %x, cause %d\n",
+	dev_err(dev, "Firmware reports %serror, cause %d\n",
 		crq->error_indication.flags
 			& IBMVNIC_FATAL_ERROR ? "FATAL " : "",
-		be32_to_cpu(crq->error_indication.error_id),
 		be16_to_cpu(crq->error_indication.error_cause));
 
-	if (be32_to_cpu(crq->error_indication.error_id))
-		request_error_information(adapter, crq);
-
 	if (crq->error_indication.flags & IBMVNIC_FATAL_ERROR)
 		ibmvnic_reset(adapter, VNIC_RESET_FATAL);
 	else
@@ -4468,10 +4333,6 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
 		netdev_dbg(netdev, "Got Error Indication\n");
 		handle_error_indication(crq, adapter);
 		break;
-	case REQUEST_ERROR_RSP:
-		netdev_dbg(netdev, "Got Error Detail Response\n");
-		handle_error_info_rsp(crq, adapter);
-		break;
 	case REQUEST_STATISTICS_RSP:
 		netdev_dbg(netdev, "Got Statistics Response\n");
 		complete(&adapter->stats_done);
@@ -4830,9 +4691,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
 
 	spin_lock_init(&adapter->stats_lock);
 
-	INIT_LIST_HEAD(&adapter->errors);
-	spin_lock_init(&adapter->error_list_lock);
-
 	INIT_WORK(&adapter->ibmvnic_reset, __ibmvnic_reset);
 	INIT_LIST_HEAD(&adapter->rwi_list);
 	mutex_init(&adapter->reset_lock);
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
index f9fb780102ac..f06eec145ca6 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.h
+++ b/drivers/net/ethernet/ibm/ibmvnic.h
@@ -512,24 +512,6 @@ struct ibmvnic_error_indication {
 	u8 reserved2[2];
 } __packed __aligned(8);
 
-struct ibmvnic_request_error_info {
-	u8 first;
-	u8 cmd;
-	u8 reserved[2];
-	__be32 ioba;
-	__be32 len;
-	__be32 error_id;
-} __packed __aligned(8);
-
-struct ibmvnic_request_error_rsp {
-	u8 first;
-	u8 cmd;
-	u8 reserved[2];
-	__be32 error_id;
-	__be32 len;
-	struct ibmvnic_rc rc;
-} __packed __aligned(8);
-
 struct ibmvnic_link_state_indication {
 	u8 first;
 	u8 cmd;
@@ -709,8 +691,6 @@ union ibmvnic_crq {
 	struct ibmvnic_request_debug_stats request_debug_stats;
 	struct ibmvnic_request_debug_stats request_debug_stats_rsp;
 	struct ibmvnic_error_indication error_indication;
-	struct ibmvnic_request_error_info request_error_info;
-	struct ibmvnic_request_error_rsp request_error_rsp;
 	struct ibmvnic_link_state_indication link_state_indication;
 	struct ibmvnic_change_mac_addr change_mac_addr;
 	struct ibmvnic_change_mac_addr change_mac_addr_rsp;
@@ -809,8 +789,6 @@ enum ibmvnic_commands {
 	SET_PHYS_PARMS = 0x07,
 	SET_PHYS_PARMS_RSP = 0x87,
 	ERROR_INDICATION = 0x08,
-	REQUEST_ERROR_INFO = 0x09,
-	REQUEST_ERROR_RSP = 0x89,
 	LOGICAL_LINK_STATE = 0x0C,
 	LOGICAL_LINK_STATE_RSP = 0x8C,
 	REQUEST_STATISTICS = 0x0D,
@@ -945,14 +923,6 @@ struct ibmvnic_rx_pool {
 	struct ibmvnic_long_term_buff long_term_buff;
 };
 
-struct ibmvnic_error_buff {
-	char *buff;
-	dma_addr_t dma;
-	int len;
-	struct list_head list;
-	__be32 error_id;
-};
-
 struct ibmvnic_vpd {
 	unsigned char *buff;
 	dma_addr_t dma_addr;
@@ -1047,9 +1017,6 @@ struct ibmvnic_adapter {
 	struct completion init_done;
 	int init_done_rc;
 
-	struct list_head errors;
-	spinlock_t error_list_lock;
-
 	struct completion fw_done;
 	int fw_done_rc;
 
-- 
2.12.3

^ permalink raw reply related

* [PATCH net-next 2/2] ibmvnic: Update firmware error reporting with cause string
From: Thomas Falcon @ 2018-08-07  2:39 UTC (permalink / raw)
  To: netdev; +Cc: jallen, nfont, Thomas Falcon
In-Reply-To: <1533609599-10188-1-git-send-email-tlfalcon@linux.vnet.ibm.com>

Print a string instead of the error code. Since there is a
possibility that the driver can recover, classify it as a
warning instead of an error.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c | 34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 109e4a58efad..dafdd4ade705 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3825,15 +3825,41 @@ static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
 	ibmvnic_send_crq(adapter, &crq);
 }
 
+static const char *ibmvnic_fw_err_cause(u16 cause)
+{
+	switch (cause) {
+	case ADAPTER_PROBLEM:
+		return "adapter problem";
+	case BUS_PROBLEM:
+		return "bus problem";
+	case FW_PROBLEM:
+		return "firmware problem";
+	case DD_PROBLEM:
+		return "device driver problem";
+	case EEH_RECOVERY:
+		return "EEH recovery";
+	case FW_UPDATED:
+		return "firmware updated";
+	case LOW_MEMORY:
+		return "low Memory";
+	default:
+		return "unknown";
+	}
+}
+
 static void handle_error_indication(union ibmvnic_crq *crq,
 				    struct ibmvnic_adapter *adapter)
 {
 	struct device *dev = &adapter->vdev->dev;
+	u16 cause;
+
+	cause = be16_to_cpu(crq->error_indication.error_cause);
 
-	dev_err(dev, "Firmware reports %serror, cause %d\n",
-		crq->error_indication.flags
-			& IBMVNIC_FATAL_ERROR ? "FATAL " : "",
-		be16_to_cpu(crq->error_indication.error_cause));
+	dev_warn_ratelimited(dev,
+			     "Firmware reports %serror, cause: %s. Starting recovery...\n",
+			     crq->error_indication.flags
+				& IBMVNIC_FATAL_ERROR ? "FATAL " : "",
+			     ibmvnic_fw_err_cause(cause));
 
 	if (crq->error_indication.flags & IBMVNIC_FATAL_ERROR)
 		ibmvnic_reset(adapter, VNIC_RESET_FATAL);
-- 
2.12.3

^ permalink raw reply related

* Re: [RFC bpf-next v2 3/3] docs: Split filter.txt into separate documents.
From: Tobin C. Harding @ 2018-08-07  2:48 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: Daniel Borkmann, Alexei Starovoitov, David S. Miller, linux-doc,
	netdev, linux-kernel
In-Reply-To: <20180803070818.3d3e52e4@lwn.net>

On Fri, Aug 03, 2018 at 07:08:18AM -0600, Jonathan Corbet wrote:
> On Fri,  3 Aug 2018 08:31:00 +1000
> "Tobin C. Harding" <me@tobin.cc> wrote:
> 
> > In preparation for conversion of Documentation/networking/filter.txt it
> > was noticed that the document contains a lot of information.  The
> > document may be more accessible if it was split up.  Some parts pertain
> > to everyone, let's put these bits in core-api/.  The more hard core bits
> > about eBPF internals could be put with the other BPF docs in
> > Documentation/bpf/.  There is a small bit of information on testing and
> > miscellaneous matters that are useful for everyone (everyone does
> > testing, right) so lets keep that info at the bottom of both new
> > documents.  (This includes the original authors.)
> > 
> > Split Documentation/networking/filter.txt into
> > Documentation/bpf/eBPF.rst and Documentation/core-api/bpf.rst
> > 
> > Signed-off-by: Tobin C. Harding <me@tobin.cc>
> > ---
> >  .../{networking/filter.txt => bpf/eBPF.rst}   | 590 +----------------
> >  Documentation/core-api/bpf.rst                | 599 ++++++++++++++++++
> 
> Some overall thoughts...
> 
>  - A good step in the right direction, and worthwhile work.  Thanks for
>    doing this!

Thanks for you thoughts Jon.

>  - The new eBPF.rst file is not actually an RST file.  Giving it that
>    extension while not converting the contents will confuse Sphinx.  I'd
>    call it .txt at this point.

I'm a bit stumped as the best way to structure a patch set that does

	foo.txt -> foo.rst

conversion.  FTR the conditions I'm trying to meet are:

1. Each patch should be discreet and leave the kernel in a _correct_
   state.
2. One thing per patch.
3. Maintainers should be able to take the first 'n' patches without
   taking the whole set.

How about these steps:

	1. start with foo.txt
	2. do typo and grammar fixes (any number of patches).
	3. rename to foo.rst, do whitespace changes, code snippet
	   indentation, heading adornments, update references to this file.
	   (single patch).
	4. Fix up references in the file text to use RST (i.e :ref: blah)
	5. Fix up RST markers (backticks etc). (any number of patches)

Any better ideas or further suggestions?  I like 4 and 5 separate since
they can be done in multiple ways so may be controversial.

>  - The document now known as core-api/bpf.rst is still covering two
>    separate things.  One is the socket-filter API, while the other is
>    classic BPF.  Since cBPF is still used elsewhere (seccomp), it's of
>    wider interest.  Also, this is user-space API stuff, not kernel API
>    stuff, so I think that Documentation/userspace-api/ is the right place
>    for it.
> 
> I'm kind of thinking this through as I type it, but I guess I'm arguing
> for the creation of three files, all in Documentation/userspace-api/:
> 
>  - socket-filter.rst on how to write socket filters
>  - cBPF.rst describing classic BPF and its tools
>  - eBPF.rst describing extended BPF
> 
> Tying cBPF.rst into seccomp_filter.rst could also be helpful for our
> readers.
> 
> Does this make sense?

Yep, that all makes sense.  Patch set to come.

thanks,
Tobin.

^ permalink raw reply

* lening aanbod
From: FUNDING TRUST FINANCE @ 2018-08-07  2:40 UTC (permalink / raw)




Goede dag,

   We FUNDING TRUST FINANCE geven leningen per postadvertentie. Wij bieden verschillende soorten leningen of projectleningen (korte en lange termijnleningen, persoonlijke leningen, leningen aan bedrijven enz.) Met een rentetarief van 3%. We verstrekken leningen aan mensen in nood, ongeacht hun locatie, geslacht, burgerlijke staat, opleiding of baan, maar moeten een legale manier van terugbetaling hebben. Onze leningen vari&euml;ren tussen 5.000,00 tot 20.000.000,00 US Dollar of Euro of Pond met een maximale duur van 15 jaar. Als u ge&iuml;nteresseerd bent in meer informatie, neem dan contact met ons op via mail, info.fundingtrustfinance@gmail.com of website: www.fundingtrustfinance.com

1-De klant moet een korte samenvatting van het project verzenden. Dit moet het totale bedrag omvatten dat vereist is voor het project, geschat rendement op investering, terugbetalingsperiode van de lening, dit mag niet meer dan 20 jaar zijn

Vul het onderstaande formulier in.

INFORMATIE NODIG:

Jullie namen:
Adres: ...........
Telefoon: ...........
Benodigde hoeveelheid: .......
Looptijd: ...............
Beroep: ...........
Maandelijks inkomensniveau: ......
Geslacht: ..............
Geboortedatum: .......
Staat: ...............
Land: .........
Doel: .........

Bedankt voor uw begrip.

Beste wensen,

Mr.Ronny Hens
FUNDING TRUST FINANCE
info.fundingtrustfinance@gmail.com
Website: www.fundingtrustfinance.com

^ permalink raw reply

* Re: [PATCH net-next 2/2] ibmvnic: Update firmware error reporting with cause string
From: Nathan Fontenot @ 2018-08-07  3:48 UTC (permalink / raw)
  To: Thomas Falcon, netdev; +Cc: jallen
In-Reply-To: <1533609599-10188-3-git-send-email-tlfalcon@linux.vnet.ibm.com>


On 08/06/2018 09:39 PM, Thomas Falcon wrote:
> Print a string instead of the error code. Since there is a
> possibility that the driver can recover, classify it as a
> warning instead of an error.
> 
> Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
> ---
>   drivers/net/ethernet/ibm/ibmvnic.c | 34 ++++++++++++++++++++++++++++++----
>   1 file changed, 30 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
> index 109e4a58efad..dafdd4ade705 100644
> --- a/drivers/net/ethernet/ibm/ibmvnic.c
> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
> @@ -3825,15 +3825,41 @@ static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
>   	ibmvnic_send_crq(adapter, &crq);
>   }
> 
> +static const char *ibmvnic_fw_err_cause(u16 cause)
> +{
> +	switch (cause) {
> +	case ADAPTER_PROBLEM:
> +		return "adapter problem";
> +	case BUS_PROBLEM:
> +		return "bus problem";
> +	case FW_PROBLEM:
> +		return "firmware problem";
> +	case DD_PROBLEM:
> +		return "device driver problem";
> +	case EEH_RECOVERY:
> +		return "EEH recovery";
> +	case FW_UPDATED:
> +		return "firmware updated";
> +	case LOW_MEMORY:
> +		return "low Memory";
> +	default:
> +		return "unknown";
> +	}
> +}
> +
>   static void handle_error_indication(union ibmvnic_crq *crq,
>   				    struct ibmvnic_adapter *adapter)
>   {
>   	struct device *dev = &adapter->vdev->dev;
> +	u16 cause;
> +
> +	cause = be16_to_cpu(crq->error_indication.error_cause);
> 
> -	dev_err(dev, "Firmware reports %serror, cause %d\n",
> -		crq->error_indication.flags
> -			& IBMVNIC_FATAL_ERROR ? "FATAL " : "",
> -		be16_to_cpu(crq->error_indication.error_cause));
> +	dev_warn_ratelimited(dev,
> +			     "Firmware reports %serror, cause: %s. Starting recovery...\n",

                                                ^^^^^^^

You're going to want a space between after the %s here.

-Nathan

> +			     crq->error_indication.flags
> +				& IBMVNIC_FATAL_ERROR ? "FATAL " : "",
> +			     ibmvnic_fw_err_cause(cause));
> 
>   	if (crq->error_indication.flags & IBMVNIC_FATAL_ERROR)
>   		ibmvnic_reset(adapter, VNIC_RESET_FATAL);
> 

^ permalink raw reply

* Re: [PATCH net-next 2/2] ibmvnic: Update firmware error reporting with cause string
From: Thomas Falcon @ 2018-08-07  4:34 UTC (permalink / raw)
  To: Nathan Fontenot, netdev; +Cc: jallen
In-Reply-To: <4c6e57db-b5b7-fa9d-d3ef-9016dfe0be21@linux.vnet.ibm.com>

On 08/06/2018 10:48 PM, Nathan Fontenot wrote:
>
> On 08/06/2018 09:39 PM, Thomas Falcon wrote:
>> Print a string instead of the error code. Since there is a
>> possibility that the driver can recover, classify it as a
>> warning instead of an error.
>>
>> Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
>> ---
>>   drivers/net/ethernet/ibm/ibmvnic.c | 34 
>> ++++++++++++++++++++++++++++++----
>>   1 file changed, 30 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
>> b/drivers/net/ethernet/ibm/ibmvnic.c
>> index 109e4a58efad..dafdd4ade705 100644
>> --- a/drivers/net/ethernet/ibm/ibmvnic.c
>> +++ b/drivers/net/ethernet/ibm/ibmvnic.c
>> @@ -3825,15 +3825,41 @@ static void 
>> handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
>>       ibmvnic_send_crq(adapter, &crq);
>>   }
>>
>> +static const char *ibmvnic_fw_err_cause(u16 cause)
>> +{
>> +    switch (cause) {
>> +    case ADAPTER_PROBLEM:
>> +        return "adapter problem";
>> +    case BUS_PROBLEM:
>> +        return "bus problem";
>> +    case FW_PROBLEM:
>> +        return "firmware problem";
>> +    case DD_PROBLEM:
>> +        return "device driver problem";
>> +    case EEH_RECOVERY:
>> +        return "EEH recovery";
>> +    case FW_UPDATED:
>> +        return "firmware updated";
>> +    case LOW_MEMORY:
>> +        return "low Memory";
>> +    default:
>> +        return "unknown";
>> +    }
>> +}
>> +
>>   static void handle_error_indication(union ibmvnic_crq *crq,
>>                       struct ibmvnic_adapter *adapter)
>>   {
>>       struct device *dev = &adapter->vdev->dev;
>> +    u16 cause;
>> +
>> +    cause = be16_to_cpu(crq->error_indication.error_cause);
>>
>> -    dev_err(dev, "Firmware reports %serror, cause %d\n",
>> -        crq->error_indication.flags
>> -            & IBMVNIC_FATAL_ERROR ? "FATAL " : "",
>> -        be16_to_cpu(crq->error_indication.error_cause));
>> +    dev_warn_ratelimited(dev,
>> +                 "Firmware reports %serror, cause: %s. Starting 
>> recovery...\n",
>
>                                                ^^^^^^^
>
> You're going to want a space between after the %s here.
>
> -Nathan
>

It does look odd at first glance, but there is a space after "FATAL" below.

Thanks,
Tom

>> + crq->error_indication.flags
>> +                & IBMVNIC_FATAL_ERROR ? "FATAL " : "",
>> +                 ibmvnic_fw_err_cause(cause));
>>
>>       if (crq->error_indication.flags & IBMVNIC_FATAL_ERROR)
>>           ibmvnic_reset(adapter, VNIC_RESET_FATAL);
>>

^ 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