]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 7 May 2020 12:55:46 +0000 (14:55 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 7 May 2020 12:55:46 +0000 (14:55 +0200)
added patches:
alsa-fm801-initialize-chip-after-irq-handler-is-registered.patch
bonding-fix-length-of-actor-system.patch
ipv4-fix-table-id-reference-in-fib_sync_down_addr.patch
mips-perf-remove-incorrect-odd-even-counter-handling-for-i6400.patch
mlx4-do-not-call-napi_schedule-without-care.patch
vti6-fix-input-path.patch
xprtrdma-fix-backchannel-allocation-of-extra-rpcrdma_reps.patch

queue-4.4/alsa-fm801-initialize-chip-after-irq-handler-is-registered.patch [new file with mode: 0644]
queue-4.4/bonding-fix-length-of-actor-system.patch [new file with mode: 0644]
queue-4.4/ipv4-fix-table-id-reference-in-fib_sync_down_addr.patch [new file with mode: 0644]
queue-4.4/mips-perf-remove-incorrect-odd-even-counter-handling-for-i6400.patch [new file with mode: 0644]
queue-4.4/mlx4-do-not-call-napi_schedule-without-care.patch [new file with mode: 0644]
queue-4.4/phy-micrel-disable-auto-negotiation-on-startup.patch [deleted file]
queue-4.4/series
queue-4.4/vti6-fix-input-path.patch [new file with mode: 0644]
queue-4.4/xprtrdma-fix-backchannel-allocation-of-extra-rpcrdma_reps.patch [new file with mode: 0644]

diff --git a/queue-4.4/alsa-fm801-initialize-chip-after-irq-handler-is-registered.patch b/queue-4.4/alsa-fm801-initialize-chip-after-irq-handler-is-registered.patch
new file mode 100644 (file)
index 0000000..e336201
--- /dev/null
@@ -0,0 +1,52 @@
+From 610e1ae9b533be82b3aa118b907e0a703256913d Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Sun, 16 Jul 2017 21:40:03 +0300
+Subject: ALSA: fm801: Initialize chip after IRQ handler is registered
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+commit 610e1ae9b533be82b3aa118b907e0a703256913d upstream.
+
+The commit b56fa687e02b ("ALSA: fm801: detect FM-only card earlier")
+rearranged initialization calls, i.e. it makes snd_fm801_chip_init() to
+be called before we register interrupt handler and set PCI bus
+mastering.
+
+Somehow it prevents FM801-AU to work properly. Thus, partially revert
+initialization order changed by commit mentioned above.
+
+Fixes: b56fa687e02b ("ALSA: fm801: detect FM-only card earlier")
+Reported-by: Émeric MASCHINO <emeric.maschino@gmail.com>
+Tested-by: Émeric MASCHINO <emeric.maschino@gmail.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: <stable@vger.kernel.org> # v4.5+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/fm801.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/fm801.c
++++ b/sound/pci/fm801.c
+@@ -1225,8 +1225,6 @@ static int snd_fm801_create(struct snd_c
+               }
+       }
+-      snd_fm801_chip_init(chip);
+-
+       if ((chip->tea575x_tuner & TUNER_ONLY) == 0) {
+               if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt,
+                               IRQF_SHARED, KBUILD_MODNAME, chip)) {
+@@ -1238,6 +1236,8 @@ static int snd_fm801_create(struct snd_c
+               pci_set_master(pci);
+       }
++      snd_fm801_chip_init(chip);
++
+       if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+               snd_fm801_free(chip);
+               return err;
diff --git a/queue-4.4/bonding-fix-length-of-actor-system.patch b/queue-4.4/bonding-fix-length-of-actor-system.patch
new file mode 100644 (file)
index 0000000..c1519ac
--- /dev/null
@@ -0,0 +1,35 @@
+From 414dd6fb9a1a1b59983aea7bf0f79f0085ecc5b8 Mon Sep 17 00:00:00 2001
+From: Tobias Jungel <tobias.jungel@gmail.com>
+Date: Sun, 28 Oct 2018 12:54:10 +0100
+Subject: bonding: fix length of actor system
+
+From: Tobias Jungel <tobias.jungel@gmail.com>
+
+commit 414dd6fb9a1a1b59983aea7bf0f79f0085ecc5b8 upstream.
+
+The attribute IFLA_BOND_AD_ACTOR_SYSTEM is sent to user space having the
+length of sizeof(bond->params.ad_actor_system) which is 8 byte. This
+patch aligns the length to ETH_ALEN to have the same MAC address exposed
+as using sysfs.
+
+Fixes: f87fda00b6ed2 ("bonding: prevent out of bound accesses")
+Signed-off-by: Tobias Jungel <tobias.jungel@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/bonding/bond_netlink.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/net/bonding/bond_netlink.c
++++ b/drivers/net/bonding/bond_netlink.c
+@@ -628,8 +628,7 @@ static int bond_fill_info(struct sk_buff
+                               goto nla_put_failure;
+                       if (nla_put(skb, IFLA_BOND_AD_ACTOR_SYSTEM,
+-                                  sizeof(bond->params.ad_actor_system),
+-                                  &bond->params.ad_actor_system))
++                                  ETH_ALEN, &bond->params.ad_actor_system))
+                               goto nla_put_failure;
+               }
+               if (!bond_3ad_get_active_agg_info(bond, &info)) {
diff --git a/queue-4.4/ipv4-fix-table-id-reference-in-fib_sync_down_addr.patch b/queue-4.4/ipv4-fix-table-id-reference-in-fib_sync_down_addr.patch
new file mode 100644 (file)
index 0000000..d4eb416
--- /dev/null
@@ -0,0 +1,36 @@
+From e0a312629fefa943534fc46f7bfbe6de3fdaf463 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@kernel.org>
+Date: Thu, 7 Nov 2019 18:29:52 +0000
+Subject: ipv4: Fix table id reference in fib_sync_down_addr
+
+From: David Ahern <dsahern@kernel.org>
+
+commit e0a312629fefa943534fc46f7bfbe6de3fdaf463 upstream.
+
+Hendrik reported routes in the main table using source address are not
+removed when the address is removed. The problem is that fib_sync_down_addr
+does not account for devices in the default VRF which are associated
+with the main table. Fix by updating the table id reference.
+
+Fixes: 5a56a0b3a45d ("net: Don't delete routes in different VRFs")
+Reported-by: Hendrik Donner <hd@os-cillation.de>
+Signed-off-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/fib_semantics.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -1358,8 +1358,8 @@ int fib_sync_down_addr(struct net_device
+       int ret = 0;
+       unsigned int hash = fib_laddr_hashfn(local);
+       struct hlist_head *head = &fib_info_laddrhash[hash];
++      int tb_id = l3mdev_fib_table(dev) ? : RT_TABLE_MAIN;
+       struct net *net = dev_net(dev);
+-      int tb_id = l3mdev_fib_table(dev);
+       struct fib_info *fi;
+       if (!fib_info_laddrhash || local == 0)
diff --git a/queue-4.4/mips-perf-remove-incorrect-odd-even-counter-handling-for-i6400.patch b/queue-4.4/mips-perf-remove-incorrect-odd-even-counter-handling-for-i6400.patch
new file mode 100644 (file)
index 0000000..cfcd20f
--- /dev/null
@@ -0,0 +1,47 @@
+From f7a31b5e7874f77464a4eae0a8ba84b9ae0b3a54 Mon Sep 17 00:00:00 2001
+From: Marcin Nowakowski <marcin.nowakowski@mips.com>
+Date: Wed, 19 Apr 2017 14:07:43 +0200
+Subject: MIPS: perf: Remove incorrect odd/even counter handling for I6400
+
+From: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
+
+commit f7a31b5e7874f77464a4eae0a8ba84b9ae0b3a54 upstream.
+
+All performance counters on I6400 (odd and even) are capable of counting
+any of the available events, so drop current logic of using the extra
+bit to determine which counter to use.
+
+Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
+Fixes: 4e88a8621301 ("MIPS: Add cases for CPU_I6400")
+Fixes: fd716fca10fc ("MIPS: perf: Fix I6400 event numbers")
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/15991/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/perf_event_mipsxx.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/perf_event_mipsxx.c
++++ b/arch/mips/kernel/perf_event_mipsxx.c
+@@ -1606,7 +1606,6 @@ static const struct mips_perf_event *mip
+ #endif
+               break;
+       case CPU_P5600:
+-      case CPU_I6400:
+               /* 8-bit event numbers */
+               raw_id = config & 0x1ff;
+               base_id = raw_id & 0xff;
+@@ -1619,6 +1618,11 @@ static const struct mips_perf_event *mip
+               raw_event.range = P;
+ #endif
+               break;
++      case CPU_I6400:
++              /* 8-bit event numbers */
++              base_id = config & 0xff;
++              raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
++              break;
+       case CPU_1004K:
+               if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
+                       raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
diff --git a/queue-4.4/mlx4-do-not-call-napi_schedule-without-care.patch b/queue-4.4/mlx4-do-not-call-napi_schedule-without-care.patch
new file mode 100644 (file)
index 0000000..8b6eef0
--- /dev/null
@@ -0,0 +1,43 @@
+From 8cf699ec849f4ca1413cea01289bd7d37dbcc626 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 13 Jan 2017 08:39:24 -0800
+Subject: mlx4: do not call napi_schedule() without care
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 8cf699ec849f4ca1413cea01289bd7d37dbcc626 upstream.
+
+Disable BH around the call to napi_schedule() to avoid following warning
+
+[   52.095499] NOHZ: local_softirq_pending 08
+[   52.421291] NOHZ: local_softirq_pending 08
+[   52.608313] NOHZ: local_softirq_pending 08
+
+Fixes: 8d59de8f7bb3 ("net/mlx4_en: Process all completions in RX rings after port goes up")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Erez Shitrit <erezsh@mellanox.com>
+Cc: Eugenia Emantayev <eugenia@mellanox.com>
+Cc: Tariq Toukan <tariqt@mellanox.com>
+Acked-by: Tariq Toukan <tariqt@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlx4/en_netdev.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+@@ -1724,8 +1724,11 @@ int mlx4_en_start_port(struct net_device
+       /* Process all completions if exist to prevent
+        * the queues freezing if they are full
+        */
+-      for (i = 0; i < priv->rx_ring_num; i++)
++      for (i = 0; i < priv->rx_ring_num; i++) {
++              local_bh_disable();
+               napi_schedule(&priv->rx_cq[i]->napi);
++              local_bh_enable();
++      }
+       netif_tx_start_all_queues(dev);
+       netif_device_attach(dev);
diff --git a/queue-4.4/phy-micrel-disable-auto-negotiation-on-startup.patch b/queue-4.4/phy-micrel-disable-auto-negotiation-on-startup.patch
deleted file mode 100644 (file)
index 54ec17f..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-From 99f81afc139c6edd14d77a91ee91685a414a1c66 Mon Sep 17 00:00:00 2001
-From: Alexandre Belloni <alexandre.belloni@bootlin.com>
-Date: Fri, 26 Feb 2016 19:18:23 +0100
-Subject: phy: micrel: Disable auto negotiation on startup
-
-From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
-
-commit 99f81afc139c6edd14d77a91ee91685a414a1c66 upstream.
-
-Disable auto negotiation on init to properly detect an already plugged
-cable at boot.
-
-At boot, when the phy is started, it is in the PHY_UP state.
-However, if a cable is plugged at boot, because auto negociation is already
-enabled at the time we get the first interrupt, the phy is already running.
-But the state machine then switches from PHY_UP to PHY_AN and calls
-phy_start_aneg(). phy_start_aneg() will not do anything because aneg is
-already enabled on the phy. It will then wait for a interrupt before going
-further. This interrupt will never happen unless the cable is unplugged and
-then replugged.
-
-It was working properly before 321beec5047a (net: phy: Use interrupts when
-available in NOLINK state) because switching to NOLINK meant starting
-polling the phy, even if IRQ were enabled.
-
-Fixes: 321beec5047a (net: phy: Use interrupts when available in NOLINK state)
-Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/net/phy/micrel.c |   11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/net/phy/micrel.c
-+++ b/drivers/net/phy/micrel.c
-@@ -285,6 +285,17 @@ static int kszphy_config_init(struct phy
-       if (priv->led_mode >= 0)
-               kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);
-+      if (phy_interrupt_is_valid(phydev)) {
-+              int ctl = phy_read(phydev, MII_BMCR);
-+
-+              if (ctl < 0)
-+                      return ctl;
-+
-+              ret = phy_write(phydev, MII_BMCR, ctl & ~BMCR_ANENABLE);
-+              if (ret < 0)
-+                      return ret;
-+      }
-+
-       return 0;
- }
index 89270f970ee5ff8eb7e6bf07a04f5df43124aebe..5417028899bba7f89dc2778f4cdab7e715abeac0 100644 (file)
@@ -154,7 +154,6 @@ net-phy-fix-phy_mac_interrupt.patch
 net-phy-bcm7xxx-fix-shadow-mode-2-disabling.patch
 of_mdio-fix-node-leak-in-of_phy_register_fixed_link-error-path.patch
 phy-micrel-fix-finding-phy-properties-in-mac-node-for-ksz9031.patch
-phy-micrel-disable-auto-negotiation-on-startup.patch
 net-dsa-slave-fix-of-node-leak-and-phy-priority.patch
 drivers-net-cpsw-don-t-ignore-phy-mode-if-phy-handle-is-used.patch
 iommu-dma-respect-iommu-aperture-when-allocating.patch
@@ -244,3 +243,10 @@ power-bq27xxx_battery-fix-bq27541-averagepower-register-address.patch
 power_supply-tps65217-charger-fix-null-deref-during-property-export.patch
 net-vrf-fix-dst-reference-counting.patch
 net-don-t-delete-routes-in-different-vrfs.patch
+vti6-fix-input-path.patch
+ipv4-fix-table-id-reference-in-fib_sync_down_addr.patch
+mlx4-do-not-call-napi_schedule-without-care.patch
+xprtrdma-fix-backchannel-allocation-of-extra-rpcrdma_reps.patch
+alsa-fm801-initialize-chip-after-irq-handler-is-registered.patch
+bonding-fix-length-of-actor-system.patch
+mips-perf-remove-incorrect-odd-even-counter-handling-for-i6400.patch
diff --git a/queue-4.4/vti6-fix-input-path.patch b/queue-4.4/vti6-fix-input-path.patch
new file mode 100644 (file)
index 0000000..336e4ef
--- /dev/null
@@ -0,0 +1,110 @@
+From 63c43787d35e45562a6b5927e2edc8f4783d95b8 Mon Sep 17 00:00:00 2001
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Date: Mon, 19 Sep 2016 16:17:57 +0200
+Subject: vti6: fix input path
+
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+
+commit 63c43787d35e45562a6b5927e2edc8f4783d95b8 upstream.
+
+Since commit 1625f4529957, vti6 is broken, all input packets are dropped
+(LINUX_MIB_XFRMINNOSTATES is incremented).
+
+XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 is set by vti6_rcv() before calling
+xfrm6_rcv()/xfrm6_rcv_spi(), thus we cannot set to NULL that value in
+xfrm6_rcv_spi().
+
+A new function xfrm6_rcv_tnl() that enables to pass a value to
+xfrm6_rcv_spi() is added, so that xfrm6_rcv() is not touched (this function
+is used in several handlers).
+
+CC: Alexey Kodanev <alexey.kodanev@oracle.com>
+Fixes: 1625f4529957 ("net/xfrm_input: fix possible NULL deref of tunnel.ip6->parms.i_key")
+Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/xfrm.h      |    4 +++-
+ net/ipv6/ip6_vti.c      |    4 +---
+ net/ipv6/xfrm6_input.c  |   16 +++++++++++-----
+ net/ipv6/xfrm6_tunnel.c |    2 +-
+ 4 files changed, 16 insertions(+), 10 deletions(-)
+
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -1551,8 +1551,10 @@ int xfrm4_tunnel_deregister(struct xfrm_
+ void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
+ int xfrm6_extract_header(struct sk_buff *skb);
+ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
+-int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
++int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
++                struct ip6_tnl *t);
+ int xfrm6_transport_finish(struct sk_buff *skb, int async);
++int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
+ int xfrm6_rcv(struct sk_buff *skb);
+ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
+                    xfrm_address_t *saddr, u8 proto);
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -324,11 +324,9 @@ static int vti6_rcv(struct sk_buff *skb)
+                       goto discard;
+               }
+-              XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
+-
+               rcu_read_unlock();
+-              return xfrm6_rcv(skb);
++              return xfrm6_rcv_tnl(skb, t);
+       }
+       rcu_read_unlock();
+       return -EINVAL;
+--- a/net/ipv6/xfrm6_input.c
++++ b/net/ipv6/xfrm6_input.c
+@@ -21,9 +21,10 @@ int xfrm6_extract_input(struct xfrm_stat
+       return xfrm6_extract_header(skb);
+ }
+-int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
++int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
++                struct ip6_tnl *t)
+ {
+-      XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
++      XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
+       XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
+       XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
+       return xfrm_input(skb, nexthdr, spi, 0);
+@@ -49,13 +50,18 @@ int xfrm6_transport_finish(struct sk_buf
+       return -1;
+ }
+-int xfrm6_rcv(struct sk_buff *skb)
++int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t)
+ {
+       return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
+-                           0);
++                           0, t);
+ }
+-EXPORT_SYMBOL(xfrm6_rcv);
++EXPORT_SYMBOL(xfrm6_rcv_tnl);
++int xfrm6_rcv(struct sk_buff *skb)
++{
++      return xfrm6_rcv_tnl(skb, NULL);
++}
++EXPORT_SYMBOL(xfrm6_rcv);
+ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
+                    xfrm_address_t *saddr, u8 proto)
+ {
+--- a/net/ipv6/xfrm6_tunnel.c
++++ b/net/ipv6/xfrm6_tunnel.c
+@@ -239,7 +239,7 @@ static int xfrm6_tunnel_rcv(struct sk_bu
+       __be32 spi;
+       spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr);
+-      return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi);
++      return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL);
+ }
+ static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff --git a/queue-4.4/xprtrdma-fix-backchannel-allocation-of-extra-rpcrdma_reps.patch b/queue-4.4/xprtrdma-fix-backchannel-allocation-of-extra-rpcrdma_reps.patch
new file mode 100644 (file)
index 0000000..caed83e
--- /dev/null
@@ -0,0 +1,142 @@
+From d698c4a02ee02053bbebe051322ff427a2dad56a Mon Sep 17 00:00:00 2001
+From: Chuck Lever <chuck.lever@oracle.com>
+Date: Thu, 14 Dec 2017 20:56:09 -0500
+Subject: xprtrdma: Fix backchannel allocation of extra rpcrdma_reps
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+commit d698c4a02ee02053bbebe051322ff427a2dad56a upstream.
+
+The backchannel code uses rpcrdma_recv_buffer_put to add new reps
+to the free rep list. This also decrements rb_recv_count, which
+spoofs the receive overrun logic in rpcrdma_buffer_get_rep.
+
+Commit 9b06688bc3b9 ("xprtrdma: Fix additional uses of
+spin_lock_irqsave(rb_lock)") replaced the original open-coded
+list_add with a call to rpcrdma_recv_buffer_put(), but then a year
+later, commit 05c974669ece ("xprtrdma: Fix receive buffer
+accounting") added rep accounting to rpcrdma_recv_buffer_put.
+It was an oversight to let the backchannel continue to use this
+function.
+
+The fix this, let's combine the "add to free list" logic with
+rpcrdma_create_rep.
+
+Also, do not allocate RPCRDMA_MAX_BC_REQUESTS rpcrdma_reps in
+rpcrdma_buffer_create and then allocate additional rpcrdma_reps in
+rpcrdma_bc_setup_reps. Allocating the extra reps during backchannel
+set-up is sufficient.
+
+Fixes: 05c974669ece ("xprtrdma: Fix receive buffer accounting")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/xprtrdma/backchannel.c |   12 ++----------
+ net/sunrpc/xprtrdma/verbs.c       |   34 ++++++++++++++++++++--------------
+ net/sunrpc/xprtrdma/xprt_rdma.h   |    2 +-
+ 3 files changed, 23 insertions(+), 25 deletions(-)
+
+--- a/net/sunrpc/xprtrdma/backchannel.c
++++ b/net/sunrpc/xprtrdma/backchannel.c
+@@ -84,21 +84,13 @@ out_fail:
+ static int rpcrdma_bc_setup_reps(struct rpcrdma_xprt *r_xprt,
+                                unsigned int count)
+ {
+-      struct rpcrdma_rep *rep;
+       int rc = 0;
+       while (count--) {
+-              rep = rpcrdma_create_rep(r_xprt);
+-              if (IS_ERR(rep)) {
+-                      pr_err("RPC:       %s: reply buffer alloc failed\n",
+-                             __func__);
+-                      rc = PTR_ERR(rep);
++              rc = rpcrdma_create_rep(r_xprt);
++              if (rc)
+                       break;
+-              }
+-
+-              rpcrdma_recv_buffer_put(rep);
+       }
+-
+       return rc;
+ }
+--- a/net/sunrpc/xprtrdma/verbs.c
++++ b/net/sunrpc/xprtrdma/verbs.c
+@@ -911,10 +911,17 @@ rpcrdma_create_req(struct rpcrdma_xprt *
+       return req;
+ }
+-struct rpcrdma_rep *
+-rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt)
++/**
++ * rpcrdma_create_rep - Allocate an rpcrdma_rep object
++ * @r_xprt: controlling transport
++ *
++ * Returns 0 on success or a negative errno on failure.
++ */
++int
++ rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt)
+ {
+       struct rpcrdma_create_data_internal *cdata = &r_xprt->rx_data;
++      struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
+       struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+       struct rpcrdma_rep *rep;
+       int rc;
+@@ -934,12 +941,18 @@ rpcrdma_create_rep(struct rpcrdma_xprt *
+       rep->rr_device = ia->ri_device;
+       rep->rr_rxprt = r_xprt;
+       INIT_WORK(&rep->rr_work, rpcrdma_receive_worker);
+-      return rep;
++
++      spin_lock(&buf->rb_lock);
++      list_add(&rep->rr_list, &buf->rb_recv_bufs);
++      spin_unlock(&buf->rb_lock);
++      return 0;
+ out_free:
+       kfree(rep);
+ out:
+-      return ERR_PTR(rc);
++      dprintk("RPC:       %s: reply buffer %d alloc failed\n",
++              __func__, rc);
++      return rc;
+ }
+ int
+@@ -975,17 +988,10 @@ rpcrdma_buffer_create(struct rpcrdma_xpr
+       }
+       INIT_LIST_HEAD(&buf->rb_recv_bufs);
+-      for (i = 0; i < buf->rb_max_requests + 2; i++) {
+-              struct rpcrdma_rep *rep;
+-
+-              rep = rpcrdma_create_rep(r_xprt);
+-              if (IS_ERR(rep)) {
+-                      dprintk("RPC:       %s: reply buffer %d alloc failed\n",
+-                              __func__, i);
+-                      rc = PTR_ERR(rep);
++      for (i = 0; i <= buf->rb_max_requests; i++) {
++              rc = rpcrdma_create_rep(r_xprt);
++              if (rc)
+                       goto out;
+-              }
+-              list_add(&rep->rr_list, &buf->rb_recv_bufs);
+       }
+       return 0;
+--- a/net/sunrpc/xprtrdma/xprt_rdma.h
++++ b/net/sunrpc/xprtrdma/xprt_rdma.h
+@@ -431,8 +431,8 @@ int rpcrdma_ep_post_recv(struct rpcrdma_
+  * Buffer calls - xprtrdma/verbs.c
+  */
+ struct rpcrdma_req *rpcrdma_create_req(struct rpcrdma_xprt *);
+-struct rpcrdma_rep *rpcrdma_create_rep(struct rpcrdma_xprt *);
+ void rpcrdma_destroy_req(struct rpcrdma_ia *, struct rpcrdma_req *);
++int rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt);
+ int rpcrdma_buffer_create(struct rpcrdma_xprt *);
+ void rpcrdma_buffer_destroy(struct rpcrdma_buffer *);