]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.10
authorSasha Levin <sashal@kernel.org>
Fri, 23 Aug 2024 00:12:52 +0000 (20:12 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 23 Aug 2024 00:12:52 +0000 (20:12 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.10/alsa-hda-tas2781-use-correct-endian-conversion.patch [new file with mode: 0644]
queue-6.10/cifs-add-a-tracepoint-to-track-credits-involved-in-r.patch [new file with mode: 0644]
queue-6.10/dm-suspend-return-erestartsys-instead-of-eintr.patch [new file with mode: 0644]
queue-6.10/platform-surface-aggregator-fix-warning-when-control.patch [new file with mode: 0644]
queue-6.10/series
queue-6.10/smb-client-avoid-possible-null-dereference-in-cifs_f.patch [new file with mode: 0644]
queue-6.10/thermal-gov_bang_bang-add-.manage-callback.patch [new file with mode: 0644]
queue-6.10/thermal-gov_bang_bang-drop-unnecessary-cooling-devic.patch [new file with mode: 0644]
queue-6.10/thermal-gov_bang_bang-split-bang_bang_control.patch [new file with mode: 0644]
queue-6.10/thermal-gov_bang_bang-use-governor_data-to-reduce-ov.patch [new file with mode: 0644]
queue-6.10/wifi-ath12k-use-128-bytes-aligned-iova-in-transmit-p.patch [new file with mode: 0644]

diff --git a/queue-6.10/alsa-hda-tas2781-use-correct-endian-conversion.patch b/queue-6.10/alsa-hda-tas2781-use-correct-endian-conversion.patch
new file mode 100644 (file)
index 0000000..f9ef2d3
--- /dev/null
@@ -0,0 +1,44 @@
+From 6030d4306f4dfb8ecf9a711dbbbc29a3e3f86d98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Aug 2024 12:04:59 +0200
+Subject: ALSA: hda/tas2781: Use correct endian conversion
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 829e2a23121fb36ee30ea5145c2a85199f68e2c8 ]
+
+The data conversion is done rather by a wrong function.  We convert to
+BE32, not from BE32.  Although the end result must be same, this was
+complained by the compiler.
+
+Fix the code again and align with another similar function
+tas2563_apply_calib() that does already right.
+
+Fixes: 3beddef84d90 ("ALSA: hda/tas2781: fix wrong calibrated data order")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202408141630.DiDUB8Z4-lkp@intel.com/
+Link: https://patch.msgid.link/20240814100500.1944-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/tas2781_hda_i2c.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c
+index 1d4b044b78410..9e88d39eac1e2 100644
+--- a/sound/pci/hda/tas2781_hda_i2c.c
++++ b/sound/pci/hda/tas2781_hda_i2c.c
+@@ -527,8 +527,8 @@ static void tas2781_apply_calib(struct tasdevice_priv *tas_priv)
+       for (i = 0; i < tas_priv->ndev; i++) {
+               for (j = 0; j < CALIB_MAX; j++) {
+-                      data = get_unaligned_be32(
+-                              &tas_priv->cali_data.data[offset]);
++                      data = cpu_to_be32(
++                              *(uint32_t *)&tas_priv->cali_data.data[offset]);
+                       rc = tasdevice_dev_bulk_write(tas_priv, i,
+                               TASDEVICE_REG(0, page_array[j], rgno_array[j]),
+                               (unsigned char *)&data, 4);
+-- 
+2.43.0
+
diff --git a/queue-6.10/cifs-add-a-tracepoint-to-track-credits-involved-in-r.patch b/queue-6.10/cifs-add-a-tracepoint-to-track-credits-involved-in-r.patch
new file mode 100644 (file)
index 0000000..ac50755
--- /dev/null
@@ -0,0 +1,475 @@
+From 73ca5c8a33f52f8068f04f18ba1fc903e7871326 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 May 2024 10:01:08 +0100
+Subject: cifs: Add a tracepoint to track credits involved in R/W requests
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 519be989717c5bffaed1dc14a439e3872cb4bb8d ]
+
+Add a tracepoint to track the credit changes and server in_flight value
+involved in the lifetime of a R/W request, logging it against the
+request/subreq debugging ID.  This requires the debugging IDs to be
+recorded in the cifs_credits struct.
+
+The tracepoint can be enabled with:
+
+       echo 1 >/sys/kernel/debug/tracing/events/cifs/smb3_rw_credits/enable
+
+Also add a three-state flag to struct cifs_credits to note if we're
+interested in determining when the in_flight contribution ends and, if so,
+to track whether we've decremented the contribution yet.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+cc: Jeff Layton <jlayton@kernel.org>
+cc: linux-cifs@vger.kernel.org
+cc: netfs@lists.linux.dev
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 74c2ab6d653b ("smb/client: avoid possible NULL dereference in cifs_free_subrequest()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsglob.h  | 17 +++++++-----
+ fs/smb/client/file.c      | 32 ++++++++++++++++++++++-
+ fs/smb/client/smb1ops.c   |  2 +-
+ fs/smb/client/smb2ops.c   | 42 ++++++++++++++++++++++++++----
+ fs/smb/client/smb2pdu.c   | 40 +++++++++++++++++++++++++---
+ fs/smb/client/trace.h     | 55 ++++++++++++++++++++++++++++++++++++++-
+ fs/smb/client/transport.c |  8 +++---
+ 7 files changed, 173 insertions(+), 23 deletions(-)
+
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index d4bcc7da700c6..0a271b9fbc622 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -290,7 +290,7 @@ struct smb_version_operations {
+       int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
+                            bool);
+       void (*add_credits)(struct TCP_Server_Info *server,
+-                          const struct cifs_credits *credits,
++                          struct cifs_credits *credits,
+                           const int optype);
+       void (*set_credits)(struct TCP_Server_Info *, const int);
+       int * (*get_credits_field)(struct TCP_Server_Info *, const int);
+@@ -550,8 +550,8 @@ struct smb_version_operations {
+                               size_t *, struct cifs_credits *);
+       /* adjust previously taken mtu credits to request size */
+       int (*adjust_credits)(struct TCP_Server_Info *server,
+-                            struct cifs_credits *credits,
+-                            const unsigned int payload_size);
++                            struct cifs_io_subrequest *subreq,
++                            unsigned int /*enum smb3_rw_credits_trace*/ trace);
+       /* check if we need to issue closedir */
+       bool (*dir_needs_close)(struct cifsFileInfo *);
+       long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t,
+@@ -848,6 +848,9 @@ static inline void cifs_server_unlock(struct TCP_Server_Info *server)
+ struct cifs_credits {
+       unsigned int value;
+       unsigned int instance;
++      unsigned int in_flight_check;
++      unsigned int rreq_debug_id;
++      unsigned int rreq_debug_index;
+ };
+ static inline unsigned int
+@@ -873,7 +876,7 @@ has_credits(struct TCP_Server_Info *server, int *credits, int num_credits)
+ }
+ static inline void
+-add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits,
++add_credits(struct TCP_Server_Info *server, struct cifs_credits *credits,
+           const int optype)
+ {
+       server->ops->add_credits(server, credits, optype);
+@@ -897,11 +900,11 @@ set_credits(struct TCP_Server_Info *server, const int val)
+ }
+ static inline int
+-adjust_credits(struct TCP_Server_Info *server, struct cifs_credits *credits,
+-             const unsigned int payload_size)
++adjust_credits(struct TCP_Server_Info *server, struct cifs_io_subrequest *subreq,
++             unsigned int /* enum smb3_rw_credits_trace */ trace)
+ {
+       return server->ops->adjust_credits ?
+-              server->ops->adjust_credits(server, credits, payload_size) : 0;
++              server->ops->adjust_credits(server, subreq, trace) : 0;
+ }
+ static inline __le64
+diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
+index 9e4f4e67768b9..b413cfef05422 100644
+--- a/fs/smb/client/file.c
++++ b/fs/smb/client/file.c
+@@ -80,6 +80,16 @@ static void cifs_prepare_write(struct netfs_io_subrequest *subreq)
+               return netfs_prepare_write_failed(subreq);
+       }
++      wdata->credits.rreq_debug_id = subreq->rreq->debug_id;
++      wdata->credits.rreq_debug_index = subreq->debug_index;
++      wdata->credits.in_flight_check = 1;
++      trace_smb3_rw_credits(wdata->rreq->debug_id,
++                            wdata->subreq.debug_index,
++                            wdata->credits.value,
++                            server->credits, server->in_flight,
++                            wdata->credits.value,
++                            cifs_trace_rw_credits_write_prepare);
++
+ #ifdef CONFIG_CIFS_SMB_DIRECT
+       if (server->smbd_conn)
+               subreq->max_nr_segs = server->smbd_conn->max_frmr_depth;
+@@ -101,7 +111,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq)
+               goto fail;
+       }
+-      rc = adjust_credits(wdata->server, &wdata->credits, wdata->subreq.len);
++      rc = adjust_credits(wdata->server, wdata, cifs_trace_rw_credits_issue_write_adjust);
+       if (rc)
+               goto fail;
+@@ -163,7 +173,18 @@ static bool cifs_clamp_length(struct netfs_io_subrequest *subreq)
+               return false;
+       }
++      rdata->credits.in_flight_check = 1;
++      rdata->credits.rreq_debug_id = rreq->debug_id;
++      rdata->credits.rreq_debug_index = subreq->debug_index;
++
++      trace_smb3_rw_credits(rdata->rreq->debug_id,
++                            rdata->subreq.debug_index,
++                            rdata->credits.value,
++                            server->credits, server->in_flight, 0,
++                            cifs_trace_rw_credits_read_submit);
++
+       subreq->len = min_t(size_t, subreq->len, rsize);
++
+ #ifdef CONFIG_CIFS_SMB_DIRECT
+       if (server->smbd_conn)
+               subreq->max_nr_segs = server->smbd_conn->max_frmr_depth;
+@@ -295,6 +316,15 @@ static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
+ #endif
+       }
++      if (rdata->credits.value != 0)
++              trace_smb3_rw_credits(rdata->rreq->debug_id,
++                                    rdata->subreq.debug_index,
++                                    rdata->credits.value,
++                                    rdata->server ? rdata->server->credits : 0,
++                                    rdata->server ? rdata->server->in_flight : 0,
++                                    -rdata->credits.value,
++                                    cifs_trace_rw_credits_free_subreq);
++
+       add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
+       if (rdata->have_xid)
+               free_xid(rdata->xid);
+diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
+index 212ec6f66ec65..e1f2feb56f45f 100644
+--- a/fs/smb/client/smb1ops.c
++++ b/fs/smb/client/smb1ops.c
+@@ -108,7 +108,7 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
+ static void
+ cifs_add_credits(struct TCP_Server_Info *server,
+-               const struct cifs_credits *credits, const int optype)
++               struct cifs_credits *credits, const int optype)
+ {
+       spin_lock(&server->req_lock);
+       server->credits += credits->value;
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index c8e536540895a..7fe59235f0901 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -66,7 +66,7 @@ change_conf(struct TCP_Server_Info *server)
+ static void
+ smb2_add_credits(struct TCP_Server_Info *server,
+-               const struct cifs_credits *credits, const int optype)
++               struct cifs_credits *credits, const int optype)
+ {
+       int *val, rc = -1;
+       int scredits, in_flight;
+@@ -94,7 +94,21 @@ smb2_add_credits(struct TCP_Server_Info *server,
+                                           server->conn_id, server->hostname, *val,
+                                           add, server->in_flight);
+       }
+-      WARN_ON_ONCE(server->in_flight == 0);
++      if (credits->in_flight_check > 1) {
++              pr_warn_once("rreq R=%08x[%x] Credits not in flight\n",
++                           credits->rreq_debug_id, credits->rreq_debug_index);
++      } else {
++              credits->in_flight_check = 2;
++      }
++      if (WARN_ON_ONCE(server->in_flight == 0)) {
++              pr_warn_once("rreq R=%08x[%x] Zero in_flight\n",
++                           credits->rreq_debug_id, credits->rreq_debug_index);
++              trace_smb3_rw_credits(credits->rreq_debug_id,
++                                    credits->rreq_debug_index,
++                                    credits->value,
++                                    server->credits, server->in_flight, 0,
++                                    cifs_trace_rw_credits_zero_in_flight);
++      }
+       server->in_flight--;
+       if (server->in_flight == 0 &&
+          ((optype & CIFS_OP_MASK) != CIFS_NEG_OP) &&
+@@ -283,16 +297,23 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
+ static int
+ smb2_adjust_credits(struct TCP_Server_Info *server,
+-                  struct cifs_credits *credits,
+-                  const unsigned int payload_size)
++                  struct cifs_io_subrequest *subreq,
++                  unsigned int /*enum smb3_rw_credits_trace*/ trace)
+ {
+-      int new_val = DIV_ROUND_UP(payload_size, SMB2_MAX_BUFFER_SIZE);
++      struct cifs_credits *credits = &subreq->credits;
++      int new_val = DIV_ROUND_UP(subreq->subreq.len, SMB2_MAX_BUFFER_SIZE);
+       int scredits, in_flight;
+       if (!credits->value || credits->value == new_val)
+               return 0;
+       if (credits->value < new_val) {
++              trace_smb3_rw_credits(subreq->rreq->debug_id,
++                                    subreq->subreq.debug_index,
++                                    credits->value,
++                                    server->credits, server->in_flight,
++                                    new_val - credits->value,
++                                    cifs_trace_rw_credits_no_adjust_up);
+               trace_smb3_too_many_credits(server->CurrentMid,
+                               server->conn_id, server->hostname, 0, credits->value - new_val, 0);
+               cifs_server_dbg(VFS, "request has less credits (%d) than required (%d)",
+@@ -308,6 +329,12 @@ smb2_adjust_credits(struct TCP_Server_Info *server,
+               in_flight = server->in_flight;
+               spin_unlock(&server->req_lock);
++              trace_smb3_rw_credits(subreq->rreq->debug_id,
++                                    subreq->subreq.debug_index,
++                                    credits->value,
++                                    server->credits, server->in_flight,
++                                    new_val - credits->value,
++                                    cifs_trace_rw_credits_old_session);
+               trace_smb3_reconnect_detected(server->CurrentMid,
+                       server->conn_id, server->hostname, scredits,
+                       credits->value - new_val, in_flight);
+@@ -316,6 +343,11 @@ smb2_adjust_credits(struct TCP_Server_Info *server,
+               return -EAGAIN;
+       }
++      trace_smb3_rw_credits(subreq->rreq->debug_id,
++                            subreq->subreq.debug_index,
++                            credits->value,
++                            server->credits, server->in_flight,
++                            new_val - credits->value, trace);
+       server->credits += credits->value - new_val;
+       scredits = server->credits;
+       in_flight = server->in_flight;
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 896147ba6660e..4cd5c33be2a1a 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -4505,8 +4505,15 @@ smb2_readv_callback(struct mid_q_entry *mid)
+       struct TCP_Server_Info *server = rdata->server;
+       struct smb2_hdr *shdr =
+                               (struct smb2_hdr *)rdata->iov[0].iov_base;
+-      struct cifs_credits credits = { .value = 0, .instance = 0 };
++      struct cifs_credits credits = {
++              .value = 0,
++              .instance = 0,
++              .rreq_debug_id = rdata->rreq->debug_id,
++              .rreq_debug_index = rdata->subreq.debug_index,
++      };
+       struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], .rq_nvec = 1 };
++      unsigned int rreq_debug_id = rdata->rreq->debug_id;
++      unsigned int subreq_debug_index = rdata->subreq.debug_index;
+       if (rdata->got_bytes) {
+               rqst.rq_iter      = rdata->subreq.io_iter;
+@@ -4590,10 +4597,16 @@ smb2_readv_callback(struct mid_q_entry *mid)
+               if (rdata->subreq.start < rdata->subreq.rreq->i_size)
+                       rdata->result = 0;
+       }
++      trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value,
++                            server->credits, server->in_flight,
++                            0, cifs_trace_rw_credits_read_response_clear);
+       rdata->credits.value = 0;
+       INIT_WORK(&rdata->subreq.work, smb2_readv_worker);
+       queue_work(cifsiod_wq, &rdata->subreq.work);
+       release_mid(mid);
++      trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
++                            server->credits, server->in_flight,
++                            credits.value, cifs_trace_rw_credits_read_response_add);
+       add_credits(server, &credits, 0);
+ }
+@@ -4650,7 +4663,7 @@ smb2_async_readv(struct cifs_io_subrequest *rdata)
+                               min_t(int, server->max_credits -
+                                               server->credits, credit_request));
+-              rc = adjust_credits(server, &rdata->credits, rdata->subreq.len);
++              rc = adjust_credits(server, rdata, cifs_trace_rw_credits_call_readv_adjust);
+               if (rc)
+                       goto async_readv_out;
+@@ -4769,7 +4782,14 @@ smb2_writev_callback(struct mid_q_entry *mid)
+       struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
+       struct TCP_Server_Info *server = wdata->server;
+       struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
+-      struct cifs_credits credits = { .value = 0, .instance = 0 };
++      struct cifs_credits credits = {
++              .value = 0,
++              .instance = 0,
++              .rreq_debug_id = wdata->rreq->debug_id,
++              .rreq_debug_index = wdata->subreq.debug_index,
++      };
++      unsigned int rreq_debug_id = wdata->rreq->debug_id;
++      unsigned int subreq_debug_index = wdata->subreq.debug_index;
+       ssize_t result = 0;
+       size_t written;
+@@ -4840,9 +4860,15 @@ smb2_writev_callback(struct mid_q_entry *mid)
+                                     tcon->tid, tcon->ses->Suid,
+                                     wdata->subreq.start, wdata->subreq.len);
++      trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, wdata->credits.value,
++                            server->credits, server->in_flight,
++                            0, cifs_trace_rw_credits_write_response_clear);
+       wdata->credits.value = 0;
+       cifs_write_subrequest_terminated(wdata, result ?: written, true);
+       release_mid(mid);
++      trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
++                            server->credits, server->in_flight,
++                            credits.value, cifs_trace_rw_credits_write_response_add);
+       add_credits(server, &credits, 0);
+ }
+@@ -4972,7 +4998,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
+                               min_t(int, server->max_credits -
+                                               server->credits, credit_request));
+-              rc = adjust_credits(server, &wdata->credits, io_parms->length);
++              rc = adjust_credits(server, wdata, cifs_trace_rw_credits_call_writev_adjust);
+               if (rc)
+                       goto async_writev_out;
+@@ -4997,6 +5023,12 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
+       cifs_small_buf_release(req);
+ out:
+       if (rc) {
++              trace_smb3_rw_credits(wdata->rreq->debug_id,
++                                    wdata->subreq.debug_index,
++                                    wdata->credits.value,
++                                    server->credits, server->in_flight,
++                                    -(int)wdata->credits.value,
++                                    cifs_trace_rw_credits_write_response_clear);
+               add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
+               cifs_write_subrequest_terminated(wdata, rc, true);
+       }
+diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
+index 36d47ce596317..36d5295c2a6f9 100644
+--- a/fs/smb/client/trace.h
++++ b/fs/smb/client/trace.h
+@@ -20,6 +20,22 @@
+ /*
+  * Specify enums for tracing information.
+  */
++#define smb3_rw_credits_traces \
++      EM(cifs_trace_rw_credits_call_readv_adjust,     "rd-call-adj") \
++      EM(cifs_trace_rw_credits_call_writev_adjust,    "wr-call-adj") \
++      EM(cifs_trace_rw_credits_free_subreq,           "free-subreq") \
++      EM(cifs_trace_rw_credits_issue_read_adjust,     "rd-issu-adj") \
++      EM(cifs_trace_rw_credits_issue_write_adjust,    "wr-issu-adj") \
++      EM(cifs_trace_rw_credits_no_adjust_up,          "no-adj-up  ") \
++      EM(cifs_trace_rw_credits_old_session,           "old-session") \
++      EM(cifs_trace_rw_credits_read_response_add,     "rd-resp-add") \
++      EM(cifs_trace_rw_credits_read_response_clear,   "rd-resp-clr") \
++      EM(cifs_trace_rw_credits_read_submit,           "rd-submit  ") \
++      EM(cifs_trace_rw_credits_write_prepare,         "wr-prepare ") \
++      EM(cifs_trace_rw_credits_write_response_add,    "wr-resp-add") \
++      EM(cifs_trace_rw_credits_write_response_clear,  "wr-resp-clr") \
++      E_(cifs_trace_rw_credits_zero_in_flight,        "ZERO-IN-FLT")
++
+ #define smb3_tcon_ref_traces                                        \
+       EM(netfs_trace_tcon_ref_dec_dfs_refer,          "DEC DfsRef") \
+       EM(netfs_trace_tcon_ref_free,                   "FRE       ") \
+@@ -59,7 +75,8 @@
+ #define EM(a, b) a,
+ #define E_(a, b) a
+-enum smb3_tcon_ref_trace { smb3_tcon_ref_traces } __mode(byte);
++enum smb3_rw_credits_trace    { smb3_rw_credits_traces } __mode(byte);
++enum smb3_tcon_ref_trace      { smb3_tcon_ref_traces } __mode(byte);
+ #undef EM
+ #undef E_
+@@ -71,6 +88,7 @@ enum smb3_tcon_ref_trace { smb3_tcon_ref_traces } __mode(byte);
+ #define EM(a, b) TRACE_DEFINE_ENUM(a);
+ #define E_(a, b) TRACE_DEFINE_ENUM(a);
++smb3_rw_credits_traces;
+ smb3_tcon_ref_traces;
+ #undef EM
+@@ -1316,6 +1334,41 @@ TRACE_EVENT(smb3_tcon_ref,
+                     __entry->ref)
+           );
++TRACE_EVENT(smb3_rw_credits,
++          TP_PROTO(unsigned int rreq_debug_id,
++                   unsigned int subreq_debug_index,
++                   unsigned int subreq_credits,
++                   unsigned int server_credits,
++                   int server_in_flight,
++                   int credit_change,
++                   enum smb3_rw_credits_trace trace),
++          TP_ARGS(rreq_debug_id, subreq_debug_index, subreq_credits,
++                  server_credits, server_in_flight, credit_change, trace),
++          TP_STRUCT__entry(
++                  __field(unsigned int, rreq_debug_id)
++                  __field(unsigned int, subreq_debug_index)
++                  __field(unsigned int, subreq_credits)
++                  __field(unsigned int, server_credits)
++                  __field(int,          in_flight)
++                  __field(int,          credit_change)
++                  __field(enum smb3_rw_credits_trace, trace)
++                           ),
++          TP_fast_assign(
++                  __entry->rreq_debug_id      = rreq_debug_id;
++                  __entry->subreq_debug_index = subreq_debug_index;
++                  __entry->subreq_credits     = subreq_credits;
++                  __entry->server_credits     = server_credits;
++                  __entry->in_flight          = server_in_flight;
++                  __entry->credit_change      = credit_change;
++                  __entry->trace              = trace;
++                         ),
++          TP_printk("R=%08x[%x] %s cred=%u chg=%d pool=%u ifl=%d",
++                    __entry->rreq_debug_id, __entry->subreq_debug_index,
++                    __print_symbolic(__entry->trace, smb3_rw_credits_traces),
++                    __entry->subreq_credits, __entry->credit_change,
++                    __entry->server_credits, __entry->in_flight)
++          );
++
+ #undef EM
+ #undef E_
+diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
+index 012b9bd069952..adfe0d0587010 100644
+--- a/fs/smb/client/transport.c
++++ b/fs/smb/client/transport.c
+@@ -988,10 +988,10 @@ static void
+ cifs_compound_callback(struct mid_q_entry *mid)
+ {
+       struct TCP_Server_Info *server = mid->server;
+-      struct cifs_credits credits;
+-
+-      credits.value = server->ops->get_credits(mid);
+-      credits.instance = server->reconnect_instance;
++      struct cifs_credits credits = {
++              .value = server->ops->get_credits(mid),
++              .instance = server->reconnect_instance,
++      };
+       add_credits(server, &credits, mid->optype);
+-- 
+2.43.0
+
diff --git a/queue-6.10/dm-suspend-return-erestartsys-instead-of-eintr.patch b/queue-6.10/dm-suspend-return-erestartsys-instead-of-eintr.patch
new file mode 100644 (file)
index 0000000..7421bd6
--- /dev/null
@@ -0,0 +1,48 @@
+From b79c7bdeec796b5a7117ca1f4c949bf70591d793 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 12:38:51 +0200
+Subject: dm suspend: return -ERESTARTSYS instead of -EINTR
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 1e1fd567d32fcf7544c6e09e0e5bc6c650da6e23 ]
+
+This commit changes device mapper, so that it returns -ERESTARTSYS
+instead of -EINTR when it is interrupted by a signal (so that the ioctl
+can be restarted).
+
+The manpage signal(7) says that the ioctl function should be restarted if
+the signal was handled with SA_RESTART.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 13037d6a6f62a..6e15ac4e0845c 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2594,7 +2594,7 @@ static int dm_wait_for_bios_completion(struct mapped_device *md, unsigned int ta
+                       break;
+               if (signal_pending_state(task_state, current)) {
+-                      r = -EINTR;
++                      r = -ERESTARTSYS;
+                       break;
+               }
+@@ -2619,7 +2619,7 @@ static int dm_wait_for_completion(struct mapped_device *md, unsigned int task_st
+                       break;
+               if (signal_pending_state(task_state, current)) {
+-                      r = -EINTR;
++                      r = -ERESTARTSYS;
+                       break;
+               }
+-- 
+2.43.0
+
diff --git a/queue-6.10/platform-surface-aggregator-fix-warning-when-control.patch b/queue-6.10/platform-surface-aggregator-fix-warning-when-control.patch
new file mode 100644 (file)
index 0000000..9ca9865
--- /dev/null
@@ -0,0 +1,65 @@
+From 0db55dc7f29d49fdbbfc9d15ccd77d837f04b80f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Aug 2024 14:46:44 +0200
+Subject: platform/surface: aggregator: Fix warning when controller is
+ destroyed in probe
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maximilian Luz <luzmaximilian@gmail.com>
+
+[ Upstream commit bc923d594db21bee0ead128eb4bb78f7e77467a4 ]
+
+There is a small window in ssam_serial_hub_probe() where the controller
+is initialized but has not been started yet. Specifically, between
+ssam_controller_init() and ssam_controller_start(). Any failure in this
+window, for example caused by a failure of serdev_device_open(),
+currently results in an incorrect warning being emitted.
+
+In particular, any failure in this window results in the controller
+being destroyed via ssam_controller_destroy(). This function checks the
+state of the controller and, in an attempt to validate that the
+controller has been cleanly shut down before we try and deallocate any
+resources, emits a warning if that state is not SSAM_CONTROLLER_STOPPED.
+
+However, since we have only just initialized the controller and have not
+yet started it, its state is SSAM_CONTROLLER_INITIALIZED. Note that this
+is the only point at which the controller has this state, as it will
+change after we start the controller with ssam_controller_start() and
+never revert back. Further, at this point no communication has taken
+place and the sender and receiver threads have not been started yet (and
+we may not even have an open serdev device either).
+
+Therefore, it is perfectly safe to call ssam_controller_destroy() with a
+state of SSAM_CONTROLLER_INITIALIZED. This, however, means that the
+warning currently being emitted is incorrect. Fix it by extending the
+check.
+
+Fixes: c167b9c7e3d6 ("platform/surface: Add Surface Aggregator subsystem")
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Link: https://lore.kernel.org/r/20240811124645.246016-1-luzmaximilian@gmail.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/surface/aggregator/controller.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
+index 7fc602e01487d..7e89f547999b2 100644
+--- a/drivers/platform/surface/aggregator/controller.c
++++ b/drivers/platform/surface/aggregator/controller.c
+@@ -1354,7 +1354,8 @@ void ssam_controller_destroy(struct ssam_controller *ctrl)
+       if (ctrl->state == SSAM_CONTROLLER_UNINITIALIZED)
+               return;
+-      WARN_ON(ctrl->state != SSAM_CONTROLLER_STOPPED);
++      WARN_ON(ctrl->state != SSAM_CONTROLLER_STOPPED &&
++              ctrl->state != SSAM_CONTROLLER_INITIALIZED);
+       /*
+        * Note: New events could still have been received after the previous
+-- 
+2.43.0
+
index 0ac88dd6a1e05a786bc8c2ddedcef65308d8534c..828c6bfaaed4a50d58b068c3d1cb3f868152ae18 100644 (file)
@@ -135,3 +135,13 @@ printk-panic-allow-cpu-backtraces-to-be-written-into.patch
 arm64-fix-kasan-random-tag-seed-initialization.patch
 block-fix-lockdep-warning-in-blk_mq_mark_tag_wait.patch
 drm-amd-display-don-t-register-panel_power_savings-on-oled-panels.patch
+thermal-gov_bang_bang-drop-unnecessary-cooling-devic.patch
+thermal-gov_bang_bang-split-bang_bang_control.patch
+thermal-gov_bang_bang-add-.manage-callback.patch
+thermal-gov_bang_bang-use-governor_data-to-reduce-ov.patch
+cifs-add-a-tracepoint-to-track-credits-involved-in-r.patch
+smb-client-avoid-possible-null-dereference-in-cifs_f.patch
+dm-suspend-return-erestartsys-instead-of-eintr.patch
+wifi-ath12k-use-128-bytes-aligned-iova-in-transmit-p.patch
+platform-surface-aggregator-fix-warning-when-control.patch
+alsa-hda-tas2781-use-correct-endian-conversion.patch
diff --git a/queue-6.10/smb-client-avoid-possible-null-dereference-in-cifs_f.patch b/queue-6.10/smb-client-avoid-possible-null-dereference-in-cifs_f.patch
new file mode 100644 (file)
index 0000000..af112b0
--- /dev/null
@@ -0,0 +1,62 @@
+From 91ee85fb8eaf49b895086f7bb4ce80df52e5911d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2024 20:23:32 +0800
+Subject: smb/client: avoid possible NULL dereference in cifs_free_subrequest()
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit 74c2ab6d653b4c2354df65a7f7f2df1925a40a51 ]
+
+Clang static checker (scan-build) warning:
+       cifsglob.h:line 890, column 3
+       Access to field 'ops' results in a dereference of a null pointer.
+
+Commit 519be989717c ("cifs: Add a tracepoint to track credits involved in
+R/W requests") adds a check for 'rdata->server', and let clang throw this
+warning about NULL dereference.
+
+When 'rdata->credits.value != 0 && rdata->server == NULL' happens,
+add_credits_and_wake_if() will call rdata->server->ops->add_credits().
+This will cause NULL dereference problem. Add a check for 'rdata->server'
+to avoid NULL dereference.
+
+Cc: stable@vger.kernel.org
+Fixes: 69c3c023af25 ("cifs: Implement netfslib hooks")
+Reviewed-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Su Hui <suhui@nfschina.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/file.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
+index b413cfef05422..1fc66bcf49eb4 100644
+--- a/fs/smb/client/file.c
++++ b/fs/smb/client/file.c
+@@ -316,7 +316,7 @@ static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
+ #endif
+       }
+-      if (rdata->credits.value != 0)
++      if (rdata->credits.value != 0) {
+               trace_smb3_rw_credits(rdata->rreq->debug_id,
+                                     rdata->subreq.debug_index,
+                                     rdata->credits.value,
+@@ -324,8 +324,12 @@ static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
+                                     rdata->server ? rdata->server->in_flight : 0,
+                                     -rdata->credits.value,
+                                     cifs_trace_rw_credits_free_subreq);
++              if (rdata->server)
++                      add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
++              else
++                      rdata->credits.value = 0;
++      }
+-      add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
+       if (rdata->have_xid)
+               free_xid(rdata->xid);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.10/thermal-gov_bang_bang-add-.manage-callback.patch b/queue-6.10/thermal-gov_bang_bang-add-.manage-callback.patch
new file mode 100644 (file)
index 0000000..2560d76
--- /dev/null
@@ -0,0 +1,96 @@
+From 71c567b10c8c1606f37f0a28cf80e03a27cd4008 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 16:27:33 +0200
+Subject: thermal: gov_bang_bang: Add .manage() callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 5f64b4a1ab1b0412446d42e1fc2964c2cdb60b27 ]
+
+After recent changes, the Bang-bang governor may not adjust the
+initial configuration of cooling devices to the actual situation.
+
+Namely, if a cooling device bound to a certain trip point starts in
+the "on" state and the thermal zone temperature is below the threshold
+of that trip point, the trip point may never be crossed on the way up
+in which case the state of the cooling device will never be adjusted
+because the thermal core will never invoke the governor's
+.trip_crossed() callback.  [Note that there is no issue if the zone
+temperature is at the trip threshold or above it to start with because
+.trip_crossed() will be invoked then to indicate the start of thermal
+mitigation for the given trip.]
+
+To address this, add a .manage() callback to the Bang-bang governor
+and use it to ensure that all of the thermal instances managed by the
+governor have been initialized properly and the states of all of the
+cooling devices involved have been adjusted to the current zone
+temperature as appropriate.
+
+Fixes: 530c932bdf75 ("thermal: gov_bang_bang: Use .trip_crossed() instead of .throttle()")
+Link: https://lore.kernel.org/linux-pm/1bfbbae5-42b0-4c7d-9544-e98855715294@piie.net/
+Cc: 6.10+ <stable@vger.kernel.org> # 6.10+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Peter Kästle <peter@piie.net>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Link: https://patch.msgid.link/8419356.T7Z3S40VBb@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_bang_bang.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c
+index 87cff3ea77a9d..bc55e0698bfa8 100644
+--- a/drivers/thermal/gov_bang_bang.c
++++ b/drivers/thermal/gov_bang_bang.c
+@@ -26,6 +26,7 @@ static void bang_bang_set_instance_target(struct thermal_instance *instance,
+        * when the trip is crossed on the way down.
+        */
+       instance->target = target;
++      instance->initialized = true;
+       dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
+@@ -80,8 +81,37 @@ static void bang_bang_control(struct thermal_zone_device *tz,
+       }
+ }
++static void bang_bang_manage(struct thermal_zone_device *tz)
++{
++      const struct thermal_trip_desc *td;
++      struct thermal_instance *instance;
++
++      for_each_trip_desc(tz, td) {
++              const struct thermal_trip *trip = &td->trip;
++
++              if (tz->temperature >= td->threshold ||
++                  trip->temperature == THERMAL_TEMP_INVALID ||
++                  trip->type == THERMAL_TRIP_CRITICAL ||
++                  trip->type == THERMAL_TRIP_HOT)
++                      continue;
++
++              /*
++               * If the initial cooling device state is "on", but the zone
++               * temperature is not above the trip point, the core will not
++               * call bang_bang_control() until the zone temperature reaches
++               * the trip point temperature which may be never.  In those
++               * cases, set the initial state of the cooling device to 0.
++               */
++              list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
++                      if (!instance->initialized && instance->trip == trip)
++                              bang_bang_set_instance_target(instance, 0);
++              }
++      }
++}
++
+ static struct thermal_governor thermal_gov_bang_bang = {
+       .name           = "bang_bang",
+       .trip_crossed   = bang_bang_control,
++      .manage         = bang_bang_manage,
+ };
+ THERMAL_GOVERNOR_DECLARE(thermal_gov_bang_bang);
+-- 
+2.43.0
+
diff --git a/queue-6.10/thermal-gov_bang_bang-drop-unnecessary-cooling-devic.patch b/queue-6.10/thermal-gov_bang_bang-drop-unnecessary-cooling-devic.patch
new file mode 100644 (file)
index 0000000..69837db
--- /dev/null
@@ -0,0 +1,59 @@
+From 7f264d9ef29607f68e28313a85b02df8c6e36811 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 May 2024 18:54:01 +0200
+Subject: thermal: gov_bang_bang: Drop unnecessary cooling device target state
+ checks
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 2c637af8a74d9a2a52ee5456a75dd29c8cb52da5 ]
+
+Some cooling device target state checks in bang_bang_control()
+done before setting the new target state are not necessary after
+recent changes, so drop them.
+
+Also avoid updating the target state before checking it for
+unexpected values.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 84248e35d9b6 ("thermal: gov_bang_bang: Split bang_bang_control()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_bang_bang.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c
+index 2a6a651e9d921..b9474c6af72b5 100644
+--- a/drivers/thermal/gov_bang_bang.c
++++ b/drivers/thermal/gov_bang_bang.c
+@@ -57,24 +57,16 @@ static void bang_bang_control(struct thermal_zone_device *tz,
+               if (instance->trip != trip)
+                       continue;
+-              if (instance->target == THERMAL_NO_TARGET)
+-                      instance->target = 0;
+-
+-              if (instance->target != 0 && instance->target != 1) {
++              if (instance->target != 0 && instance->target != 1 &&
++                  instance->target != THERMAL_NO_TARGET)
+                       pr_debug("Unexpected state %ld of thermal instance %s in bang-bang\n",
+                                instance->target, instance->name);
+-                      instance->target = 1;
+-              }
+-
+               /*
+                * Enable the fan when the trip is crossed on the way up and
+                * disable it when the trip is crossed on the way down.
+                */
+-              if (instance->target == 0 && crossed_up)
+-                      instance->target = 1;
+-              else if (instance->target == 1 && !crossed_up)
+-                      instance->target = 0;
++              instance->target = crossed_up;
+               dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
+-- 
+2.43.0
+
diff --git a/queue-6.10/thermal-gov_bang_bang-split-bang_bang_control.patch b/queue-6.10/thermal-gov_bang_bang-split-bang_bang_control.patch
new file mode 100644 (file)
index 0000000..c5f3e4b
--- /dev/null
@@ -0,0 +1,91 @@
+From f9f2d2275908b83d8127e718a2698e1fcec4a888 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 16:26:42 +0200
+Subject: thermal: gov_bang_bang: Split bang_bang_control()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 84248e35d9b60e03df7276627e4e91fbaf80f73d ]
+
+Move the setting of the thermal instance target state from
+bang_bang_control() into a separate function that will be also called
+in a different place going forward.
+
+No intentional functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Peter Kästle <peter@piie.net>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Cc: 6.10+ <stable@vger.kernel.org> # 6.10+
+Link: https://patch.msgid.link/3313587.aeNJFYEL58@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_bang_bang.c | 42 ++++++++++++++++++---------------
+ 1 file changed, 23 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c
+index b9474c6af72b5..87cff3ea77a9d 100644
+--- a/drivers/thermal/gov_bang_bang.c
++++ b/drivers/thermal/gov_bang_bang.c
+@@ -13,6 +13,27 @@
+ #include "thermal_core.h"
++static void bang_bang_set_instance_target(struct thermal_instance *instance,
++                                        unsigned int target)
++{
++      if (instance->target != 0 && instance->target != 1 &&
++          instance->target != THERMAL_NO_TARGET)
++              pr_debug("Unexpected state %ld of thermal instance %s in bang-bang\n",
++                       instance->target, instance->name);
++
++      /*
++       * Enable the fan when the trip is crossed on the way up and disable it
++       * when the trip is crossed on the way down.
++       */
++      instance->target = target;
++
++      dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
++
++      mutex_lock(&instance->cdev->lock);
++      __thermal_cdev_update(instance->cdev);
++      mutex_unlock(&instance->cdev->lock);
++}
++
+ /**
+  * bang_bang_control - controls devices associated with the given zone
+  * @tz: thermal_zone_device
+@@ -54,25 +75,8 @@ static void bang_bang_control(struct thermal_zone_device *tz,
+               tz->temperature, trip->hysteresis);
+       list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
+-              if (instance->trip != trip)
+-                      continue;
+-
+-              if (instance->target != 0 && instance->target != 1 &&
+-                  instance->target != THERMAL_NO_TARGET)
+-                      pr_debug("Unexpected state %ld of thermal instance %s in bang-bang\n",
+-                               instance->target, instance->name);
+-
+-              /*
+-               * Enable the fan when the trip is crossed on the way up and
+-               * disable it when the trip is crossed on the way down.
+-               */
+-              instance->target = crossed_up;
+-
+-              dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
+-
+-              mutex_lock(&instance->cdev->lock);
+-              __thermal_cdev_update(instance->cdev);
+-              mutex_unlock(&instance->cdev->lock);
++              if (instance->trip == trip)
++                      bang_bang_set_instance_target(instance, crossed_up);
+       }
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.10/thermal-gov_bang_bang-use-governor_data-to-reduce-ov.patch b/queue-6.10/thermal-gov_bang_bang-use-governor_data-to-reduce-ov.patch
new file mode 100644 (file)
index 0000000..343b9d2
--- /dev/null
@@ -0,0 +1,113 @@
+From a2255a4d4ad531959dcd058dccf6b6048bbed71d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 16:29:11 +0200
+Subject: thermal: gov_bang_bang: Use governor_data to reduce overhead
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 6e6f58a170ea98e44075b761f2da42a5aec47dfb ]
+
+After running once, the for_each_trip_desc() loop in
+bang_bang_manage() is pure needless overhead because it is not going to
+make any changes unless a new cooling device has been bound to one of
+the trips in the thermal zone or the system is resuming from sleep.
+
+For this reason, make bang_bang_manage() set governor_data for the
+thermal zone and check it upfront to decide whether or not it needs to
+do anything.
+
+However, governor_data needs to be reset in some cases to let
+bang_bang_manage() know that it should walk the trips again, so add an
+.update_tz() callback to the governor and make the core additionally
+invoke it during system resume.
+
+To avoid affecting the other users of that callback unnecessarily, add
+a special notification reason for system resume, THERMAL_TZ_RESUME, and
+also pass it to __thermal_zone_device_update() called during system
+resume for consistency.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Peter Kästle <peter@piie.net>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Cc: 6.10+ <stable@vger.kernel.org> # 6.10+
+Link: https://patch.msgid.link/2285575.iZASKD2KPV@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_bang_bang.c | 18 ++++++++++++++++++
+ drivers/thermal/thermal_core.c  |  3 ++-
+ include/linux/thermal.h         |  1 +
+ 3 files changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c
+index bc55e0698bfa8..daed67d19efb8 100644
+--- a/drivers/thermal/gov_bang_bang.c
++++ b/drivers/thermal/gov_bang_bang.c
+@@ -86,6 +86,10 @@ static void bang_bang_manage(struct thermal_zone_device *tz)
+       const struct thermal_trip_desc *td;
+       struct thermal_instance *instance;
++      /* If the code below has run already, nothing needs to be done. */
++      if (tz->governor_data)
++              return;
++
+       for_each_trip_desc(tz, td) {
+               const struct thermal_trip *trip = &td->trip;
+@@ -107,11 +111,25 @@ static void bang_bang_manage(struct thermal_zone_device *tz)
+                               bang_bang_set_instance_target(instance, 0);
+               }
+       }
++
++      tz->governor_data = (void *)true;
++}
++
++static void bang_bang_update_tz(struct thermal_zone_device *tz,
++                              enum thermal_notify_event reason)
++{
++      /*
++       * Let bang_bang_manage() know that it needs to walk trips after binding
++       * a new cdev and after system resume.
++       */
++      if (reason == THERMAL_TZ_BIND_CDEV || reason == THERMAL_TZ_RESUME)
++              tz->governor_data = NULL;
+ }
+ static struct thermal_governor thermal_gov_bang_bang = {
+       .name           = "bang_bang",
+       .trip_crossed   = bang_bang_control,
+       .manage         = bang_bang_manage,
++      .update_tz      = bang_bang_update_tz,
+ };
+ THERMAL_GOVERNOR_DECLARE(thermal_gov_bang_bang);
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index f2d31bc48f529..b8d889ef4fa5e 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -1715,7 +1715,8 @@ static void thermal_zone_device_resume(struct work_struct *work)
+       tz->suspended = false;
+       thermal_zone_device_init(tz);
+-      __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
++      thermal_governor_update_tz(tz, THERMAL_TZ_RESUME);
++      __thermal_zone_device_update(tz, THERMAL_TZ_RESUME);
+       complete(&tz->resume);
+       tz->resuming = false;
+diff --git a/include/linux/thermal.h b/include/linux/thermal.h
+index f1155c0439c4b..13f88317b81bf 100644
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -55,6 +55,7 @@ enum thermal_notify_event {
+       THERMAL_TZ_BIND_CDEV, /* Cooling dev is bind to the thermal zone */
+       THERMAL_TZ_UNBIND_CDEV, /* Cooling dev is unbind from the thermal zone */
+       THERMAL_INSTANCE_WEIGHT_CHANGED, /* Thermal instance weight changed */
++      THERMAL_TZ_RESUME, /* Thermal zone is resuming after system sleep */
+ };
+ /**
+-- 
+2.43.0
+
diff --git a/queue-6.10/wifi-ath12k-use-128-bytes-aligned-iova-in-transmit-p.patch b/queue-6.10/wifi-ath12k-use-128-bytes-aligned-iova-in-transmit-p.patch
new file mode 100644 (file)
index 0000000..5156eeb
--- /dev/null
@@ -0,0 +1,218 @@
+From cfd305d3c703c0982a9172fb5c2f63dd320c5a3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Aug 2024 18:04:07 +0300
+Subject: wifi: ath12k: use 128 bytes aligned iova in transmit path for WCN7850
+
+From: Baochen Qiang <quic_bqiang@quicinc.com>
+
+[ Upstream commit 38055789d15155109b41602ad719d770af507030 ]
+
+In transmit path, it is likely that the iova is not aligned to PCIe TLP
+max payload size, which is 128 for WCN7850. Normally in such cases hardware
+is expected to split the packet into several parts in a manner such that
+they, other than the first one, have aligned iova. However due to hardware
+limitations, WCN7850 does not behave like that properly with some specific
+unaligned iova in transmit path. This easily results in target hang in a
+KPI transmit test: packet send/receive failure, WMI command send timeout
+etc. Also fatal error seen in PCIe level:
+
+       ...
+       Capabilities: ...
+               ...
+               DevSta: ... FatalErr+ ...
+               ...
+       ...
+
+Work around this by manually moving/reallocating payload buffer such that
+we can map it to a 128 bytes aligned iova. The moving requires sufficient
+head room or tail room in skb: for the former we can do ourselves a favor
+by asking some extra bytes when registering with mac80211, while for the
+latter we can do nothing.
+
+Moving/reallocating buffer consumes additional CPU cycles, but the good news
+is that an aligned iova increases PCIe efficiency. In my tests on some X86
+platforms the KPI results are almost consistent.
+
+Since this is seen only with WCN7850, add a new hardware parameter to
+differentiate from others.
+
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Cc: <stable@vger.kernel.org>
+Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://patch.msgid.link/20240715023814.20242-1-quic_bqiang@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_tx.c | 72 +++++++++++++++++++++++++
+ drivers/net/wireless/ath/ath12k/hw.c    |  6 +++
+ drivers/net/wireless/ath/ath12k/hw.h    |  4 ++
+ drivers/net/wireless/ath/ath12k/mac.c   |  1 +
+ 4 files changed, 83 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
+index a7c7a868c14ce..fca9f7e510b41 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
+@@ -124,6 +124,60 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab,
+                                                HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE);
+ }
++static void ath12k_dp_tx_move_payload(struct sk_buff *skb,
++                                    unsigned long delta,
++                                    bool head)
++{
++      unsigned long len = skb->len;
++
++      if (head) {
++              skb_push(skb, delta);
++              memmove(skb->data, skb->data + delta, len);
++              skb_trim(skb, len);
++      } else {
++              skb_put(skb, delta);
++              memmove(skb->data + delta, skb->data, len);
++              skb_pull(skb, delta);
++      }
++}
++
++static int ath12k_dp_tx_align_payload(struct ath12k_base *ab,
++                                    struct sk_buff **pskb)
++{
++      u32 iova_mask = ab->hw_params->iova_mask;
++      unsigned long offset, delta1, delta2;
++      struct sk_buff *skb2, *skb = *pskb;
++      unsigned int headroom = skb_headroom(skb);
++      int tailroom = skb_tailroom(skb);
++      int ret = 0;
++
++      offset = (unsigned long)skb->data & iova_mask;
++      delta1 = offset;
++      delta2 = iova_mask - offset + 1;
++
++      if (headroom >= delta1) {
++              ath12k_dp_tx_move_payload(skb, delta1, true);
++      } else if (tailroom >= delta2) {
++              ath12k_dp_tx_move_payload(skb, delta2, false);
++      } else {
++              skb2 = skb_realloc_headroom(skb, iova_mask);
++              if (!skb2) {
++                      ret = -ENOMEM;
++                      goto out;
++              }
++
++              dev_kfree_skb_any(skb);
++
++              offset = (unsigned long)skb2->data & iova_mask;
++              if (offset)
++                      ath12k_dp_tx_move_payload(skb2, offset, true);
++              *pskb = skb2;
++      }
++
++out:
++      return ret;
++}
++
+ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
+                struct sk_buff *skb)
+ {
+@@ -145,6 +199,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
+       u8 ring_selector, ring_map = 0;
+       bool tcl_ring_retry;
+       bool msdu_ext_desc = false;
++      u32 iova_mask = ab->hw_params->iova_mask;
+       if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
+               return -ESHUTDOWN;
+@@ -240,6 +295,23 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
+               goto fail_remove_tx_buf;
+       }
++      if (iova_mask &&
++          (unsigned long)skb->data & iova_mask) {
++              ret = ath12k_dp_tx_align_payload(ab, &skb);
++              if (ret) {
++                      ath12k_warn(ab, "failed to align TX buffer %d\n", ret);
++                      /* don't bail out, give original buffer
++                       * a chance even unaligned.
++                       */
++                      goto map;
++              }
++
++              /* hdr is pointing to a wrong place after alignment,
++               * so refresh it for later use.
++               */
++              hdr = (void *)skb->data;
++      }
++map:
+       ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
+       if (dma_mapping_error(ab->dev, ti.paddr)) {
+               atomic_inc(&ab->soc_stats.tx_err.misc_fail);
+diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c
+index bff8cf97a18c6..2a92147d15fa1 100644
+--- a/drivers/net/wireless/ath/ath12k/hw.c
++++ b/drivers/net/wireless/ath/ath12k/hw.c
+@@ -922,6 +922,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
+               .supports_sta_ps = false,
+               .acpi_guid = NULL,
++
++              .iova_mask = 0,
+       },
+       {
+               .name = "wcn7850 hw2.0",
+@@ -997,6 +999,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
+               .supports_sta_ps = true,
+               .acpi_guid = &wcn7850_uuid,
++
++              .iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
+       },
+       {
+               .name = "qcn9274 hw2.0",
+@@ -1067,6 +1071,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
+               .supports_sta_ps = false,
+               .acpi_guid = NULL,
++
++              .iova_mask = 0,
+       },
+ };
+diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
+index 2a314cfc8cb84..400bda17e02f6 100644
+--- a/drivers/net/wireless/ath/ath12k/hw.h
++++ b/drivers/net/wireless/ath/ath12k/hw.h
+@@ -96,6 +96,8 @@
+ #define ATH12K_M3_FILE                        "m3.bin"
+ #define ATH12K_REGDB_FILE_NAME                "regdb.bin"
++#define ATH12K_PCIE_MAX_PAYLOAD_SIZE  128
++
+ enum ath12k_hw_rate_cck {
+       ATH12K_HW_RATE_CCK_LP_11M = 0,
+       ATH12K_HW_RATE_CCK_LP_5_5M,
+@@ -214,6 +216,8 @@ struct ath12k_hw_params {
+       bool supports_sta_ps;
+       const guid_t *acpi_guid;
++
++      u32 iova_mask;
+ };
+ struct ath12k_hw_ops {
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index ead37a4e002a2..8474e25d2ac64 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -8737,6 +8737,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
+       hw->vif_data_size = sizeof(struct ath12k_vif);
+       hw->sta_data_size = sizeof(struct ath12k_sta);
++      hw->extra_tx_headroom = ab->hw_params->iova_mask;
+       wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
+       wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
+-- 
+2.43.0
+