--- /dev/null
+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
+@@ -1605,7 +1605,6 @@ static const struct mips_perf_event *mip
+ break;
+ case CPU_P5600:
+ case CPU_P6600:
+- case CPU_I6400:
+ /* 8-bit event numbers */
+ raw_id = config & 0x1ff;
+ base_id = raw_id & 0xff;
+@@ -1618,6 +1617,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;
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- drivers/net/ethernet/broadcom/bcmsysport.c | 3 ++-
+ drivers/net/ethernet/broadcom/bcmsysport.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
-diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
-index 6519dd33c7ca2..5d67dbdd943dc 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
-@@ -504,7 +504,8 @@ static struct sk_buff *bcm_sysport_rx_refill(struct bcm_sysport_priv *priv,
+@@ -504,7 +504,8 @@ static struct sk_buff *bcm_sysport_rx_re
dma_addr_t mapping;
/* Allocate a new SKB for a new packet */
if (!skb) {
priv->mib.alloc_rx_buff_failed++;
netif_err(priv, rx_err, ndev, "SKB alloc failed\n");
---
-2.20.1
-
--- /dev/null
+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
+@@ -71,21 +71,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
+@@ -891,10 +891,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;
+@@ -919,12 +926,18 @@ rpcrdma_create_rep(struct rpcrdma_xprt *
+ rep->rr_recv_wr.wr_cqe = &rep->rr_cqe;
+ rep->rr_recv_wr.sg_list = &rep->rr_rdmabuf->rg_iov;
+ rep->rr_recv_wr.num_sge = 1;
+- 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
+@@ -967,17 +980,10 @@ rpcrdma_buffer_create(struct rpcrdma_xpr
+ }
+
+ INIT_LIST_HEAD(&buf->rb_recv_bufs);
+- for (i = 0; i < buf->rb_max_requests + RPCRDMA_MAX_BC_REQUESTS; 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
+@@ -502,8 +502,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_req *);
++int rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt);
+ int rpcrdma_buffer_create(struct rpcrdma_xprt *);
+ void rpcrdma_buffer_destroy(struct rpcrdma_buffer *);
+