]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Feb 2022 17:04:06 +0000 (18:04 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Feb 2022 17:04:06 +0000 (18:04 +0100)
added patches:
net-ipa-prevent-concurrent-replenish.patch
net-ipa-use-a-bitmap-for-endpoint-replenish_enabled.patch

queue-5.15/net-ipa-prevent-concurrent-replenish.patch [new file with mode: 0644]
queue-5.15/net-ipa-use-a-bitmap-for-endpoint-replenish_enabled.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/net-ipa-prevent-concurrent-replenish.patch b/queue-5.15/net-ipa-prevent-concurrent-replenish.patch
new file mode 100644 (file)
index 0000000..f826786
--- /dev/null
@@ -0,0 +1,79 @@
+From 998c0bd2b3715244da7639cc4e6a2062cb79c3f4 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@linaro.org>
+Date: Wed, 12 Jan 2022 07:30:12 -0600
+Subject: net: ipa: prevent concurrent replenish
+
+From: Alex Elder <elder@linaro.org>
+
+commit 998c0bd2b3715244da7639cc4e6a2062cb79c3f4 upstream.
+
+We have seen cases where an endpoint RX completion interrupt arrives
+while replenishing for the endpoint is underway.  This causes another
+instance of replenishing to begin as part of completing the receive
+transaction.  If this occurs it can lead to transaction corruption.
+
+Use a new flag to ensure only one replenish instance for an endpoint
+executes at a time.
+
+Fixes: 84f9bd12d46db ("soc: qcom: ipa: IPA endpoints")
+Signed-off-by: Alex Elder <elder@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ipa/ipa_endpoint.c |   13 +++++++++++++
+ drivers/net/ipa/ipa_endpoint.h |    2 ++
+ 2 files changed, 15 insertions(+)
+
+--- a/drivers/net/ipa/ipa_endpoint.c
++++ b/drivers/net/ipa/ipa_endpoint.c
+@@ -1075,15 +1075,27 @@ static void ipa_endpoint_replenish(struc
+               return;
+       }
++      /* If already active, just update the backlog */
++      if (test_and_set_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags)) {
++              if (add_one)
++                      atomic_inc(&endpoint->replenish_backlog);
++              return;
++      }
++
+       while (atomic_dec_not_zero(&endpoint->replenish_backlog))
+               if (ipa_endpoint_replenish_one(endpoint))
+                       goto try_again_later;
++
++      clear_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags);
++
+       if (add_one)
+               atomic_inc(&endpoint->replenish_backlog);
+       return;
+ try_again_later:
++      clear_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags);
++
+       /* The last one didn't succeed, so fix the backlog */
+       delta = add_one ? 2 : 1;
+       backlog = atomic_add_return(delta, &endpoint->replenish_backlog);
+@@ -1666,6 +1678,7 @@ static void ipa_endpoint_setup_one(struc
+                * backlog is the same as the maximum outstanding TREs.
+                */
+               clear_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags);
++              clear_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags);
+               atomic_set(&endpoint->replenish_saved,
+                          gsi_channel_tre_max(gsi, endpoint->channel_id));
+               atomic_set(&endpoint->replenish_backlog, 0);
+--- a/drivers/net/ipa/ipa_endpoint.h
++++ b/drivers/net/ipa/ipa_endpoint.h
+@@ -44,10 +44,12 @@ enum ipa_endpoint_name {
+  * enum ipa_replenish_flag:   RX buffer replenish flags
+  *
+  * @IPA_REPLENISH_ENABLED:    Whether receive buffer replenishing is enabled
++ * @IPA_REPLENISH_ACTIVE:     Whether replenishing is underway
+  * @IPA_REPLENISH_COUNT:      Number of defined replenish flags
+  */
+ enum ipa_replenish_flag {
+       IPA_REPLENISH_ENABLED,
++      IPA_REPLENISH_ACTIVE,
+       IPA_REPLENISH_COUNT,    /* Number of flags (must be last) */
+ };
diff --git a/queue-5.15/net-ipa-use-a-bitmap-for-endpoint-replenish_enabled.patch b/queue-5.15/net-ipa-use-a-bitmap-for-endpoint-replenish_enabled.patch
new file mode 100644 (file)
index 0000000..9934d66
--- /dev/null
@@ -0,0 +1,98 @@
+From c1aaa01dbf4cef95af3e04a5a43986c290e06ea3 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@linaro.org>
+Date: Wed, 12 Jan 2022 07:30:11 -0600
+Subject: net: ipa: use a bitmap for endpoint replenish_enabled
+
+From: Alex Elder <elder@linaro.org>
+
+commit c1aaa01dbf4cef95af3e04a5a43986c290e06ea3 upstream.
+
+Define a new replenish_flags bitmap to contain Boolean flags
+associated with an endpoint's replenishing state.  Replace the
+replenish_enabled field with a flag in that bitmap.  This is to
+prepare for the next patch, which adds another flag.
+
+Signed-off-by: Alex Elder <elder@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ipa/ipa_endpoint.c |    8 ++++----
+ drivers/net/ipa/ipa_endpoint.h |   15 +++++++++++++--
+ 2 files changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ipa/ipa_endpoint.c
++++ b/drivers/net/ipa/ipa_endpoint.c
+@@ -1069,7 +1069,7 @@ static void ipa_endpoint_replenish(struc
+       u32 backlog;
+       int delta;
+-      if (!endpoint->replenish_enabled) {
++      if (!test_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags)) {
+               if (add_one)
+                       atomic_inc(&endpoint->replenish_saved);
+               return;
+@@ -1106,7 +1106,7 @@ static void ipa_endpoint_replenish_enabl
+       u32 max_backlog;
+       u32 saved;
+-      endpoint->replenish_enabled = true;
++      set_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags);
+       while ((saved = atomic_xchg(&endpoint->replenish_saved, 0)))
+               atomic_add(saved, &endpoint->replenish_backlog);
+@@ -1120,7 +1120,7 @@ static void ipa_endpoint_replenish_disab
+ {
+       u32 backlog;
+-      endpoint->replenish_enabled = false;
++      clear_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags);
+       while ((backlog = atomic_xchg(&endpoint->replenish_backlog, 0)))
+               atomic_add(backlog, &endpoint->replenish_saved);
+ }
+@@ -1665,7 +1665,7 @@ static void ipa_endpoint_setup_one(struc
+               /* RX transactions require a single TRE, so the maximum
+                * backlog is the same as the maximum outstanding TREs.
+                */
+-              endpoint->replenish_enabled = false;
++              clear_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags);
+               atomic_set(&endpoint->replenish_saved,
+                          gsi_channel_tre_max(gsi, endpoint->channel_id));
+               atomic_set(&endpoint->replenish_backlog, 0);
+--- a/drivers/net/ipa/ipa_endpoint.h
++++ b/drivers/net/ipa/ipa_endpoint.h
+@@ -41,6 +41,17 @@ enum ipa_endpoint_name {
+ #define IPA_ENDPOINT_MAX              32      /* Max supported by driver */
+ /**
++ * enum ipa_replenish_flag:   RX buffer replenish flags
++ *
++ * @IPA_REPLENISH_ENABLED:    Whether receive buffer replenishing is enabled
++ * @IPA_REPLENISH_COUNT:      Number of defined replenish flags
++ */
++enum ipa_replenish_flag {
++      IPA_REPLENISH_ENABLED,
++      IPA_REPLENISH_COUNT,    /* Number of flags (must be last) */
++};
++
++/**
+  * struct ipa_endpoint - IPA endpoint information
+  * @ipa:              IPA pointer
+  * @ee_id:            Execution environmnent endpoint is associated with
+@@ -51,7 +62,7 @@ enum ipa_endpoint_name {
+  * @trans_tre_max:    Maximum number of TRE descriptors per transaction
+  * @evt_ring_id:      GSI event ring used by the endpoint
+  * @netdev:           Network device pointer, if endpoint uses one
+- * @replenish_enabled:        Whether receive buffer replenishing is enabled
++ * @replenish_flags:  Replenishing state flags
+  * @replenish_ready:  Number of replenish transactions without doorbell
+  * @replenish_saved:  Replenish requests held while disabled
+  * @replenish_backlog:        Number of buffers needed to fill hardware queue
+@@ -72,7 +83,7 @@ struct ipa_endpoint {
+       struct net_device *netdev;
+       /* Receive buffer replenishing for RX endpoints */
+-      bool replenish_enabled;
++      DECLARE_BITMAP(replenish_flags, IPA_REPLENISH_COUNT);
+       u32 replenish_ready;
+       atomic_t replenish_saved;
+       atomic_t replenish_backlog;
index 7b46f3a0849e3e3f264a061005d2f9ac6cd6336b..7aadba04d17fe651711172a679e6ec2d0586a4a0 100644 (file)
@@ -1,2 +1,4 @@
 pci-pciehp-fix-infinite-loop-in-irq-handler-upon-power-fault.patch
 selftests-mptcp-fix-ipv6-routing-setup.patch
+net-ipa-use-a-bitmap-for-endpoint-replenish_enabled.patch
+net-ipa-prevent-concurrent-replenish.patch