From: Sasha Levin Date: Fri, 23 Aug 2024 00:12:52 +0000 (-0400) Subject: Fixes for 6.10 X-Git-Tag: v6.1.107~82 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=10d44bfb2e1f405d6ab8f1bab559aa46eb05a5d9;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.10 Signed-off-by: Sasha Levin --- 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 index 00000000000..f9ef2d38132 --- /dev/null +++ b/queue-6.10/alsa-hda-tas2781-use-correct-endian-conversion.patch @@ -0,0 +1,44 @@ +From 6030d4306f4dfb8ecf9a711dbbbc29a3e3f86d98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Aug 2024 12:04:59 +0200 +Subject: ALSA: hda/tas2781: Use correct endian conversion + +From: Takashi Iwai + +[ 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 +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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ac50755ac18 --- /dev/null +++ b/queue-6.10/cifs-add-a-tracepoint-to-track-credits-involved-in-r.patch @@ -0,0 +1,475 @@ +From 73ca5c8a33f52f8068f04f18ba1fc903e7871326 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Paulo Alcantara (Red Hat) +cc: Jeff Layton +cc: linux-cifs@vger.kernel.org +cc: netfs@lists.linux.dev +cc: linux-fsdevel@vger.kernel.org +Signed-off-by: Steve French +Stable-dep-of: 74c2ab6d653b ("smb/client: avoid possible NULL dereference in cifs_free_subrequest()") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..7421bd6ef76 --- /dev/null +++ b/queue-6.10/dm-suspend-return-erestartsys-instead-of-eintr.patch @@ -0,0 +1,48 @@ +From b79c7bdeec796b5a7117ca1f4c949bf70591d793 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Aug 2024 12:38:51 +0200 +Subject: dm suspend: return -ERESTARTSYS instead of -EINTR + +From: Mikulas Patocka + +[ 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 +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..9ca986543e7 --- /dev/null +++ b/queue-6.10/platform-surface-aggregator-fix-warning-when-control.patch @@ -0,0 +1,65 @@ +From 0db55dc7f29d49fdbbfc9d15ccd77d837f04b80f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20240811124645.246016-1-luzmaximilian@gmail.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.10/series b/queue-6.10/series index 0ac88dd6a1e..828c6bfaaed 100644 --- a/queue-6.10/series +++ b/queue-6.10/series @@ -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 index 00000000000..af112b0fc1c --- /dev/null +++ b/queue-6.10/smb-client-avoid-possible-null-dereference-in-cifs_f.patch @@ -0,0 +1,62 @@ +From 91ee85fb8eaf49b895086f7bb4ce80df52e5911d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Aug 2024 20:23:32 +0800 +Subject: smb/client: avoid possible NULL dereference in cifs_free_subrequest() + +From: Su Hui + +[ 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 +Signed-off-by: Su Hui +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2560d7693be --- /dev/null +++ b/queue-6.10/thermal-gov_bang_bang-add-.manage-callback.patch @@ -0,0 +1,96 @@ +From 71c567b10c8c1606f37f0a28cf80e03a27cd4008 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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+ # 6.10+ +Signed-off-by: Rafael J. Wysocki +Acked-by: Peter Kästle +Reviewed-by: Zhang Rui +Link: https://patch.msgid.link/8419356.T7Z3S40VBb@rjwysocki.net +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..69837db058e --- /dev/null +++ b/queue-6.10/thermal-gov_bang_bang-drop-unnecessary-cooling-devic.patch @@ -0,0 +1,59 @@ +From 7f264d9ef29607f68e28313a85b02df8c6e36811 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Stable-dep-of: 84248e35d9b6 ("thermal: gov_bang_bang: Split bang_bang_control()") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c5f3e4b9fc6 --- /dev/null +++ b/queue-6.10/thermal-gov_bang_bang-split-bang_bang_control.patch @@ -0,0 +1,91 @@ +From f9f2d2275908b83d8127e718a2698e1fcec4a888 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Peter Kästle +Reviewed-by: Zhang Rui +Cc: 6.10+ # 6.10+ +Link: https://patch.msgid.link/3313587.aeNJFYEL58@rjwysocki.net +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..343b9d26d6f --- /dev/null +++ b/queue-6.10/thermal-gov_bang_bang-use-governor_data-to-reduce-ov.patch @@ -0,0 +1,113 @@ +From a2255a4d4ad531959dcd058dccf6b6048bbed71d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Peter Kästle +Reviewed-by: Zhang Rui +Cc: 6.10+ # 6.10+ +Link: https://patch.msgid.link/2285575.iZASKD2KPV@rjwysocki.net +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..5156eeb5b1f --- /dev/null +++ b/queue-6.10/wifi-ath12k-use-128-bytes-aligned-iova-in-transmit-p.patch @@ -0,0 +1,218 @@ +From cfd305d3c703c0982a9172fb5c2f63dd320c5a3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: +Tested-by: Mark Pearson +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20240715023814.20242-1-quic_bqiang@quicinc.com +Signed-off-by: Sasha Levin +--- + 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 +