diff for duplicates of <20260923140647.993637736@linuxfoundation.org> diff --git a/a/1.txt b/N1/1.txt index d96d9ca..cafe959 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,34 +1,141 @@ -7.2-stable review patch. If anyone has any objections, please let me know. +6.18-stable review patch. If anyone has any objections, please let me know. ------------------ -From: Namjae Jeon <linkinjeon@kernel.org> +From: Jakub Kicinski <kuba@kernel.org> -[ Upstream commit 1923eeffa63edeff427d76fc302bc5eb835771ce ] +[ Upstream commit 490599ab23134962a6d18a024e84541d77bdb999 ] -Return the error from __filemap_get_folio() instead of replacing it -with -ENOMEM. +fbnic_tx_map() skips the doorbell write, and the completion request, +for every packet handed to it with xmit_more set, counting on the +packet which ends the burst to publish them all. When that packet is +dropped instead - skb_put_padto(), skb_cow_head() or a DMA mapping +failure - nothing rings. The descriptors of the preceding packets stay +invisible to the HW until the next transmit on that queue, which for a +burst-then-idle workload may never come. -Fixes: af0db57d4293 ("ntfs: update inode operations") -Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> -Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> +Remember the meta descriptor of the last packet left without a doorbell +and flush it from the error paths. The completion request has to be set +on that descriptor rather than simply writing the tail, otherwise the HW +would transmit the packets but never report a head, and the ring would +fill up and stall for good. + +This is very similar to Joe's recent series of fixes for bnxt. +Not seen in real life, reproduced under QEMU with failure injection. + +Fixes: 9a57bacd574b ("eth: fbnic: Add basic Tx handling") +Reviewed-by: Alexander Duyck <alexanderduyck@fb.com> +Reviewed-by: Simon Horman <horms@kernel.org> +Link: https://patch.msgid.link/20260915022327.913218-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> --- - fs/ntfs/inode.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c -index 560f1dd1fba39..b6e161d51dce2 100644 ---- a/fs/ntfs/inode.c -+++ b/fs/ntfs/inode.c -@@ -3713,7 +3713,7 @@ static s64 __ntfs_inode_non_resident_attr_pwrite(struct inode *vi, - FGP_CREAT | FGP_LOCK, - mapping_gfp_mask(mapping)); - if (IS_ERR(folio)) { -- ret = -ENOMEM; -+ ret = PTR_ERR(folio); - break; - } - } else { + drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 42 +++++++++++++++----- + drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 9 ++++- + 2 files changed, 40 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +index dbe0855ecb575..0ea861ff40f56 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +@@ -311,6 +311,29 @@ fbnic_rx_csum(u64 rcd, struct sk_buff *skb, struct fbnic_ring *rcq, + } + } + ++static void fbnic_tx_doorbell(struct fbnic_ring *ring, __le64 *meta) ++{ ++ *meta |= cpu_to_le64(FBNIC_TWD_FLAG_REQ_COMPLETION); ++ ring->deferred_meta = -1; ++ ++ /* Force DMA writes to flush before writing to tail */ ++ dma_wmb(); ++ ++ writel(ring->tail, ring->doorbell); ++} ++ ++/* Packets handed to us with xmit_more set are left in the ring without a ++ * doorbell, and without a completion request, in the expectation that the ++ * packet ending the burst will ring for all of them. If that packet gets ++ * dropped instead we have to ring here, otherwise the descriptors sit in ++ * the ring until the next transmit, which may never come. ++ */ ++static void fbnic_tx_flush_doorbell(struct fbnic_ring *ring) ++{ ++ if (ring->deferred_meta >= 0) ++ fbnic_tx_doorbell(ring, &ring->desc[ring->deferred_meta]); ++} ++ + static bool + fbnic_tx_map(struct fbnic_ring *ring, struct sk_buff *skb, __le64 *meta) + { +@@ -378,14 +401,10 @@ fbnic_tx_map(struct fbnic_ring *ring, struct sk_buff *skb, __le64 *meta) + /* Verify there is room for another packet */ + fbnic_maybe_stop_tx(skb->dev, ring, FBNIC_MAX_SKB_DESC); + +- if (fbnic_tx_sent_queue(skb, ring)) { +- *meta |= cpu_to_le64(FBNIC_TWD_FLAG_REQ_COMPLETION); +- +- /* Force DMA writes to flush before writing to tail */ +- dma_wmb(); +- +- writel(tail, ring->doorbell); +- } ++ if (fbnic_tx_sent_queue(skb, ring)) ++ fbnic_tx_doorbell(ring, meta); ++ else ++ ring->deferred_meta = meta - ring->desc; + + return false; + dma_error: +@@ -425,8 +444,10 @@ fbnic_xmit_frame_ring(struct sk_buff *skb, struct fbnic_ring *ring) + * otherwise try next time + */ + desc_needed = skb_shinfo(skb)->nr_frags + 10; +- if (fbnic_maybe_stop_tx(skb->dev, ring, desc_needed)) ++ if (fbnic_maybe_stop_tx(skb->dev, ring, desc_needed)) { ++ fbnic_tx_flush_doorbell(ring); + return NETDEV_TX_BUSY; ++ } + + *meta = cpu_to_le64(FBNIC_TWD_FLAG_DEST_MAC); + +@@ -447,6 +468,8 @@ fbnic_xmit_frame_ring(struct sk_buff *skb, struct fbnic_ring *ring) + err_free: + dev_kfree_skb_any(skb); + err_count: ++ fbnic_tx_flush_doorbell(ring); ++ + u64_stats_update_begin(&ring->stats.syncp); + ring->stats.dropped++; + u64_stats_update_end(&ring->stats.syncp); +@@ -2473,6 +2496,7 @@ static void fbnic_enable_twq0(struct fbnic_ring *twq) + fbnic_ring_wr32(twq, FBNIC_QUEUE_TWQ0_CTL, FBNIC_QUEUE_TWQ_CTL_RESET); + twq->tail = 0; + twq->head = 0; ++ twq->deferred_meta = -1; + + /* Store descriptor ring address and size */ + fbnic_ring_wr32(twq, FBNIC_QUEUE_TWQ0_BAL, lower_32_bits(twq->dma)); +diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +index f2ee2cbf3486b..643e7d3ddb543 100644 +--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h ++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +@@ -128,9 +128,14 @@ struct fbnic_ring { + /* Rx BDQs only */ + struct page_pool *page_pool; + +- /* Deferred_head is used to cache the head for TWQ1 if ++ /* TWQ0 only, index of the meta descriptor of the last packet ++ * placed in the ring without ringing the doorbell, -1 if the ++ * doorbell is in sync with the tail. ++ */ ++ s32 deferred_meta; ++ ++ /* TCQ only, used to cache the head for TWQ1 if + * an attempt is made to clean TWQ1 with zero napi_budget. +- * We do not use it for any other ring. + */ + s32 deferred_head; + }; -- 2.53.0 diff --git a/a/content_digest b/N1/content_digest index bf5d77b..2a5138e 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,48 +1,156 @@ - "ref\020260923140644.756254324@linuxfoundation.org\0" + "ref\020260923140643.441954610@linuxfoundation.org\0" "From\0Greg Kroah-Hartman <gregkh@linuxfoundation.org>\0" - "Subject\0[PATCH 7.2 124/438] ntfs: propagate folio errors\0" - "Date\0Wed, 23 Sep 2026 16:02:25 +0200\0" + "Subject\0[PATCH 6.18 176/398] eth: fbnic: ring the doorbell if a burst ends in a drop\0" + "Date\0Wed, 23 Sep 2026 16:04:10 +0200\0" "To\0stable@vger.kernel.org\0" "Cc\0Greg Kroah-Hartman <gregkh@linuxfoundation.org>" patches@lists.linux.dev - Hyunchul Lee <hyc.lee@gmail.com> - Namjae Jeon <linkinjeon@kernel.org> + Alexander Duyck <alexanderduyck@fb.com> + Simon Horman <horms@kernel.org> + Jakub Kicinski <kuba@kernel.org> " Sasha Levin <sashal@kernel.org>\0" "\00:1\0" "b\0" - "7.2-stable review patch. If anyone has any objections, please let me know.\n" + "6.18-stable review patch. If anyone has any objections, please let me know.\n" "\n" "------------------\n" "\n" - "From: Namjae Jeon <linkinjeon@kernel.org>\n" + "From: Jakub Kicinski <kuba@kernel.org>\n" "\n" - "[ Upstream commit 1923eeffa63edeff427d76fc302bc5eb835771ce ]\n" + "[ Upstream commit 490599ab23134962a6d18a024e84541d77bdb999 ]\n" "\n" - "Return the error from __filemap_get_folio() instead of replacing it\n" - "with -ENOMEM.\n" + "fbnic_tx_map() skips the doorbell write, and the completion request,\n" + "for every packet handed to it with xmit_more set, counting on the\n" + "packet which ends the burst to publish them all. When that packet is\n" + "dropped instead - skb_put_padto(), skb_cow_head() or a DMA mapping\n" + "failure - nothing rings. The descriptors of the preceding packets stay\n" + "invisible to the HW until the next transmit on that queue, which for a\n" + "burst-then-idle workload may never come.\n" "\n" - "Fixes: af0db57d4293 (\"ntfs: update inode operations\")\n" - "Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>\n" - "Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>\n" + "Remember the meta descriptor of the last packet left without a doorbell\n" + "and flush it from the error paths. The completion request has to be set\n" + "on that descriptor rather than simply writing the tail, otherwise the HW\n" + "would transmit the packets but never report a head, and the ring would\n" + "fill up and stall for good.\n" + "\n" + "This is very similar to Joe's recent series of fixes for bnxt.\n" + "Not seen in real life, reproduced under QEMU with failure injection.\n" + "\n" + "Fixes: 9a57bacd574b (\"eth: fbnic: Add basic Tx handling\")\n" + "Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>\n" + "Reviewed-by: Simon Horman <horms@kernel.org>\n" + "Link: https://patch.msgid.link/20260915022327.913218-1-kuba@kernel.org\n" + "Signed-off-by: Jakub Kicinski <kuba@kernel.org>\n" "Signed-off-by: Sasha Levin <sashal@kernel.org>\n" "---\n" - " fs/ntfs/inode.c | 2 +-\n" - " 1 file changed, 1 insertion(+), 1 deletion(-)\n" - "\n" - "diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c\n" - "index 560f1dd1fba39..b6e161d51dce2 100644\n" - "--- a/fs/ntfs/inode.c\n" - "+++ b/fs/ntfs/inode.c\n" - "@@ -3713,7 +3713,7 @@ static s64 __ntfs_inode_non_resident_attr_pwrite(struct inode *vi,\n" - " \t\t\t\t\tFGP_CREAT | FGP_LOCK,\n" - " \t\t\t\t\tmapping_gfp_mask(mapping));\n" - " \t\t\tif (IS_ERR(folio)) {\n" - "-\t\t\t\tret = -ENOMEM;\n" - "+\t\t\t\tret = PTR_ERR(folio);\n" - " \t\t\t\tbreak;\n" - " \t\t\t}\n" - " \t\t} else {\n" + " drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 42 +++++++++++++++-----\n" + " drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 9 ++++-\n" + " 2 files changed, 40 insertions(+), 11 deletions(-)\n" + "\n" + "diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c\n" + "index dbe0855ecb575..0ea861ff40f56 100644\n" + "--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c\n" + "+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c\n" + "@@ -311,6 +311,29 @@ fbnic_rx_csum(u64 rcd, struct sk_buff *skb, struct fbnic_ring *rcq,\n" + " \t}\n" + " }\n" + " \n" + "+static void fbnic_tx_doorbell(struct fbnic_ring *ring, __le64 *meta)\n" + "+{\n" + "+\t*meta |= cpu_to_le64(FBNIC_TWD_FLAG_REQ_COMPLETION);\n" + "+\tring->deferred_meta = -1;\n" + "+\n" + "+\t/* Force DMA writes to flush before writing to tail */\n" + "+\tdma_wmb();\n" + "+\n" + "+\twritel(ring->tail, ring->doorbell);\n" + "+}\n" + "+\n" + "+/* Packets handed to us with xmit_more set are left in the ring without a\n" + "+ * doorbell, and without a completion request, in the expectation that the\n" + "+ * packet ending the burst will ring for all of them. If that packet gets\n" + "+ * dropped instead we have to ring here, otherwise the descriptors sit in\n" + "+ * the ring until the next transmit, which may never come.\n" + "+ */\n" + "+static void fbnic_tx_flush_doorbell(struct fbnic_ring *ring)\n" + "+{\n" + "+\tif (ring->deferred_meta >= 0)\n" + "+\t\tfbnic_tx_doorbell(ring, &ring->desc[ring->deferred_meta]);\n" + "+}\n" + "+\n" + " static bool\n" + " fbnic_tx_map(struct fbnic_ring *ring, struct sk_buff *skb, __le64 *meta)\n" + " {\n" + "@@ -378,14 +401,10 @@ fbnic_tx_map(struct fbnic_ring *ring, struct sk_buff *skb, __le64 *meta)\n" + " \t/* Verify there is room for another packet */\n" + " \tfbnic_maybe_stop_tx(skb->dev, ring, FBNIC_MAX_SKB_DESC);\n" + " \n" + "-\tif (fbnic_tx_sent_queue(skb, ring)) {\n" + "-\t\t*meta |= cpu_to_le64(FBNIC_TWD_FLAG_REQ_COMPLETION);\n" + "-\n" + "-\t\t/* Force DMA writes to flush before writing to tail */\n" + "-\t\tdma_wmb();\n" + "-\n" + "-\t\twritel(tail, ring->doorbell);\n" + "-\t}\n" + "+\tif (fbnic_tx_sent_queue(skb, ring))\n" + "+\t\tfbnic_tx_doorbell(ring, meta);\n" + "+\telse\n" + "+\t\tring->deferred_meta = meta - ring->desc;\n" + " \n" + " \treturn false;\n" + " dma_error:\n" + "@@ -425,8 +444,10 @@ fbnic_xmit_frame_ring(struct sk_buff *skb, struct fbnic_ring *ring)\n" + " \t * otherwise try next time\n" + " \t */\n" + " \tdesc_needed = skb_shinfo(skb)->nr_frags + 10;\n" + "-\tif (fbnic_maybe_stop_tx(skb->dev, ring, desc_needed))\n" + "+\tif (fbnic_maybe_stop_tx(skb->dev, ring, desc_needed)) {\n" + "+\t\tfbnic_tx_flush_doorbell(ring);\n" + " \t\treturn NETDEV_TX_BUSY;\n" + "+\t}\n" + " \n" + " \t*meta = cpu_to_le64(FBNIC_TWD_FLAG_DEST_MAC);\n" + " \n" + "@@ -447,6 +468,8 @@ fbnic_xmit_frame_ring(struct sk_buff *skb, struct fbnic_ring *ring)\n" + " err_free:\n" + " \tdev_kfree_skb_any(skb);\n" + " err_count:\n" + "+\tfbnic_tx_flush_doorbell(ring);\n" + "+\n" + " \tu64_stats_update_begin(&ring->stats.syncp);\n" + " \tring->stats.dropped++;\n" + " \tu64_stats_update_end(&ring->stats.syncp);\n" + "@@ -2473,6 +2496,7 @@ static void fbnic_enable_twq0(struct fbnic_ring *twq)\n" + " \tfbnic_ring_wr32(twq, FBNIC_QUEUE_TWQ0_CTL, FBNIC_QUEUE_TWQ_CTL_RESET);\n" + " \ttwq->tail = 0;\n" + " \ttwq->head = 0;\n" + "+\ttwq->deferred_meta = -1;\n" + " \n" + " \t/* Store descriptor ring address and size */\n" + " \tfbnic_ring_wr32(twq, FBNIC_QUEUE_TWQ0_BAL, lower_32_bits(twq->dma));\n" + "diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h\n" + "index f2ee2cbf3486b..643e7d3ddb543 100644\n" + "--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h\n" + "+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h\n" + "@@ -128,9 +128,14 @@ struct fbnic_ring {\n" + " \t\t/* Rx BDQs only */\n" + " \t\tstruct page_pool *page_pool;\n" + " \n" + "-\t\t/* Deferred_head is used to cache the head for TWQ1 if\n" + "+\t\t/* TWQ0 only, index of the meta descriptor of the last packet\n" + "+\t\t * placed in the ring without ringing the doorbell, -1 if the\n" + "+\t\t * doorbell is in sync with the tail.\n" + "+\t\t */\n" + "+\t\ts32 deferred_meta;\n" + "+\n" + "+\t\t/* TCQ only, used to cache the head for TWQ1 if\n" + " \t\t * an attempt is made to clean TWQ1 with zero napi_budget.\n" + "-\t\t * We do not use it for any other ring.\n" + " \t\t */\n" + " \t\ts32 deferred_head;\n" + " \t};\n" "-- \n" 2.53.0 -9521a702a45c07316a1621d69d0cd49189446e876e008e9132420beb74971994 +eb80bb861fc86d55bb7289532cbf43a1d04c630049df0d77f5293b815a6b8158
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox