--- /dev/null
+From 88e69af061f2e061a68751ef9cad47a674527a1b Mon Sep 17 00:00:00 2001
+From: Ratheesh Kannoth <rkannoth@marvell.com>
+Date: Fri, 8 Sep 2023 08:23:09 +0530
+Subject: octeontx2-pf: Fix page pool cache index corruption.
+
+From: Ratheesh Kannoth <rkannoth@marvell.com>
+
+commit 88e69af061f2e061a68751ef9cad47a674527a1b upstream.
+
+The access to page pool `cache' array and the `count' variable
+is not locked. Page pool cache access is fine as long as there
+is only one consumer per pool.
+
+octeontx2 driver fills in rx buffers from page pool in NAPI context.
+If system is stressed and could not allocate buffers, refiiling work
+will be delegated to a delayed workqueue. This means that there are
+two cosumers to the page pool cache.
+
+Either workqueue or IRQ/NAPI can be run on other CPU. This will lead
+to lock less access, hence corruption of cache pool indexes.
+
+To fix this issue, NAPI is rescheduled from workqueue context to refill
+rx buffers.
+
+Fixes: b2e3406a38f0 ("octeontx2-pf: Add support for page pool")
+Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
+Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c | 6 +-
+ drivers/net/ethernet/marvell/octeontx2/nic/cn10k.h | 2
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 43 ++-------------
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h | 3 -
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 7 +-
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | 30 ++++++++--
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h | 4 -
+ 7 files changed, 44 insertions(+), 51 deletions(-)
+
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
+@@ -107,12 +107,13 @@ int cn10k_sq_aq_init(void *dev, u16 qidx
+ }
+
+ #define NPA_MAX_BURST 16
+-void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq)
++int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq)
+ {
+ struct otx2_nic *pfvf = dev;
++ int cnt = cq->pool_ptrs;
+ u64 ptrs[NPA_MAX_BURST];
+- int num_ptrs = 1;
+ dma_addr_t bufptr;
++ int num_ptrs = 1;
+
+ /* Refill pool with new buffers */
+ while (cq->pool_ptrs) {
+@@ -131,6 +132,7 @@ void cn10k_refill_pool_ptrs(void *dev, s
+ num_ptrs = 1;
+ }
+ }
++ return cnt - cq->pool_ptrs;
+ }
+
+ void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx)
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.h
+@@ -24,7 +24,7 @@ static inline int mtu_to_dwrr_weight(str
+ return weight;
+ }
+
+-void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq);
++int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq);
+ void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx);
+ int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura);
+ int cn10k_lmtst_init(struct otx2_nic *pfvf);
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -567,20 +567,8 @@ int otx2_alloc_rbuf(struct otx2_nic *pfv
+ int otx2_alloc_buffer(struct otx2_nic *pfvf, struct otx2_cq_queue *cq,
+ dma_addr_t *dma)
+ {
+- if (unlikely(__otx2_alloc_rbuf(pfvf, cq->rbpool, dma))) {
+- struct refill_work *work;
+- struct delayed_work *dwork;
+-
+- work = &pfvf->refill_wrk[cq->cq_idx];
+- dwork = &work->pool_refill_work;
+- /* Schedule a task if no other task is running */
+- if (!cq->refill_task_sched) {
+- cq->refill_task_sched = true;
+- schedule_delayed_work(dwork,
+- msecs_to_jiffies(100));
+- }
++ if (unlikely(__otx2_alloc_rbuf(pfvf, cq->rbpool, dma)))
+ return -ENOMEM;
+- }
+ return 0;
+ }
+
+@@ -1081,39 +1069,20 @@ static int otx2_cq_init(struct otx2_nic
+ static void otx2_pool_refill_task(struct work_struct *work)
+ {
+ struct otx2_cq_queue *cq;
+- struct otx2_pool *rbpool;
+ struct refill_work *wrk;
+- int qidx, free_ptrs = 0;
+ struct otx2_nic *pfvf;
+- dma_addr_t bufptr;
++ int qidx;
+
+ wrk = container_of(work, struct refill_work, pool_refill_work.work);
+ pfvf = wrk->pf;
+ qidx = wrk - pfvf->refill_wrk;
+ cq = &pfvf->qset.cq[qidx];
+- rbpool = cq->rbpool;
+- free_ptrs = cq->pool_ptrs;
+-
+- while (cq->pool_ptrs) {
+- if (otx2_alloc_rbuf(pfvf, rbpool, &bufptr)) {
+- /* Schedule a WQ if we fails to free atleast half of the
+- * pointers else enable napi for this RQ.
+- */
+- if (!((free_ptrs - cq->pool_ptrs) > free_ptrs / 2)) {
+- struct delayed_work *dwork;
+
+- dwork = &wrk->pool_refill_work;
+- schedule_delayed_work(dwork,
+- msecs_to_jiffies(100));
+- } else {
+- cq->refill_task_sched = false;
+- }
+- return;
+- }
+- pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM);
+- cq->pool_ptrs--;
+- }
+ cq->refill_task_sched = false;
++
++ local_bh_disable();
++ napi_schedule(wrk->napi);
++ local_bh_enable();
+ }
+
+ int otx2_config_nix_queues(struct otx2_nic *pfvf)
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -280,6 +280,7 @@ struct flr_work {
+ struct refill_work {
+ struct delayed_work pool_refill_work;
+ struct otx2_nic *pf;
++ struct napi_struct *napi;
+ };
+
+ /* PTPv2 originTimestamp structure */
+@@ -347,7 +348,7 @@ struct dev_hw_ops {
+ int (*sq_aq_init)(void *dev, u16 qidx, u16 sqb_aura);
+ void (*sqe_flush)(void *dev, struct otx2_snd_queue *sq,
+ int size, int qidx);
+- void (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq);
++ int (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq);
+ void (*aura_freeptr)(void *dev, int aura, u64 buf);
+ };
+
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -2005,6 +2005,10 @@ int otx2_stop(struct net_device *netdev)
+
+ netif_tx_disable(netdev);
+
++ for (wrk = 0; wrk < pf->qset.cq_cnt; wrk++)
++ cancel_delayed_work_sync(&pf->refill_wrk[wrk].pool_refill_work);
++ devm_kfree(pf->dev, pf->refill_wrk);
++
+ otx2_free_hw_resources(pf);
+ otx2_free_cints(pf, pf->hw.cint_cnt);
+ otx2_disable_napi(pf);
+@@ -2012,9 +2016,6 @@ int otx2_stop(struct net_device *netdev)
+ for (qidx = 0; qidx < netdev->num_tx_queues; qidx++)
+ netdev_tx_reset_queue(netdev_get_tx_queue(netdev, qidx));
+
+- for (wrk = 0; wrk < pf->qset.cq_cnt; wrk++)
+- cancel_delayed_work_sync(&pf->refill_wrk[wrk].pool_refill_work);
+- devm_kfree(pf->dev, pf->refill_wrk);
+
+ kfree(qset->sq);
+ kfree(qset->cq);
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+@@ -428,9 +428,10 @@ process_cqe:
+ return processed_cqe;
+ }
+
+-void otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq)
++int otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq)
+ {
+ struct otx2_nic *pfvf = dev;
++ int cnt = cq->pool_ptrs;
+ dma_addr_t bufptr;
+
+ while (cq->pool_ptrs) {
+@@ -439,6 +440,8 @@ void otx2_refill_pool_ptrs(void *dev, st
+ otx2_aura_freeptr(pfvf, cq->cq_idx, bufptr + OTX2_HEAD_ROOM);
+ cq->pool_ptrs--;
+ }
++
++ return cnt - cq->pool_ptrs;
+ }
+
+ static int otx2_tx_napi_handler(struct otx2_nic *pfvf,
+@@ -532,6 +535,7 @@ int otx2_napi_handler(struct napi_struct
+ struct otx2_cq_queue *cq;
+ struct otx2_qset *qset;
+ struct otx2_nic *pfvf;
++ int filled_cnt = -1;
+
+ cq_poll = container_of(napi, struct otx2_cq_poll, napi);
+ pfvf = (struct otx2_nic *)cq_poll->dev;
+@@ -552,7 +556,7 @@ int otx2_napi_handler(struct napi_struct
+ }
+
+ if (rx_cq && rx_cq->pool_ptrs)
+- pfvf->hw_ops->refill_pool_ptrs(pfvf, rx_cq);
++ filled_cnt = pfvf->hw_ops->refill_pool_ptrs(pfvf, rx_cq);
+ /* Clear the IRQ */
+ otx2_write64(pfvf, NIX_LF_CINTX_INT(cq_poll->cint_idx), BIT_ULL(0));
+
+@@ -565,9 +569,25 @@ int otx2_napi_handler(struct napi_struct
+ if (pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED)
+ otx2_adjust_adaptive_coalese(pfvf, cq_poll);
+
+- /* Re-enable interrupts */
+- otx2_write64(pfvf, NIX_LF_CINTX_ENA_W1S(cq_poll->cint_idx),
+- BIT_ULL(0));
++ if (unlikely(!filled_cnt)) {
++ struct refill_work *work;
++ struct delayed_work *dwork;
++
++ work = &pfvf->refill_wrk[cq->cq_idx];
++ dwork = &work->pool_refill_work;
++ /* Schedule a task if no other task is running */
++ if (!cq->refill_task_sched) {
++ work->napi = napi;
++ cq->refill_task_sched = true;
++ schedule_delayed_work(dwork,
++ msecs_to_jiffies(100));
++ }
++ } else {
++ /* Re-enable interrupts */
++ otx2_write64(pfvf,
++ NIX_LF_CINTX_ENA_W1S(cq_poll->cint_idx),
++ BIT_ULL(0));
++ }
+ }
+ return workdone;
+ }
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
+@@ -170,6 +170,6 @@ void cn10k_sqe_flush(void *dev, struct o
+ int size, int qidx);
+ void otx2_sqe_flush(void *dev, struct otx2_snd_queue *sq,
+ int size, int qidx);
+-void otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq);
+-void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq);
++int otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq);
++int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq);
+ #endif /* OTX2_TXRX_H */
--- /dev/null
+From 50e492143374c17ad89c865a1a44837b3f5c8226 Mon Sep 17 00:00:00 2001
+From: Ratheesh Kannoth <rkannoth@marvell.com>
+Date: Tue, 10 Oct 2023 09:18:42 +0530
+Subject: octeontx2-pf: Fix page pool frag allocation warning
+
+From: Ratheesh Kannoth <rkannoth@marvell.com>
+
+commit 50e492143374c17ad89c865a1a44837b3f5c8226 upstream.
+
+Since page pool param's "order" is set to 0, will result
+in below warn message if interface is configured with higher
+rx buffer size.
+
+Steps to reproduce the issue.
+1. devlink dev param set pci/0002:04:00.0 name receive_buffer_size \
+ value 8196 cmode runtime
+2. ifconfig eth0 up
+
+[ 19.901356] ------------[ cut here ]------------
+[ 19.901361] WARNING: CPU: 11 PID: 12331 at net/core/page_pool.c:567 page_pool_alloc_frag+0x3c/0x230
+[ 19.901449] pstate: 82401009 (Nzcv daif +PAN -UAO +TCO -DIT +SSBS BTYPE=--)
+[ 19.901451] pc : page_pool_alloc_frag+0x3c/0x230
+[ 19.901453] lr : __otx2_alloc_rbuf+0x60/0xbc [rvu_nicpf]
+[ 19.901460] sp : ffff80000f66b970
+[ 19.901461] x29: ffff80000f66b970 x28: 0000000000000000 x27: 0000000000000000
+[ 19.901464] x26: ffff800000d15b68 x25: ffff000195b5c080 x24: ffff0002a5a32dc0
+[ 19.901467] x23: ffff0001063c0878 x22: 0000000000000100 x21: 0000000000000000
+[ 19.901469] x20: 0000000000000000 x19: ffff00016f781000 x18: 0000000000000000
+[ 19.901472] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
+[ 19.901474] x14: 0000000000000000 x13: ffff0005ffdc9c80 x12: 0000000000000000
+[ 19.901477] x11: ffff800009119a38 x10: 4c6ef2e3ba300519 x9 : ffff800000d13844
+[ 19.901479] x8 : ffff0002a5a33cc8 x7 : 0000000000000030 x6 : 0000000000000030
+[ 19.901482] x5 : 0000000000000005 x4 : 0000000000000000 x3 : 0000000000000a20
+[ 19.901484] x2 : 0000000000001080 x1 : ffff80000f66b9d4 x0 : 0000000000001000
+[ 19.901487] Call trace:
+[ 19.901488] page_pool_alloc_frag+0x3c/0x230
+[ 19.901490] __otx2_alloc_rbuf+0x60/0xbc [rvu_nicpf]
+[ 19.901494] otx2_rq_aura_pool_init+0x1c4/0x240 [rvu_nicpf]
+[ 19.901498] otx2_open+0x228/0xa70 [rvu_nicpf]
+[ 19.901501] otx2vf_open+0x20/0xd0 [rvu_nicvf]
+[ 19.901504] __dev_open+0x114/0x1d0
+[ 19.901507] __dev_change_flags+0x194/0x210
+[ 19.901510] dev_change_flags+0x2c/0x70
+[ 19.901512] devinet_ioctl+0x3a4/0x6c4
+[ 19.901515] inet_ioctl+0x228/0x240
+[ 19.901518] sock_ioctl+0x2ac/0x480
+[ 19.901522] __arm64_sys_ioctl+0x564/0xe50
+[ 19.901525] invoke_syscall.constprop.0+0x58/0xf0
+[ 19.901529] do_el0_svc+0x58/0x150
+[ 19.901531] el0_svc+0x30/0x140
+[ 19.901533] el0t_64_sync_handler+0xe8/0x114
+[ 19.901535] el0t_64_sync+0x1a0/0x1a4
+[ 19.901537] ---[ end trace 678c0bf660ad8116 ]---
+
+Fixes: b2e3406a38f0 ("octeontx2-pf: Add support for page pool")
+Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
+Reviewed-by: Yunsheng Lin <linyunsheng@huawei.com>
+Link: https://lore.kernel.org/r/20231010034842.3807816-1-rkannoth@marvell.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -1402,6 +1402,7 @@ int otx2_pool_init(struct otx2_nic *pfvf
+ return 0;
+ }
+
++ pp_params.order = get_order(buf_size);
+ pp_params.flags = PP_FLAG_PAGE_FRAG | PP_FLAG_DMA_MAP;
+ pp_params.pool_size = min(OTX2_PAGE_POOL_SZ, numptrs);
+ pp_params.nid = NUMA_NO_NODE;
--- /dev/null
+From 49fa4b0d06705a24a81bb8be6eb175059b77f0a7 Mon Sep 17 00:00:00 2001
+From: Ratheesh Kannoth <rkannoth@marvell.com>
+Date: Thu, 24 Aug 2023 08:33:01 +0530
+Subject: octeontx2-pf: fix page_pool creation fail for rings > 32k
+
+From: Ratheesh Kannoth <rkannoth@marvell.com>
+
+commit 49fa4b0d06705a24a81bb8be6eb175059b77f0a7 upstream.
+
+octeontx2 driver calls page_pool_create() during driver probe()
+and fails if queue size > 32k. Page pool infra uses these buffers
+as shock absorbers for burst traffic. These pages are pinned down
+over time as working sets varies, due to the recycling nature
+of page pool, given page pool (currently) don't have a shrinker
+mechanism, the pages remain pinned down in ptr_ring.
+Instead of clamping page_pool size to 32k at
+most, limit it even more to 2k to avoid wasting memory.
+
+This have been tested on octeontx2 CN10KA hardware.
+TCP and UDP tests using iperf shows no performance regressions.
+
+Fixes: b2e3406a38f0 ("octeontx2-pf: Add support for page pool")
+Suggested-by: Alexander Lobakin <aleksander.lobakin@intel.com>
+Reviewed-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
+Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 2 +-
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -1434,7 +1434,7 @@ int otx2_pool_init(struct otx2_nic *pfvf
+ }
+
+ pp_params.flags = PP_FLAG_PAGE_FRAG | PP_FLAG_DMA_MAP;
+- pp_params.pool_size = numptrs;
++ pp_params.pool_size = min(OTX2_PAGE_POOL_SZ, numptrs);
+ pp_params.nid = NUMA_NO_NODE;
+ pp_params.dev = pfvf->dev;
+ pp_params.dma_dir = DMA_FROM_DEVICE;
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
+@@ -23,6 +23,8 @@
+ #define OTX2_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN)
+ #define OTX2_MIN_MTU 60
+
++#define OTX2_PAGE_POOL_SZ 2048
++
+ #define OTX2_MAX_GSO_SEGS 255
+ #define OTX2_MAX_FRAGS_IN_SQE 9
+