commit:     b2dfe994a979d5ace0f18e467c1e82bfa4d3ab30
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Mar 31 22:19:50 2018 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Mar 31 22:19:50 2018 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b2dfe994

Linux patch 4.15.15

 0000_README              |    4 +
 1014_linux-4.15.15.patch | 1683 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1687 insertions(+)

diff --git a/0000_README b/0000_README
index f4d8a80..f1a4ce6 100644
--- a/0000_README
+++ b/0000_README
@@ -99,6 +99,10 @@ Patch:  1013_linux-4.15.14.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.15.14
 
+Patch:  1014_linux-4.15.15.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.15.15
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1014_linux-4.15.15.patch b/1014_linux-4.15.15.patch
new file mode 100644
index 0000000..ab1089f
--- /dev/null
+++ b/1014_linux-4.15.15.patch
@@ -0,0 +1,1683 @@
+diff --git a/Makefile b/Makefile
+index a5e561900daf..20c9b7bfeed4 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 15
+-SUBLEVEL = 14
++SUBLEVEL = 15
+ EXTRAVERSION =
+ NAME = Fearless Coyote
+ 
+diff --git a/drivers/net/ethernet/arc/emac_rockchip.c 
b/drivers/net/ethernet/arc/emac_rockchip.c
+index 16f9bee992fe..0f6576802607 100644
+--- a/drivers/net/ethernet/arc/emac_rockchip.c
++++ b/drivers/net/ethernet/arc/emac_rockchip.c
+@@ -169,8 +169,10 @@ static int emac_rockchip_probe(struct platform_device 
*pdev)
+       /* Optional regulator for PHY */
+       priv->regulator = devm_regulator_get_optional(dev, "phy");
+       if (IS_ERR(priv->regulator)) {
+-              if (PTR_ERR(priv->regulator) == -EPROBE_DEFER)
+-                      return -EPROBE_DEFER;
++              if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) {
++                      err = -EPROBE_DEFER;
++                      goto out_clk_disable;
++              }
+               dev_err(dev, "no regulator found\n");
+               priv->regulator = NULL;
+       }
+diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c 
b/drivers/net/ethernet/broadcom/bcmsysport.c
+index 087f01b4dc3a..f239ef2e6f23 100644
+--- a/drivers/net/ethernet/broadcom/bcmsysport.c
++++ b/drivers/net/ethernet/broadcom/bcmsysport.c
+@@ -855,10 +855,12 @@ static void bcm_sysport_tx_reclaim_one(struct 
bcm_sysport_tx_ring *ring,
+ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
+                                            struct bcm_sysport_tx_ring *ring)
+ {
+-      unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs;
+       unsigned int pkts_compl = 0, bytes_compl = 0;
+       struct net_device *ndev = priv->netdev;
++      unsigned int txbds_processed = 0;
+       struct bcm_sysport_cb *cb;
++      unsigned int txbds_ready;
++      unsigned int c_index;
+       u32 hw_ind;
+ 
+       /* Clear status before servicing to reduce spurious interrupts */
+@@ -871,29 +873,23 @@ static unsigned int __bcm_sysport_tx_reclaim(struct 
bcm_sysport_priv *priv,
+       /* Compute how many descriptors have been processed since last call */
+       hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index));
+       c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK;
+-      ring->p_index = (hw_ind & RING_PROD_INDEX_MASK);
+-
+-      last_c_index = ring->c_index;
+-      num_tx_cbs = ring->size;
+-
+-      c_index &= (num_tx_cbs - 1);
+-
+-      if (c_index >= last_c_index)
+-              last_tx_cn = c_index - last_c_index;
+-      else
+-              last_tx_cn = num_tx_cbs - last_c_index + c_index;
++      txbds_ready = (c_index - ring->c_index) & RING_CONS_INDEX_MASK;
+ 
+       netif_dbg(priv, tx_done, ndev,
+-                "ring=%d c_index=%d last_tx_cn=%d last_c_index=%d\n",
+-                ring->index, c_index, last_tx_cn, last_c_index);
++                "ring=%d old_c_index=%u c_index=%u txbds_ready=%u\n",
++                ring->index, ring->c_index, c_index, txbds_ready);
+ 
+-      while (last_tx_cn-- > 0) {
+-              cb = ring->cbs + last_c_index;
++      while (txbds_processed < txbds_ready) {
++              cb = &ring->cbs[ring->clean_index];
+               bcm_sysport_tx_reclaim_one(ring, cb, &bytes_compl, &pkts_compl);
+ 
+               ring->desc_count++;
+-              last_c_index++;
+-              last_c_index &= (num_tx_cbs - 1);
++              txbds_processed++;
++
++              if (likely(ring->clean_index < ring->size - 1))
++                      ring->clean_index++;
++              else
++                      ring->clean_index = 0;
+       }
+ 
+       u64_stats_update_begin(&priv->syncp);
+@@ -1406,6 +1402,7 @@ static int bcm_sysport_init_tx_ring(struct 
bcm_sysport_priv *priv,
+       netif_tx_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64);
+       ring->index = index;
+       ring->size = size;
++      ring->clean_index = 0;
+       ring->alloc_size = ring->size;
+       ring->desc_cpu = p;
+       ring->desc_count = ring->size;
+diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h 
b/drivers/net/ethernet/broadcom/bcmsysport.h
+index f5a984c1c986..19c91c76e327 100644
+--- a/drivers/net/ethernet/broadcom/bcmsysport.h
++++ b/drivers/net/ethernet/broadcom/bcmsysport.h
+@@ -706,7 +706,7 @@ struct bcm_sysport_tx_ring {
+       unsigned int    desc_count;     /* Number of descriptors */
+       unsigned int    curr_desc;      /* Current descriptor */
+       unsigned int    c_index;        /* Last consumer index */
+-      unsigned int    p_index;        /* Current producer index */
++      unsigned int    clean_index;    /* Current clean index */
+       struct bcm_sysport_cb *cbs;     /* Transmit control blocks */
+       struct dma_desc *desc_cpu;      /* CPU view of the descriptor */
+       struct bcm_sysport_priv *priv;  /* private context backpointer */
+diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+index 7caa8da48421..e4ec32a9ca15 100644
+--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+@@ -2008,7 +2008,6 @@ static inline int dpaa_xmit(struct dpaa_priv *priv,
+       }
+ 
+       if (unlikely(err < 0)) {
+-              percpu_stats->tx_errors++;
+               percpu_stats->tx_fifo_errors++;
+               return err;
+       }
+@@ -2278,7 +2277,6 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
+       vaddr = phys_to_virt(addr);
+       prefetch(vaddr + qm_fd_get_offset(fd));
+ 
+-      fd_format = qm_fd_get_format(fd);
+       /* The only FD types that we may receive are contig and S/G */
+       WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg));
+ 
+@@ -2311,8 +2309,10 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
+ 
+       skb_len = skb->len;
+ 
+-      if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
++      if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) {
++              percpu_stats->rx_dropped++;
+               return qman_cb_dqrr_consume;
++      }
+ 
+       percpu_stats->rx_packets++;
+       percpu_stats->rx_bytes += skb_len;
+@@ -2860,7 +2860,7 @@ static int dpaa_remove(struct platform_device *pdev)
+       struct device *dev;
+       int err;
+ 
+-      dev = &pdev->dev;
++      dev = pdev->dev.parent;
+       net_dev = dev_get_drvdata(dev);
+ 
+       priv = netdev_priv(net_dev);
+diff --git a/drivers/net/ethernet/freescale/fec_main.c 
b/drivers/net/ethernet/freescale/fec_main.c
+index a74300a4459c..febadd39e29a 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -3578,6 +3578,8 @@ fec_drv_remove(struct platform_device *pdev)
+       fec_enet_mii_remove(fep);
+       if (fep->reg_phy)
+               regulator_disable(fep->reg_phy);
++      pm_runtime_put(&pdev->dev);
++      pm_runtime_disable(&pdev->dev);
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
+       of_node_put(fep->phy_node);
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
+index 93728c694e6d..0a9adc5962fb 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
+@@ -385,13 +385,13 @@ static const struct mlxsw_sp_sb_cm 
mlxsw_sp_sb_cms_egress[] = {
+ 
+ static const struct mlxsw_sp_sb_cm mlxsw_sp_cpu_port_sb_cms[] = {
+       MLXSW_SP_CPU_PORT_SB_CM,
++      MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
++      MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
++      MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
++      MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
++      MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
+       MLXSW_SP_CPU_PORT_SB_CM,
+-      MLXSW_SP_CPU_PORT_SB_CM,
+-      MLXSW_SP_CPU_PORT_SB_CM,
+-      MLXSW_SP_CPU_PORT_SB_CM,
+-      MLXSW_SP_CPU_PORT_SB_CM,
+-      MLXSW_SP_CPU_PORT_SB_CM,
+-      MLXSW_SP_SB_CM(10000, 0, 0),
++      MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
+       MLXSW_SP_CPU_PORT_SB_CM,
+       MLXSW_SP_CPU_PORT_SB_CM,
+       MLXSW_SP_CPU_PORT_SB_CM,
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c 
b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+index 409041eab189..fba7f5c34b85 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
+@@ -1681,6 +1681,13 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn,
+       iph = (struct iphdr *)((u8 *)(ethh) + eth_hlen);
+ 
+       if (eth_type == ETH_P_IP) {
++              if (iph->protocol != IPPROTO_TCP) {
++                      DP_NOTICE(p_hwfn,
++                                "Unexpected ip protocol on ll2 %x\n",
++                                iph->protocol);
++                      return -EINVAL;
++              }
++
+               cm_info->local_ip[0] = ntohl(iph->daddr);
+               cm_info->remote_ip[0] = ntohl(iph->saddr);
+               cm_info->ip_version = TCP_IPV4;
+@@ -1689,6 +1696,14 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn,
+               *payload_len = ntohs(iph->tot_len) - ip_hlen;
+       } else if (eth_type == ETH_P_IPV6) {
+               ip6h = (struct ipv6hdr *)iph;
++
++              if (ip6h->nexthdr != IPPROTO_TCP) {
++                      DP_NOTICE(p_hwfn,
++                                "Unexpected ip protocol on ll2 %x\n",
++                                iph->protocol);
++                      return -EINVAL;
++              }
++
+               for (i = 0; i < 4; i++) {
+                       cm_info->local_ip[i] =
+                           ntohl(ip6h->daddr.in6_u.u6_addr32[i]);
+@@ -1906,8 +1921,8 @@ qed_iwarp_update_fpdu_length(struct qed_hwfn *p_hwfn,
+               /* Missing lower byte is now available */
+               mpa_len = fpdu->fpdu_length | *mpa_data;
+               fpdu->fpdu_length = QED_IWARP_FPDU_LEN_WITH_PAD(mpa_len);
+-              fpdu->mpa_frag_len = fpdu->fpdu_length;
+               /* one byte of hdr */
++              fpdu->mpa_frag_len = 1;
+               fpdu->incomplete_bytes = fpdu->fpdu_length - 1;
+               DP_VERBOSE(p_hwfn,
+                          QED_MSG_RDMA,
+diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c 
b/drivers/net/ethernet/qlogic/qede/qede_main.c
+index 8f9b3eb82137..cdcccecfc24a 100644
+--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
++++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
+@@ -2066,8 +2066,6 @@ static int qede_load(struct qede_dev *edev, enum 
qede_load_mode mode,
+       link_params.link_up = true;
+       edev->ops->common->set_link(edev->cdev, &link_params);
+ 
+-      qede_rdma_dev_event_open(edev);
+-
+       edev->state = QEDE_STATE_OPEN;
+ 
+       DP_INFO(edev, "Ending successfully qede load\n");
+@@ -2168,12 +2166,14 @@ static void qede_link_update(void *dev, struct 
qed_link_output *link)
+                       DP_NOTICE(edev, "Link is up\n");
+                       netif_tx_start_all_queues(edev->ndev);
+                       netif_carrier_on(edev->ndev);
++                      qede_rdma_dev_event_open(edev);
+               }
+       } else {
+               if (netif_carrier_ok(edev->ndev)) {
+                       DP_NOTICE(edev, "Link is down\n");
+                       netif_tx_disable(edev->ndev);
+                       netif_carrier_off(edev->ndev);
++                      qede_rdma_dev_event_close(edev);
+               }
+       }
+ }
+diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
+index a1ffc3ed77f9..c08d74cd1fd2 100644
+--- a/drivers/net/ethernet/ti/cpsw.c
++++ b/drivers/net/ethernet/ti/cpsw.c
+@@ -996,7 +996,8 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
+               /* set speed_in input in case RMII mode is used in 100Mbps */
+               if (phy->speed == 100)
+                       mac_control |= BIT(15);
+-              else if (phy->speed == 10)
++              /* in band mode only works in 10Mbps RGMII mode */
++              else if ((phy->speed == 10) && phy_interface_is_rgmii(phy))
+                       mac_control |= BIT(18); /* In Band mode */
+ 
+               if (priv->rx_pause)
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index a0f2be81d52e..4884f6149b0a 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1036,7 +1036,7 @@ static netdev_features_t macvlan_fix_features(struct 
net_device *dev,
+       lowerdev_features &= (features | ~NETIF_F_LRO);
+       features = netdev_increment_features(lowerdev_features, features, mask);
+       features |= ALWAYS_ON_FEATURES;
+-      features &= ~NETIF_F_NETNS_LOCAL;
++      features &= (ALWAYS_ON_FEATURES | MACVLAN_FEATURES);
+ 
+       return features;
+ }
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index 39de77a8bb63..dba6d17ad885 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -614,6 +614,91 @@ static void phy_error(struct phy_device *phydev)
+       phy_trigger_machine(phydev, false);
+ }
+ 
++/**
++ * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
++ * @phydev: target phy_device struct
++ */
++static int phy_disable_interrupts(struct phy_device *phydev)
++{
++      int err;
++
++      /* Disable PHY interrupts */
++      err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
++      if (err)
++              goto phy_err;
++
++      /* Clear the interrupt */
++      err = phy_clear_interrupt(phydev);
++      if (err)
++              goto phy_err;
++
++      return 0;
++
++phy_err:
++      phy_error(phydev);
++
++      return err;
++}
++
++/**
++ * phy_change - Called by the phy_interrupt to handle PHY changes
++ * @phydev: phy_device struct that interrupted
++ */
++static irqreturn_t phy_change(struct phy_device *phydev)
++{
++      if (phy_interrupt_is_valid(phydev)) {
++              if (phydev->drv->did_interrupt &&
++                  !phydev->drv->did_interrupt(phydev))
++                      goto ignore;
++
++              if (phy_disable_interrupts(phydev))
++                      goto phy_err;
++      }
++
++      mutex_lock(&phydev->lock);
++      if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
++              phydev->state = PHY_CHANGELINK;
++      mutex_unlock(&phydev->lock);
++
++      if (phy_interrupt_is_valid(phydev)) {
++              atomic_dec(&phydev->irq_disable);
++              enable_irq(phydev->irq);
++
++              /* Reenable interrupts */
++              if (PHY_HALTED != phydev->state &&
++                  phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED))
++                      goto irq_enable_err;
++      }
++
++      /* reschedule state queue work to run as soon as possible */
++      phy_trigger_machine(phydev, true);
++      return IRQ_HANDLED;
++
++ignore:
++      atomic_dec(&phydev->irq_disable);
++      enable_irq(phydev->irq);
++      return IRQ_NONE;
++
++irq_enable_err:
++      disable_irq(phydev->irq);
++      atomic_inc(&phydev->irq_disable);
++phy_err:
++      phy_error(phydev);
++      return IRQ_NONE;
++}
++
++/**
++ * phy_change_work - Scheduled by the phy_mac_interrupt to handle PHY changes
++ * @work: work_struct that describes the work to be done
++ */
++void phy_change_work(struct work_struct *work)
++{
++      struct phy_device *phydev =
++              container_of(work, struct phy_device, phy_queue);
++
++      phy_change(phydev);
++}
++
+ /**
+  * phy_interrupt - PHY interrupt handler
+  * @irq: interrupt line
+@@ -632,9 +717,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
+       disable_irq_nosync(irq);
+       atomic_inc(&phydev->irq_disable);
+ 
+-      phy_change(phydev);
+-
+-      return IRQ_HANDLED;
++      return phy_change(phydev);
+ }
+ 
+ /**
+@@ -651,32 +734,6 @@ static int phy_enable_interrupts(struct phy_device 
*phydev)
+       return phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
+ }
+ 
+-/**
+- * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
+- * @phydev: target phy_device struct
+- */
+-static int phy_disable_interrupts(struct phy_device *phydev)
+-{
+-      int err;
+-
+-      /* Disable PHY interrupts */
+-      err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
+-      if (err)
+-              goto phy_err;
+-
+-      /* Clear the interrupt */
+-      err = phy_clear_interrupt(phydev);
+-      if (err)
+-              goto phy_err;
+-
+-      return 0;
+-
+-phy_err:
+-      phy_error(phydev);
+-
+-      return err;
+-}
+-
+ /**
+  * phy_start_interrupts - request and enable interrupts for a PHY device
+  * @phydev: target phy_device struct
+@@ -727,64 +784,6 @@ int phy_stop_interrupts(struct phy_device *phydev)
+ }
+ EXPORT_SYMBOL(phy_stop_interrupts);
+ 
+-/**
+- * phy_change - Called by the phy_interrupt to handle PHY changes
+- * @phydev: phy_device struct that interrupted
+- */
+-void phy_change(struct phy_device *phydev)
+-{
+-      if (phy_interrupt_is_valid(phydev)) {
+-              if (phydev->drv->did_interrupt &&
+-                  !phydev->drv->did_interrupt(phydev))
+-                      goto ignore;
+-
+-              if (phy_disable_interrupts(phydev))
+-                      goto phy_err;
+-      }
+-
+-      mutex_lock(&phydev->lock);
+-      if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
+-              phydev->state = PHY_CHANGELINK;
+-      mutex_unlock(&phydev->lock);
+-
+-      if (phy_interrupt_is_valid(phydev)) {
+-              atomic_dec(&phydev->irq_disable);
+-              enable_irq(phydev->irq);
+-
+-              /* Reenable interrupts */
+-              if (PHY_HALTED != phydev->state &&
+-                  phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED))
+-                      goto irq_enable_err;
+-      }
+-
+-      /* reschedule state queue work to run as soon as possible */
+-      phy_trigger_machine(phydev, true);
+-      return;
+-
+-ignore:
+-      atomic_dec(&phydev->irq_disable);
+-      enable_irq(phydev->irq);
+-      return;
+-
+-irq_enable_err:
+-      disable_irq(phydev->irq);
+-      atomic_inc(&phydev->irq_disable);
+-phy_err:
+-      phy_error(phydev);
+-}
+-
+-/**
+- * phy_change_work - Scheduled by the phy_mac_interrupt to handle PHY changes
+- * @work: work_struct that describes the work to be done
+- */
+-void phy_change_work(struct work_struct *work)
+-{
+-      struct phy_device *phydev =
+-              container_of(work, struct phy_device, phy_queue);
+-
+-      phy_change(phydev);
+-}
+-
+ /**
+  * phy_stop - Bring down the PHY link, and stop checking the status
+  * @phydev: target phy_device struct
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index d312b314825e..a1e7ea4d4b16 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -999,10 +999,17 @@ int phy_attach_direct(struct net_device *dev, struct 
phy_device *phydev,
+       err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj,
+                               "attached_dev");
+       if (!err) {
+-              err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj,
+-                                      "phydev");
+-              if (err)
+-                      goto error;
++              err = sysfs_create_link_nowarn(&dev->dev.kobj,
++                                             &phydev->mdio.dev.kobj,
++                                             "phydev");
++              if (err) {
++                      dev_err(&dev->dev, "could not add device link to %s err 
%d\n",
++                              kobject_name(&phydev->mdio.dev.kobj),
++                              err);
++                      /* non-fatal - some net drivers can use one netdevice
++                       * with more then one phy
++                       */
++              }
+ 
+               phydev->sysfs_links = true;
+       }
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index 9f79f9274c50..d37183aec313 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -257,7 +257,7 @@ struct ppp_net {
+ /* Prototypes. */
+ static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
+                       struct file *file, unsigned int cmd, unsigned long arg);
+-static void ppp_xmit_process(struct ppp *ppp);
++static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb);
+ static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
+ static void ppp_push(struct ppp *ppp);
+ static void ppp_channel_push(struct channel *pch);
+@@ -513,13 +513,12 @@ static ssize_t ppp_write(struct file *file, const char 
__user *buf,
+               goto out;
+       }
+ 
+-      skb_queue_tail(&pf->xq, skb);
+-
+       switch (pf->kind) {
+       case INTERFACE:
+-              ppp_xmit_process(PF_TO_PPP(pf));
++              ppp_xmit_process(PF_TO_PPP(pf), skb);
+               break;
+       case CHANNEL:
++              skb_queue_tail(&pf->xq, skb);
+               ppp_channel_push(PF_TO_CHANNEL(pf));
+               break;
+       }
+@@ -1267,8 +1266,8 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device 
*dev)
+       put_unaligned_be16(proto, pp);
+ 
+       skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(dev)));
+-      skb_queue_tail(&ppp->file.xq, skb);
+-      ppp_xmit_process(ppp);
++      ppp_xmit_process(ppp, skb);
++
+       return NETDEV_TX_OK;
+ 
+  outf:
+@@ -1420,13 +1419,14 @@ static void ppp_setup(struct net_device *dev)
+  */
+ 
+ /* Called to do any work queued up on the transmit side that can now be done 
*/
+-static void __ppp_xmit_process(struct ppp *ppp)
++static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
+ {
+-      struct sk_buff *skb;
+-
+       ppp_xmit_lock(ppp);
+       if (!ppp->closing) {
+               ppp_push(ppp);
++
++              if (skb)
++                      skb_queue_tail(&ppp->file.xq, skb);
+               while (!ppp->xmit_pending &&
+                      (skb = skb_dequeue(&ppp->file.xq)))
+                       ppp_send_frame(ppp, skb);
+@@ -1440,7 +1440,7 @@ static void __ppp_xmit_process(struct ppp *ppp)
+       ppp_xmit_unlock(ppp);
+ }
+ 
+-static void ppp_xmit_process(struct ppp *ppp)
++static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
+ {
+       local_bh_disable();
+ 
+@@ -1448,7 +1448,7 @@ static void ppp_xmit_process(struct ppp *ppp)
+               goto err;
+ 
+       (*this_cpu_ptr(ppp->xmit_recursion))++;
+-      __ppp_xmit_process(ppp);
++      __ppp_xmit_process(ppp, skb);
+       (*this_cpu_ptr(ppp->xmit_recursion))--;
+ 
+       local_bh_enable();
+@@ -1458,6 +1458,8 @@ static void ppp_xmit_process(struct ppp *ppp)
+ err:
+       local_bh_enable();
+ 
++      kfree_skb(skb);
++
+       if (net_ratelimit())
+               netdev_err(ppp->dev, "recursion detected\n");
+ }
+@@ -1942,7 +1944,7 @@ static void __ppp_channel_push(struct channel *pch)
+       if (skb_queue_empty(&pch->file.xq)) {
+               ppp = pch->ppp;
+               if (ppp)
+-                      __ppp_xmit_process(ppp);
++                      __ppp_xmit_process(ppp, NULL);
+       }
+ }
+ 
+diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
+index a468439969df..56c701b73c12 100644
+--- a/drivers/net/team/team.c
++++ b/drivers/net/team/team.c
+@@ -2395,7 +2395,7 @@ static int team_nl_send_options_get(struct team *team, 
u32 portid, u32 seq,
+       if (!nlh) {
+               err = __send_and_alloc_skb(&skb, team, portid, send_func);
+               if (err)
+-                      goto errout;
++                      return err;
+               goto send_done;
+       }
+ 
+@@ -2681,7 +2681,7 @@ static int team_nl_send_port_list_get(struct team *team, 
u32 portid, u32 seq,
+       if (!nlh) {
+               err = __send_and_alloc_skb(&skb, team, portid, send_func);
+               if (err)
+-                      goto errout;
++                      return err;
+               goto send_done;
+       }
+ 
+diff --git a/drivers/s390/net/qeth_core_main.c 
b/drivers/s390/net/qeth_core_main.c
+index 61e9d0bca197..eeabbcf7a4e2 100644
+--- a/drivers/s390/net/qeth_core_main.c
++++ b/drivers/s390/net/qeth_core_main.c
+@@ -526,8 +526,7 @@ static inline int qeth_is_cq(struct qeth_card *card, 
unsigned int queue)
+           queue == card->qdio.no_in_queues - 1;
+ }
+ 
+-
+-static int qeth_issue_next_read(struct qeth_card *card)
++static int __qeth_issue_next_read(struct qeth_card *card)
+ {
+       int rc;
+       struct qeth_cmd_buffer *iob;
+@@ -558,6 +557,17 @@ static int qeth_issue_next_read(struct qeth_card *card)
+       return rc;
+ }
+ 
++static int qeth_issue_next_read(struct qeth_card *card)
++{
++      int ret;
++
++      spin_lock_irq(get_ccwdev_lock(CARD_RDEV(card)));
++      ret = __qeth_issue_next_read(card);
++      spin_unlock_irq(get_ccwdev_lock(CARD_RDEV(card)));
++
++      return ret;
++}
++
+ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
+ {
+       struct qeth_reply *reply;
+@@ -961,7 +971,7 @@ void qeth_clear_thread_running_bit(struct qeth_card *card, 
unsigned long thread)
+       spin_lock_irqsave(&card->thread_mask_lock, flags);
+       card->thread_running_mask &= ~thread;
+       spin_unlock_irqrestore(&card->thread_mask_lock, flags);
+-      wake_up(&card->wait_q);
++      wake_up_all(&card->wait_q);
+ }
+ EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit);
+ 
+@@ -1165,6 +1175,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned 
long intparm,
+               }
+               rc = qeth_get_problem(cdev, irb);
+               if (rc) {
++                      card->read_or_write_problem = 1;
+                       qeth_clear_ipacmd_list(card);
+                       qeth_schedule_recovery(card);
+                       goto out;
+@@ -1183,7 +1194,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned 
long intparm,
+               return;
+       if (channel == &card->read &&
+           channel->state == CH_STATE_UP)
+-              qeth_issue_next_read(card);
++              __qeth_issue_next_read(card);
+ 
+       iob = channel->iob;
+       index = channel->buf_no;
+@@ -5022,8 +5033,6 @@ static void qeth_core_free_card(struct qeth_card *card)
+       QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
+       qeth_clean_channel(&card->read);
+       qeth_clean_channel(&card->write);
+-      if (card->dev)
+-              free_netdev(card->dev);
+       qeth_free_qdio_buffers(card);
+       unregister_service_level(&card->qeth_service_level);
+       kfree(card);
+diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
+index 5863ea170ff2..42d56b3bed82 100644
+--- a/drivers/s390/net/qeth_l2_main.c
++++ b/drivers/s390/net/qeth_l2_main.c
+@@ -933,8 +933,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device 
*cgdev)
+               qeth_l2_set_offline(cgdev);
+ 
+       if (card->dev) {
+-              netif_napi_del(&card->napi);
+               unregister_netdev(card->dev);
++              free_netdev(card->dev);
+               card->dev = NULL;
+       }
+       return;
+diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
+index 33131c594627..5287eab5c600 100644
+--- a/drivers/s390/net/qeth_l3_main.c
++++ b/drivers/s390/net/qeth_l3_main.c
+@@ -3042,8 +3042,8 @@ static void qeth_l3_remove_device(struct ccwgroup_device 
*cgdev)
+               qeth_l3_set_offline(cgdev);
+ 
+       if (card->dev) {
+-              netif_napi_del(&card->napi);
+               unregister_netdev(card->dev);
++              free_netdev(card->dev);
+               card->dev = NULL;
+       }
+ 
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index e4f5bb056fd2..ba3cfa8e279b 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -2443,39 +2443,21 @@ struct cgr_comp {
+       struct completion completion;
+ };
+ 
+-static int qman_delete_cgr_thread(void *p)
++static void qman_delete_cgr_smp_call(void *p)
+ {
+-      struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
+-      int ret;
+-
+-      ret = qman_delete_cgr(cgr_comp->cgr);
+-      complete(&cgr_comp->completion);
+-
+-      return ret;
++      qman_delete_cgr((struct qman_cgr *)p);
+ }
+ 
+ void qman_delete_cgr_safe(struct qman_cgr *cgr)
+ {
+-      struct task_struct *thread;
+-      struct cgr_comp cgr_comp;
+-
+       preempt_disable();
+       if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
+-              init_completion(&cgr_comp.completion);
+-              cgr_comp.cgr = cgr;
+-              thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
+-                                      "cgr_del");
+-
+-              if (IS_ERR(thread))
+-                      goto out;
+-
+-              kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
+-              wake_up_process(thread);
+-              wait_for_completion(&cgr_comp.completion);
++              smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
++                                       qman_delete_cgr_smp_call, cgr, true);
+               preempt_enable();
+               return;
+       }
+-out:
++
+       qman_delete_cgr(cgr);
+       preempt_enable();
+ }
+diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
+index aecb15f84557..808f018fa976 100644
+--- a/fs/sysfs/symlink.c
++++ b/fs/sysfs/symlink.c
+@@ -107,6 +107,7 @@ int sysfs_create_link_nowarn(struct kobject *kobj, struct 
kobject *target,
+ {
+       return sysfs_do_create_link(kobj, target, name, 0);
+ }
++EXPORT_SYMBOL_GPL(sysfs_create_link_nowarn);
+ 
+ /**
+  *    sysfs_delete_link - remove symlink in object's directory.
+diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
+index 8b7fd8eeccee..cb8a9ce149de 100644
+--- a/include/linux/cgroup-defs.h
++++ b/include/linux/cgroup-defs.h
+@@ -755,13 +755,13 @@ struct sock_cgroup_data {
+  * updaters and return part of the previous pointer as the prioidx or
+  * classid.  Such races are short-lived and the result isn't critical.
+  */
+-static inline u16 sock_cgroup_prioidx(struct sock_cgroup_data *skcd)
++static inline u16 sock_cgroup_prioidx(const struct sock_cgroup_data *skcd)
+ {
+       /* fallback to 1 which is always the ID of the root cgroup */
+       return (skcd->is_data & 1) ? skcd->prioidx : 1;
+ }
+ 
+-static inline u32 sock_cgroup_classid(struct sock_cgroup_data *skcd)
++static inline u32 sock_cgroup_classid(const struct sock_cgroup_data *skcd)
+ {
+       /* fallback to 0 which is the unconfigured default classid */
+       return (skcd->is_data & 1) ? skcd->classid : 0;
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index 123cd703741d..ea0cbd6d9556 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -897,7 +897,6 @@ int phy_driver_register(struct phy_driver *new_driver, 
struct module *owner);
+ int phy_drivers_register(struct phy_driver *new_driver, int n,
+                        struct module *owner);
+ void phy_state_machine(struct work_struct *work);
+-void phy_change(struct phy_device *phydev);
+ void phy_change_work(struct work_struct *work);
+ void phy_mac_interrupt(struct phy_device *phydev, int new_link);
+ void phy_start_machine(struct phy_device *phydev);
+diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
+index 361c08e35dbc..7fd514f36e74 100644
+--- a/include/linux/rhashtable.h
++++ b/include/linux/rhashtable.h
+@@ -750,8 +750,10 @@ static inline void *__rhashtable_insert_fast(
+               if (!key ||
+                   (params.obj_cmpfn ?
+                    params.obj_cmpfn(&arg, rht_obj(ht, head)) :
+-                   rhashtable_compare(&arg, rht_obj(ht, head))))
++                   rhashtable_compare(&arg, rht_obj(ht, head)))) {
++                      pprev = &head->next;
+                       continue;
++              }
+ 
+               data = rht_obj(ht, head);
+ 
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
+index d6ec5a5a6782..d794aebb3157 100644
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -735,6 +735,16 @@ static inline void __qdisc_drop(struct sk_buff *skb, 
struct sk_buff **to_free)
+       *to_free = skb;
+ }
+ 
++static inline void __qdisc_drop_all(struct sk_buff *skb,
++                                  struct sk_buff **to_free)
++{
++      if (skb->prev)
++              skb->prev->next = *to_free;
++      else
++              skb->next = *to_free;
++      *to_free = skb;
++}
++
+ static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch,
+                                                  struct qdisc_skb_head *qh,
+                                                  struct sk_buff **to_free)
+@@ -855,6 +865,15 @@ static inline int qdisc_drop(struct sk_buff *skb, struct 
Qdisc *sch,
+       return NET_XMIT_DROP;
+ }
+ 
++static inline int qdisc_drop_all(struct sk_buff *skb, struct Qdisc *sch,
++                               struct sk_buff **to_free)
++{
++      __qdisc_drop_all(skb, to_free);
++      qdisc_qstats_drop(sch);
++
++      return NET_XMIT_DROP;
++}
++
+ /* Length to Time (L2T) lookup in a qdisc_rate_table, to determine how
+    long it will take to send a packet given its size.
+  */
+diff --git a/lib/rhashtable.c b/lib/rhashtable.c
+index ddd7dde87c3c..b734ce731a7a 100644
+--- a/lib/rhashtable.c
++++ b/lib/rhashtable.c
+@@ -537,8 +537,10 @@ static void *rhashtable_lookup_one(struct rhashtable *ht,
+               if (!key ||
+                   (ht->p.obj_cmpfn ?
+                    ht->p.obj_cmpfn(&arg, rht_obj(ht, head)) :
+-                   rhashtable_compare(&arg, rht_obj(ht, head))))
++                   rhashtable_compare(&arg, rht_obj(ht, head)))) {
++                      pprev = &head->next;
+                       continue;
++              }
+ 
+               if (!ht->rhlist)
+                       return rht_obj(ht, head);
+diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
+index 8e83cbdc049c..6f2e3dc44a80 100644
+--- a/lib/test_rhashtable.c
++++ b/lib/test_rhashtable.c
+@@ -79,6 +79,21 @@ struct thread_data {
+       struct test_obj *objs;
+ };
+ 
++static u32 my_hashfn(const void *data, u32 len, u32 seed)
++{
++      const struct test_obj_rhl *obj = data;
++
++      return (obj->value.id % 10) << RHT_HASH_RESERVED_SPACE;
++}
++
++static int my_cmpfn(struct rhashtable_compare_arg *arg, const void *obj)
++{
++      const struct test_obj_rhl *test_obj = obj;
++      const struct test_obj_val *val = arg->key;
++
++      return test_obj->value.id - val->id;
++}
++
+ static struct rhashtable_params test_rht_params = {
+       .head_offset = offsetof(struct test_obj, node),
+       .key_offset = offsetof(struct test_obj, value),
+@@ -87,6 +102,17 @@ static struct rhashtable_params test_rht_params = {
+       .nulls_base = (3U << RHT_BASE_SHIFT),
+ };
+ 
++static struct rhashtable_params test_rht_params_dup = {
++      .head_offset = offsetof(struct test_obj_rhl, list_node),
++      .key_offset = offsetof(struct test_obj_rhl, value),
++      .key_len = sizeof(struct test_obj_val),
++      .hashfn = jhash,
++      .obj_hashfn = my_hashfn,
++      .obj_cmpfn = my_cmpfn,
++      .nelem_hint = 128,
++      .automatic_shrinking = false,
++};
++
+ static struct semaphore prestart_sem;
+ static struct semaphore startup_sem = __SEMAPHORE_INITIALIZER(startup_sem, 0);
+ 
+@@ -469,6 +495,112 @@ static int __init test_rhashtable_max(struct test_obj 
*array,
+       return err;
+ }
+ 
++static unsigned int __init print_ht(struct rhltable *rhlt)
++{
++      struct rhashtable *ht;
++      const struct bucket_table *tbl;
++      char buff[512] = "";
++      unsigned int i, cnt = 0;
++
++      ht = &rhlt->ht;
++      tbl = rht_dereference(ht->tbl, ht);
++      for (i = 0; i < tbl->size; i++) {
++              struct rhash_head *pos, *next;
++              struct test_obj_rhl *p;
++
++              pos = rht_dereference(tbl->buckets[i], ht);
++              next = !rht_is_a_nulls(pos) ? rht_dereference(pos->next, ht) : 
NULL;
++
++              if (!rht_is_a_nulls(pos)) {
++                      sprintf(buff, "%s\nbucket[%d] -> ", buff, i);
++              }
++
++              while (!rht_is_a_nulls(pos)) {
++                      struct rhlist_head *list = container_of(pos, struct 
rhlist_head, rhead);
++                      sprintf(buff, "%s[[", buff);
++                      do {
++                              pos = &list->rhead;
++                              list = rht_dereference(list->next, ht);
++                              p = rht_obj(ht, pos);
++
++                              sprintf(buff, "%s val %d (tid=%d)%s", buff, 
p->value.id, p->value.tid,
++                                      list? ", " : " ");
++                              cnt++;
++                      } while (list);
++
++                      pos = next,
++                      next = !rht_is_a_nulls(pos) ?
++                              rht_dereference(pos->next, ht) : NULL;
++
++                      sprintf(buff, "%s]]%s", buff, !rht_is_a_nulls(pos) ? " 
-> " : "");
++              }
++      }
++      printk(KERN_ERR "\n---- ht: ----%s\n-------------\n", buff);
++
++      return cnt;
++}
++
++static int __init test_insert_dup(struct test_obj_rhl *rhl_test_objects,
++                                int cnt, bool slow)
++{
++      struct rhltable rhlt;
++      unsigned int i, ret;
++      const char *key;
++      int err = 0;
++
++      err = rhltable_init(&rhlt, &test_rht_params_dup);
++      if (WARN_ON(err))
++              return err;
++
++      for (i = 0; i < cnt; i++) {
++              rhl_test_objects[i].value.tid = i;
++              key = rht_obj(&rhlt.ht, &rhl_test_objects[i].list_node.rhead);
++              key += test_rht_params_dup.key_offset;
++
++              if (slow) {
++                      err = PTR_ERR(rhashtable_insert_slow(&rhlt.ht, key,
++                                                           
&rhl_test_objects[i].list_node.rhead));
++                      if (err == -EAGAIN)
++                              err = 0;
++              } else
++                      err = rhltable_insert(&rhlt,
++                                            &rhl_test_objects[i].list_node,
++                                            test_rht_params_dup);
++              if (WARN(err, "error %d on element %d/%d (%s)\n", err, i, cnt, 
slow? "slow" : "fast"))
++                      goto skip_print;
++      }
++
++      ret = print_ht(&rhlt);
++      WARN(ret != cnt, "missing rhltable elements (%d != %d, %s)\n", ret, 
cnt, slow? "slow" : "fast");
++
++skip_print:
++      rhltable_destroy(&rhlt);
++
++      return 0;
++}
++
++static int __init test_insert_duplicates_run(void)
++{
++      struct test_obj_rhl rhl_test_objects[3] = {};
++
++      pr_info("test inserting duplicates\n");
++
++      /* two different values that map to same bucket */
++      rhl_test_objects[0].value.id = 1;
++      rhl_test_objects[1].value.id = 21;
++
++      /* and another duplicate with same as [0] value
++       * which will be second on the bucket list */
++      rhl_test_objects[2].value.id = rhl_test_objects[0].value.id;
++
++      test_insert_dup(rhl_test_objects, 2, false);
++      test_insert_dup(rhl_test_objects, 3, false);
++      test_insert_dup(rhl_test_objects, 2, true);
++      test_insert_dup(rhl_test_objects, 3, true);
++
++      return 0;
++}
++
+ static int thread_lookup_test(struct thread_data *tdata)
+ {
+       unsigned int entries = tdata->entries;
+@@ -617,6 +749,8 @@ static int __init test_rht_init(void)
+       do_div(total_time, runs);
+       pr_info("Average test time: %llu\n", total_time);
+ 
++      test_insert_duplicates_run();
++
+       if (!tcount)
+               return 0;
+ 
+diff --git a/net/core/dev.c b/net/core/dev.c
+index a2a89acd0de8..f3fbd10a0632 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3247,15 +3247,23 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, 
struct Qdisc *q,
+ #if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
+ static void skb_update_prio(struct sk_buff *skb)
+ {
+-      struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap);
++      const struct netprio_map *map;
++      const struct sock *sk;
++      unsigned int prioidx;
+ 
+-      if (!skb->priority && skb->sk && map) {
+-              unsigned int prioidx =
+-                      sock_cgroup_prioidx(&skb->sk->sk_cgrp_data);
++      if (skb->priority)
++              return;
++      map = rcu_dereference_bh(skb->dev->priomap);
++      if (!map)
++              return;
++      sk = skb_to_full_sk(skb);
++      if (!sk)
++              return;
+ 
+-              if (prioidx < map->priomap_len)
+-                      skb->priority = map->priomap[prioidx];
+-      }
++      prioidx = sock_cgroup_prioidx(&sk->sk_cgrp_data);
++
++      if (prioidx < map->priomap_len)
++              skb->priority = map->priomap[prioidx];
+ }
+ #else
+ #define skb_update_prio(skb)
+diff --git a/net/core/devlink.c b/net/core/devlink.c
+index 7d430c1d9c3e..5ba973311025 100644
+--- a/net/core/devlink.c
++++ b/net/core/devlink.c
+@@ -1776,7 +1776,7 @@ static int devlink_dpipe_tables_fill(struct genl_info 
*info,
+       if (!nlh) {
+               err = devlink_dpipe_send_and_alloc_skb(&skb, info);
+               if (err)
+-                      goto err_skb_send_alloc;
++                      return err;
+               goto send_done;
+       }
+ 
+@@ -1785,7 +1785,6 @@ static int devlink_dpipe_tables_fill(struct genl_info 
*info,
+ nla_put_failure:
+       err = -EMSGSIZE;
+ err_table_put:
+-err_skb_send_alloc:
+       genlmsg_cancel(skb, hdr);
+       nlmsg_free(skb);
+       return err;
+@@ -2051,7 +2050,7 @@ static int devlink_dpipe_entries_fill(struct genl_info 
*info,
+                                            table->counters_enabled,
+                                            &dump_ctx);
+       if (err)
+-              goto err_entries_dump;
++              return err;
+ 
+ send_done:
+       nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
+@@ -2059,16 +2058,10 @@ static int devlink_dpipe_entries_fill(struct genl_info 
*info,
+       if (!nlh) {
+               err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
+               if (err)
+-                      goto err_skb_send_alloc;
++                      return err;
+               goto send_done;
+       }
+       return genlmsg_reply(dump_ctx.skb, info);
+-
+-err_entries_dump:
+-err_skb_send_alloc:
+-      genlmsg_cancel(dump_ctx.skb, dump_ctx.hdr);
+-      nlmsg_free(dump_ctx.skb);
+-      return err;
+ }
+ 
+ static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
+@@ -2207,7 +2200,7 @@ static int devlink_dpipe_headers_fill(struct genl_info 
*info,
+       if (!nlh) {
+               err = devlink_dpipe_send_and_alloc_skb(&skb, info);
+               if (err)
+-                      goto err_skb_send_alloc;
++                      return err;
+               goto send_done;
+       }
+       return genlmsg_reply(skb, info);
+@@ -2215,7 +2208,6 @@ static int devlink_dpipe_headers_fill(struct genl_info 
*info,
+ nla_put_failure:
+       err = -EMSGSIZE;
+ err_table_put:
+-err_skb_send_alloc:
+       genlmsg_cancel(skb, hdr);
+       nlmsg_free(skb);
+       return err;
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 08f574081315..3538ba8771e9 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -4173,7 +4173,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff 
*skb)
+ 
+       skb_queue_tail(&sk->sk_error_queue, skb);
+       if (!sock_flag(sk, SOCK_DEAD))
+-              sk->sk_data_ready(sk);
++              sk->sk_error_report(sk);
+       return 0;
+ }
+ EXPORT_SYMBOL(sock_queue_err_skb);
+diff --git a/net/dccp/proto.c b/net/dccp/proto.c
+index 9d43c1f40274..ff3b058cf58c 100644
+--- a/net/dccp/proto.c
++++ b/net/dccp/proto.c
+@@ -789,6 +789,11 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, 
size_t len)
+       if (skb == NULL)
+               goto out_release;
+ 
++      if (sk->sk_state == DCCP_CLOSED) {
++              rc = -ENOTCONN;
++              goto out_discard;
++      }
++
+       skb_reserve(skb, sk->sk_prot->max_header);
+       rc = memcpy_from_msg(skb_put(skb, len), msg, len);
+       if (rc != 0)
+diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c
+index 84611d7fcfa2..3c9cee268b8a 100644
+--- a/net/dsa/legacy.c
++++ b/net/dsa/legacy.c
+@@ -194,7 +194,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds,
+               ds->ports[i].dn = cd->port_dn[i];
+               ds->ports[i].cpu_dp = dst->cpu_dp;
+ 
+-              if (dsa_is_user_port(ds, i))
++              if (!dsa_is_user_port(ds, i))
+                       continue;
+ 
+               ret = dsa_slave_create(&ds->ports[i]);
+diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
+index 974765b7d92a..e9f0489e4229 100644
+--- a/net/ieee802154/6lowpan/core.c
++++ b/net/ieee802154/6lowpan/core.c
+@@ -206,9 +206,13 @@ static inline void lowpan_netlink_fini(void)
+ static int lowpan_device_event(struct notifier_block *unused,
+                              unsigned long event, void *ptr)
+ {
+-      struct net_device *wdev = netdev_notifier_info_to_dev(ptr);
++      struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
++      struct wpan_dev *wpan_dev;
+ 
+-      if (wdev->type != ARPHRD_IEEE802154)
++      if (ndev->type != ARPHRD_IEEE802154)
++              return NOTIFY_DONE;
++      wpan_dev = ndev->ieee802154_ptr;
++      if (!wpan_dev)
+               return NOTIFY_DONE;
+ 
+       switch (event) {
+@@ -217,8 +221,8 @@ static int lowpan_device_event(struct notifier_block 
*unused,
+                * also delete possible lowpan interfaces which belongs
+                * to the wpan interface.
+                */
+-              if (wdev->ieee802154_ptr->lowpan_dev)
+-                      lowpan_dellink(wdev->ieee802154_ptr->lowpan_dev, NULL);
++              if (wpan_dev->lowpan_dev)
++                      lowpan_dellink(wpan_dev->lowpan_dev, NULL);
+               break;
+       default:
+               return NOTIFY_DONE;
+diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
+index 26a3d0315728..e8ec28999f5c 100644
+--- a/net/ipv4/inet_fragment.c
++++ b/net/ipv4/inet_fragment.c
+@@ -119,6 +119,9 @@ static void inet_frag_secret_rebuild(struct inet_frags *f)
+ 
+ static bool inet_fragq_should_evict(const struct inet_frag_queue *q)
+ {
++      if (!hlist_unhashed(&q->list_evictor))
++              return false;
++
+       return q->net->low_thresh == 0 ||
+              frag_mem_limit(q->net) >= q->net->low_thresh;
+ }
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
+index f56aab54e0c8..1e70ed5244ea 100644
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -258,7 +258,8 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, 
struct ipcm_cookie *ipc,
+                       src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
+                       if (!ipv6_addr_v4mapped(&src_info->ipi6_addr))
+                               return -EINVAL;
+-                      ipc->oif = src_info->ipi6_ifindex;
++                      if (src_info->ipi6_ifindex)
++                              ipc->oif = src_info->ipi6_ifindex;
+                       ipc->addr = src_info->ipi6_addr.s6_addr32[3];
+                       continue;
+               }
+@@ -288,7 +289,8 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, 
struct ipcm_cookie *ipc,
+                       if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct 
in_pktinfo)))
+                               return -EINVAL;
+                       info = (struct in_pktinfo *)CMSG_DATA(cmsg);
+-                      ipc->oif = info->ipi_ifindex;
++                      if (info->ipi_ifindex)
++                              ipc->oif = info->ipi_ifindex;
+                       ipc->addr = info->ipi_spec_dst.s_addr;
+                       break;
+               }
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index c821f5d68720..2eb91b97a062 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3542,6 +3542,7 @@ int tcp_abort(struct sock *sk, int err)
+ 
+       bh_unlock_sock(sk);
+       local_bh_enable();
++      tcp_write_queue_purge(sk);
+       release_sock(sk);
+       return 0;
+ }
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index 388158c9d9f6..c721140a7d79 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -34,6 +34,7 @@ static void tcp_write_err(struct sock *sk)
+       sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT;
+       sk->sk_error_report(sk);
+ 
++      tcp_write_queue_purge(sk);
+       tcp_done(sk);
+       __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONTIMEOUT);
+ }
+diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
+index a1f918713006..287112da3c06 100644
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -146,10 +146,12 @@ int __ip6_datagram_connect(struct sock *sk, struct 
sockaddr *uaddr,
+       struct sockaddr_in6     *usin = (struct sockaddr_in6 *) uaddr;
+       struct inet_sock        *inet = inet_sk(sk);
+       struct ipv6_pinfo       *np = inet6_sk(sk);
+-      struct in6_addr         *daddr;
++      struct in6_addr         *daddr, old_daddr;
++      __be32                  fl6_flowlabel = 0;
++      __be32                  old_fl6_flowlabel;
++      __be16                  old_dport;
+       int                     addr_type;
+       int                     err;
+-      __be32                  fl6_flowlabel = 0;
+ 
+       if (usin->sin6_family == AF_INET) {
+               if (__ipv6_only_sock(sk))
+@@ -239,9 +241,13 @@ int __ip6_datagram_connect(struct sock *sk, struct 
sockaddr *uaddr,
+               }
+       }
+ 
++      /* save the current peer information before updating it */
++      old_daddr = sk->sk_v6_daddr;
++      old_fl6_flowlabel = np->flow_label;
++      old_dport = inet->inet_dport;
++
+       sk->sk_v6_daddr = *daddr;
+       np->flow_label = fl6_flowlabel;
+-
+       inet->inet_dport = usin->sin6_port;
+ 
+       /*
+@@ -251,11 +257,12 @@ int __ip6_datagram_connect(struct sock *sk, struct 
sockaddr *uaddr,
+ 
+       err = ip6_datagram_dst_update(sk, true);
+       if (err) {
+-              /* Reset daddr and dport so that udp_v6_early_demux()
+-               * fails to find this socket
++              /* Restore the socket peer info, to keep it consistent with
++               * the old socket state
+                */
+-              memset(&sk->sk_v6_daddr, 0, sizeof(sk->sk_v6_daddr));
+-              inet->inet_dport = 0;
++              sk->sk_v6_daddr = old_daddr;
++              np->flow_label = old_fl6_flowlabel;
++              inet->inet_dport = old_dport;
+               goto out;
+       }
+ 
+diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
+index f61a5b613b52..ba5e04c6ae17 100644
+--- a/net/ipv6/ndisc.c
++++ b/net/ipv6/ndisc.c
+@@ -1554,7 +1554,8 @@ static void ndisc_fill_redirect_hdr_option(struct 
sk_buff *skb,
+       *(opt++) = (rd_len >> 3);
+       opt += 6;
+ 
+-      memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8);
++      skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt,
++                    rd_len - 8);
+ }
+ 
+ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index a560fb1d0230..08a2a65d3304 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -1510,7 +1510,30 @@ static void rt6_exceptions_remove_prefsrc(struct 
rt6_info *rt)
+       }
+ }
+ 
+-static void rt6_exceptions_update_pmtu(struct rt6_info *rt, int mtu)
++static bool rt6_mtu_change_route_allowed(struct inet6_dev *idev,
++                                       struct rt6_info *rt, int mtu)
++{
++      /* If the new MTU is lower than the route PMTU, this new MTU will be the
++       * lowest MTU in the path: always allow updating the route PMTU to
++       * reflect PMTU decreases.
++       *
++       * If the new MTU is higher, and the route PMTU is equal to the local
++       * MTU, this means the old MTU is the lowest in the path, so allow
++       * updating it: if other nodes now have lower MTUs, PMTU discovery will
++       * handle this.
++       */
++
++      if (dst_mtu(&rt->dst) >= mtu)
++              return true;
++
++      if (dst_mtu(&rt->dst) == idev->cnf.mtu6)
++              return true;
++
++      return false;
++}
++
++static void rt6_exceptions_update_pmtu(struct inet6_dev *idev,
++                                     struct rt6_info *rt, int mtu)
+ {
+       struct rt6_exception_bucket *bucket;
+       struct rt6_exception *rt6_ex;
+@@ -1519,20 +1542,22 @@ static void rt6_exceptions_update_pmtu(struct rt6_info 
*rt, int mtu)
+       bucket = rcu_dereference_protected(rt->rt6i_exception_bucket,
+                                       lockdep_is_held(&rt6_exception_lock));
+ 
+-      if (bucket) {
+-              for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) {
+-                      hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) {
+-                              struct rt6_info *entry = rt6_ex->rt6i;
+-                              /* For RTF_CACHE with rt6i_pmtu == 0
+-                               * (i.e. a redirected route),
+-                               * the metrics of its rt->dst.from has already
+-                               * been updated.
+-                               */
+-                              if (entry->rt6i_pmtu && entry->rt6i_pmtu > mtu)
+-                                      entry->rt6i_pmtu = mtu;
+-                      }
+-                      bucket++;
++      if (!bucket)
++              return;
++
++      for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) {
++              hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) {
++                      struct rt6_info *entry = rt6_ex->rt6i;
++
++                      /* For RTF_CACHE with rt6i_pmtu == 0 (i.e. a redirected
++                       * route), the metrics of its rt->dst.from have already
++                       * been updated.
++                       */
++                      if (entry->rt6i_pmtu &&
++                          rt6_mtu_change_route_allowed(idev, entry, mtu))
++                              entry->rt6i_pmtu = mtu;
+               }
++              bucket++;
+       }
+ }
+ 
+@@ -3521,25 +3546,13 @@ static int rt6_mtu_change_route(struct rt6_info *rt, 
void *p_arg)
+          Since RFC 1981 doesn't include administrative MTU increase
+          update PMTU increase is a MUST. (i.e. jumbo frame)
+        */
+-      /*
+-         If new MTU is less than route PMTU, this new MTU will be the
+-         lowest MTU in the path, update the route PMTU to reflect PMTU
+-         decreases; if new MTU is greater than route PMTU, and the
+-         old MTU is the lowest MTU in the path, update the route PMTU
+-         to reflect the increase. In this case if the other nodes' MTU
+-         also have the lowest MTU, TOO BIG MESSAGE will be lead to
+-         PMTU discovery.
+-       */
+       if (rt->dst.dev == arg->dev &&
+-          dst_metric_raw(&rt->dst, RTAX_MTU) &&
+           !dst_metric_locked(&rt->dst, RTAX_MTU)) {
+               spin_lock_bh(&rt6_exception_lock);
+-              if (dst_mtu(&rt->dst) >= arg->mtu ||
+-                  (dst_mtu(&rt->dst) < arg->mtu &&
+-                   dst_mtu(&rt->dst) == idev->cnf.mtu6)) {
++              if (dst_metric_raw(&rt->dst, RTAX_MTU) &&
++                  rt6_mtu_change_route_allowed(idev, rt, arg->mtu))
+                       dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu);
+-              }
+-              rt6_exceptions_update_pmtu(rt, arg->mtu);
++              rt6_exceptions_update_pmtu(idev, rt, arg->mtu);
+               spin_unlock_bh(&rt6_exception_lock);
+       }
+       return 0;
+diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
+index bd6cc688bd19..7a78dcfda68a 100644
+--- a/net/ipv6/seg6_iptunnel.c
++++ b/net/ipv6/seg6_iptunnel.c
+@@ -93,7 +93,8 @@ static void set_tun_src(struct net *net, struct net_device 
*dev,
+ /* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */
+ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int 
proto)
+ {
+-      struct net *net = dev_net(skb_dst(skb)->dev);
++      struct dst_entry *dst = skb_dst(skb);
++      struct net *net = dev_net(dst->dev);
+       struct ipv6hdr *hdr, *inner_hdr;
+       struct ipv6_sr_hdr *isrh;
+       int hdrlen, tot_len, err;
+@@ -134,7 +135,7 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct 
ipv6_sr_hdr *osrh, int proto)
+       isrh->nexthdr = proto;
+ 
+       hdr->daddr = isrh->segments[isrh->first_segment];
+-      set_tun_src(net, skb->dev, &hdr->daddr, &hdr->saddr);
++      set_tun_src(net, ip6_dst_idev(dst)->dev, &hdr->daddr, &hdr->saddr);
+ 
+ #ifdef CONFIG_IPV6_SEG6_HMAC
+       if (sr_has_hmac(isrh)) {
+@@ -418,7 +419,7 @@ static int seg6_build_state(struct nlattr *nla,
+ 
+       slwt = seg6_lwt_lwtunnel(newts);
+ 
+-      err = dst_cache_init(&slwt->cache, GFP_KERNEL);
++      err = dst_cache_init(&slwt->cache, GFP_ATOMIC);
+       if (err) {
+               kfree(newts);
+               return err;
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 148533169b1d..ca98276c2709 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -2433,9 +2433,11 @@ static int afiucv_iucv_init(void)
+       af_iucv_dev->driver = &af_iucv_driver;
+       err = device_register(af_iucv_dev);
+       if (err)
+-              goto out_driver;
++              goto out_iucv_dev;
+       return 0;
+ 
++out_iucv_dev:
++      put_device(af_iucv_dev);
+ out_driver:
+       driver_unregister(&af_iucv_driver);
+ out_iucv:
+diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
+index 4a8d407f8902..3f15ffd356da 100644
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -1381,24 +1381,32 @@ static int kcm_attach(struct socket *sock, struct 
socket *csock,
+               .parse_msg = kcm_parse_func_strparser,
+               .read_sock_done = kcm_read_sock_done,
+       };
+-      int err;
++      int err = 0;
+ 
+       csk = csock->sk;
+       if (!csk)
+               return -EINVAL;
+ 
++      lock_sock(csk);
++
+       /* Only allow TCP sockets to be attached for now */
+       if ((csk->sk_family != AF_INET && csk->sk_family != AF_INET6) ||
+-          csk->sk_protocol != IPPROTO_TCP)
+-              return -EOPNOTSUPP;
++          csk->sk_protocol != IPPROTO_TCP) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
+ 
+       /* Don't allow listeners or closed sockets */
+-      if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE)
+-              return -EOPNOTSUPP;
++      if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
+ 
+       psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL);
+-      if (!psock)
+-              return -ENOMEM;
++      if (!psock) {
++              err = -ENOMEM;
++              goto out;
++      }
+ 
+       psock->mux = mux;
+       psock->sk = csk;
+@@ -1407,7 +1415,7 @@ static int kcm_attach(struct socket *sock, struct socket 
*csock,
+       err = strp_init(&psock->strp, csk, &cb);
+       if (err) {
+               kmem_cache_free(kcm_psockp, psock);
+-              return err;
++              goto out;
+       }
+ 
+       write_lock_bh(&csk->sk_callback_lock);
+@@ -1419,7 +1427,8 @@ static int kcm_attach(struct socket *sock, struct socket 
*csock,
+               write_unlock_bh(&csk->sk_callback_lock);
+               strp_done(&psock->strp);
+               kmem_cache_free(kcm_psockp, psock);
+-              return -EALREADY;
++              err = -EALREADY;
++              goto out;
+       }
+ 
+       psock->save_data_ready = csk->sk_data_ready;
+@@ -1455,7 +1464,10 @@ static int kcm_attach(struct socket *sock, struct 
socket *csock,
+       /* Schedule RX work in case there are already bytes queued */
+       strp_check_rcv(&psock->strp);
+ 
+-      return 0;
++out:
++      release_sock(csk);
++
++      return err;
+ }
+ 
+ static int kcm_attach_ioctl(struct socket *sock, struct kcm_attach *info)
+@@ -1507,6 +1519,7 @@ static void kcm_unattach(struct kcm_psock *psock)
+ 
+       if (WARN_ON(psock->rx_kcm)) {
+               write_unlock_bh(&csk->sk_callback_lock);
++              release_sock(csk);
+               return;
+       }
+ 
+diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
+index 861b67c34191..e8b26afeb194 100644
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1466,9 +1466,14 @@ int l2tp_tunnel_create(struct net *net, int fd, int 
version, u32 tunnel_id, u32
+               encap = cfg->encap;
+ 
+       /* Quick sanity checks */
++      err = -EPROTONOSUPPORT;
++      if (sk->sk_type != SOCK_DGRAM) {
++              pr_debug("tunl %hu: fd %d wrong socket type\n",
++                       tunnel_id, fd);
++              goto err;
++      }
+       switch (encap) {
+       case L2TP_ENCAPTYPE_UDP:
+-              err = -EPROTONOSUPPORT;
+               if (sk->sk_protocol != IPPROTO_UDP) {
+                       pr_err("tunl %hu: fd %d wrong protocol, got %d, 
expected %d\n",
+                              tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
+@@ -1476,7 +1481,6 @@ int l2tp_tunnel_create(struct net *net, int fd, int 
version, u32 tunnel_id, u32
+               }
+               break;
+       case L2TP_ENCAPTYPE_IP:
+-              err = -EPROTONOSUPPORT;
+               if (sk->sk_protocol != IPPROTO_L2TP) {
+                       pr_err("tunl %hu: fd %d wrong protocol, got %d, 
expected %d\n",
+                              tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP);
+diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
+index 6f02499ef007..b9ce82c9440f 100644
+--- a/net/netlink/genetlink.c
++++ b/net/netlink/genetlink.c
+@@ -1106,7 +1106,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 
portid, unsigned long group,
+       if (!err)
+               delivered = true;
+       else if (err != -ESRCH)
+-              goto error;
++              return err;
+       return delivered ? 0 : -ESRCH;
+  error:
+       kfree_skb(skb);
+diff --git a/net/openvswitch/meter.c b/net/openvswitch/meter.c
+index 3fbfc78991ac..0d961f09d0c7 100644
+--- a/net/openvswitch/meter.c
++++ b/net/openvswitch/meter.c
+@@ -242,14 +242,20 @@ static struct dp_meter *dp_meter_create(struct nlattr 
**a)
+ 
+               band->type = nla_get_u32(attr[OVS_BAND_ATTR_TYPE]);
+               band->rate = nla_get_u32(attr[OVS_BAND_ATTR_RATE]);
++              if (band->rate == 0) {
++                      err = -EINVAL;
++                      goto exit_free_meter;
++              }
++
+               band->burst_size = nla_get_u32(attr[OVS_BAND_ATTR_BURST]);
+               /* Figure out max delta_t that is enough to fill any bucket.
+                * Keep max_delta_t size to the bucket units:
+                * pkts => 1/1000 packets, kilobits => bits.
++               *
++               * Start with a full bucket.
+                */
+-              band_max_delta_t = (band->burst_size + band->rate) * 1000;
+-              /* Start with a full bucket. */
+-              band->bucket = band_max_delta_t;
++              band->bucket = (band->burst_size + band->rate) * 1000;
++              band_max_delta_t = band->bucket / band->rate;
+               if (band_max_delta_t > meter->max_delta_t)
+                       meter->max_delta_t = band_max_delta_t;
+               band++;
+diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
+index 30c96274c638..22bf1a376b91 100644
+--- a/net/sched/act_tunnel_key.c
++++ b/net/sched/act_tunnel_key.c
+@@ -153,6 +153,7 @@ static int tunnel_key_init(struct net *net, struct nlattr 
*nla,
+               metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
+               break;
+       default:
++              ret = -EINVAL;
+               goto err_out;
+       }
+ 
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index dd70924cbcdf..2aeca57f9bd0 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -509,7 +509,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc 
*sch,
+       }
+ 
+       if (unlikely(sch->q.qlen >= sch->limit))
+-              return qdisc_drop(skb, sch, to_free);
++              return qdisc_drop_all(skb, sch, to_free);
+ 
+       qdisc_qstats_backlog_inc(sch, skb);
+ 

Reply via email to