From a4b2be3e352518d2991d8f6175289650a8bca9b2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 7 May 2020 14:55:46 +0200 Subject: [PATCH] 4.4-stable patches 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 --- ...chip-after-irq-handler-is-registered.patch | 52 +++++++ .../bonding-fix-length-of-actor-system.patch | 35 +++++ ...e-id-reference-in-fib_sync_down_addr.patch | 36 +++++ ...-odd-even-counter-handling-for-i6400.patch | 47 ++++++ ...-not-call-napi_schedule-without-care.patch | 43 ++++++ ...-disable-auto-negotiation-on-startup.patch | 54 ------- queue-4.4/series | 8 +- queue-4.4/vti6-fix-input-path.patch | 110 ++++++++++++++ ...nel-allocation-of-extra-rpcrdma_reps.patch | 142 ++++++++++++++++++ 9 files changed, 472 insertions(+), 55 deletions(-) create mode 100644 queue-4.4/alsa-fm801-initialize-chip-after-irq-handler-is-registered.patch create mode 100644 queue-4.4/bonding-fix-length-of-actor-system.patch create mode 100644 queue-4.4/ipv4-fix-table-id-reference-in-fib_sync_down_addr.patch create mode 100644 queue-4.4/mips-perf-remove-incorrect-odd-even-counter-handling-for-i6400.patch create mode 100644 queue-4.4/mlx4-do-not-call-napi_schedule-without-care.patch delete mode 100644 queue-4.4/phy-micrel-disable-auto-negotiation-on-startup.patch create mode 100644 queue-4.4/vti6-fix-input-path.patch create mode 100644 queue-4.4/xprtrdma-fix-backchannel-allocation-of-extra-rpcrdma_reps.patch 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 index 00000000000..e33620133ae --- /dev/null +++ b/queue-4.4/alsa-fm801-initialize-chip-after-irq-handler-is-registered.patch @@ -0,0 +1,52 @@ +From 610e1ae9b533be82b3aa118b907e0a703256913d Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +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 + +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 +Tested-by: Émeric MASCHINO +Signed-off-by: Andy Shevchenko +Cc: # v4.5+ +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c1519ac7020 --- /dev/null +++ b/queue-4.4/bonding-fix-length-of-actor-system.patch @@ -0,0 +1,35 @@ +From 414dd6fb9a1a1b59983aea7bf0f79f0085ecc5b8 Mon Sep 17 00:00:00 2001 +From: Tobias Jungel +Date: Sun, 28 Oct 2018 12:54:10 +0100 +Subject: bonding: fix length of actor system + +From: Tobias Jungel + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d4eb4164d8a --- /dev/null +++ b/queue-4.4/ipv4-fix-table-id-reference-in-fib_sync_down_addr.patch @@ -0,0 +1,36 @@ +From e0a312629fefa943534fc46f7bfbe6de3fdaf463 Mon Sep 17 00:00:00 2001 +From: David Ahern +Date: Thu, 7 Nov 2019 18:29:52 +0000 +Subject: ipv4: Fix table id reference in fib_sync_down_addr + +From: David Ahern + +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 +Signed-off-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..cfcd20f1c01 --- /dev/null +++ b/queue-4.4/mips-perf-remove-incorrect-odd-even-counter-handling-for-i6400.patch @@ -0,0 +1,47 @@ +From f7a31b5e7874f77464a4eae0a8ba84b9ae0b3a54 Mon Sep 17 00:00:00 2001 +From: Marcin Nowakowski +Date: Wed, 19 Apr 2017 14:07:43 +0200 +Subject: MIPS: perf: Remove incorrect odd/even counter handling for I6400 + +From: Marcin Nowakowski + +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 +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8b6eef09919 --- /dev/null +++ b/queue-4.4/mlx4-do-not-call-napi_schedule-without-care.patch @@ -0,0 +1,43 @@ +From 8cf699ec849f4ca1413cea01289bd7d37dbcc626 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 13 Jan 2017 08:39:24 -0800 +Subject: mlx4: do not call napi_schedule() without care + +From: Eric Dumazet + +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 +Cc: Erez Shitrit +Cc: Eugenia Emantayev +Cc: Tariq Toukan +Acked-by: Tariq Toukan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 54ec17f8feb..00000000000 --- a/queue-4.4/phy-micrel-disable-auto-negotiation-on-startup.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 99f81afc139c6edd14d77a91ee91685a414a1c66 Mon Sep 17 00:00:00 2001 -From: Alexandre Belloni -Date: Fri, 26 Feb 2016 19:18:23 +0100 -Subject: phy: micrel: Disable auto negotiation on startup - -From: Alexandre Belloni - -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 -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman - ---- - 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; - } - diff --git a/queue-4.4/series b/queue-4.4/series index 89270f970ee..5417028899b 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -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 index 00000000000..336e4ef3892 --- /dev/null +++ b/queue-4.4/vti6-fix-input-path.patch @@ -0,0 +1,110 @@ +From 63c43787d35e45562a6b5927e2edc8f4783d95b8 Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Mon, 19 Sep 2016 16:17:57 +0200 +Subject: vti6: fix input path + +From: Nicolas Dichtel + +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 +Fixes: 1625f4529957 ("net/xfrm_input: fix possible NULL deref of tunnel.ip6->parms.i_key") +Signed-off-by: Nicolas Dichtel +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..caed83ee003 --- /dev/null +++ b/queue-4.4/xprtrdma-fix-backchannel-allocation-of-extra-rpcrdma_reps.patch @@ -0,0 +1,142 @@ +From d698c4a02ee02053bbebe051322ff427a2dad56a Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Thu, 14 Dec 2017 20:56:09 -0500 +Subject: xprtrdma: Fix backchannel allocation of extra rpcrdma_reps + +From: Chuck Lever + +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 +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + 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 *); + -- 2.47.3