From patchwork Thu Jun 17 15:03:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 12328127 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9C9DC49361 for ; Thu, 17 Jun 2021 15:01:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 950A061406 for ; Thu, 17 Jun 2021 15:01:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232943AbhFQPDy (ORCPT ); Thu, 17 Jun 2021 11:03:54 -0400 Received: from mga04.intel.com ([192.55.52.120]:23962 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231992AbhFQPDw (ORCPT ); Thu, 17 Jun 2021 11:03:52 -0400 IronPort-SDR: QKK6XiYqb9ld0s8PFgaeWZQwfmcSRKc58CydSxzsJa18hQQuZx9O8zfa+GqO915w3xGa2Zg3ZA LXNXi+0V/u7w== X-IronPort-AV: E=McAfee;i="6200,9189,10017"; a="204557457" X-IronPort-AV: E=Sophos;i="5.83,280,1616482800"; d="scan'208";a="204557457" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2021 08:01:45 -0700 IronPort-SDR: LeRBiTPhp/BGkQMS3hJYo33k8SZhEgYQ9j4nkPr5dfstEao5G64u+9DraOiJRk8g6n5i+AN80P xr50+w6411hw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,280,1616482800"; d="scan'208";a="479490839" Received: from mattu-haswell.fi.intel.com ([10.237.72.170]) by FMSMGA003.fm.intel.com with ESMTP; 17 Jun 2021 08:01:42 -0700 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 1/4] xhci: Remove unused defines for ERST_SIZE and ERST_ENTRIES Date: Thu, 17 Jun 2021 18:03:51 +0300 Message-Id: <20210617150354.1512157-2-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210617150354.1512157-1-mathias.nyman@linux.intel.com> References: <20210617150354.1512157-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org We don't want those around confusing people. ERST_NUM_SEGS is used both when allocating event ring segments, and when allocating entries in the event ring segment table (erst). Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index a1d5ffb7474d..85ba326806ab 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1663,10 +1663,6 @@ struct urb_priv { * meaning 64 ring segments. * Initial allocated size of the ERST, in number of entries */ #define ERST_NUM_SEGS 1 -/* Initial allocated size of the ERST, in number of entries */ -#define ERST_SIZE 64 -/* Initial number of event segment rings allocated */ -#define ERST_ENTRIES 1 /* Poll every 60 seconds */ #define POLL_TIMEOUT 60 /* Stop endpoint command timeout (secs) for URB cancellation watchdog timer */ From patchwork Thu Jun 17 15:03:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 12328129 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E828C49EA2 for ; Thu, 17 Jun 2021 15:01:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E621561406 for ; Thu, 17 Jun 2021 15:01:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232946AbhFQPDz (ORCPT ); Thu, 17 Jun 2021 11:03:55 -0400 Received: from mga04.intel.com ([192.55.52.120]:23962 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232964AbhFQPDx (ORCPT ); Thu, 17 Jun 2021 11:03:53 -0400 IronPort-SDR: 0uUOEHKw3/c5RrZ4SuXdrqNFpbBY3xXvjRXaIg1MFU9HGNwU6Rsey3YAohPo1g1rhwOnM1uE01 mlkrTkg13gRQ== X-IronPort-AV: E=McAfee;i="6200,9189,10017"; a="204557459" X-IronPort-AV: E=Sophos;i="5.83,280,1616482800"; d="scan'208";a="204557459" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2021 08:01:45 -0700 IronPort-SDR: h7pnAAPleQ2VSFCJP6jzzml/5H02gMnoW8ObGss22lrkxZIMfdIZEAP9CdwsQC5ENwdEzPyh4N a7RE4BEbMqSA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,280,1616482800"; d="scan'208";a="479490848" Received: from mattu-haswell.fi.intel.com ([10.237.72.170]) by FMSMGA003.fm.intel.com with ESMTP; 17 Jun 2021 08:01:44 -0700 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 2/4] xhci: Add adaptive interrupt rate for isoch TRBs with XHCI_AVOID_BEI quirk Date: Thu, 17 Jun 2021 18:03:52 +0300 Message-Id: <20210617150354.1512157-3-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210617150354.1512157-1-mathias.nyman@linux.intel.com> References: <20210617150354.1512157-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Save a bit of power by not interrupting so often by default if XHCI_AVOID_BEI quirk is set. In normal cases the xhci driver will only generate an interrupt on the last isochronous TRB of an URB. In a common UVC webcam usecase there are 32 TRBs per URB. if AVOID_BEI flag is set then xhci driver will force an interrupt every 8th isoc TRB to make sure the event ring doesn't get too full. This is however way too frequent in common single webcam use cases, causing 1000 interrupts/sec and thus poor powermanagement performance. Instead start with interrupting every 32 isoc TRB, and halve it in case event ring becomes half-full. Stop halving when reaching a rate of every 8th trb. This is a one way solution. If interrupt rate is increased it will stay high until driver is reloaded. The highest rate is the same as the old default rate. Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mem.c | 2 ++ drivers/usb/host/xhci-ring.c | 7 ++++++- drivers/usb/host/xhci.h | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index f66815fe8482..2f6da35e7977 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2547,6 +2547,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Wrote ERST address to ir_set 0."); + xhci->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX; + /* * XXX: Might need to set the Interrupter Moderation Register to * something other than the default (~1ms minimum between interrupts). diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6acd2329e08d..8fea44bbc266 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3076,6 +3076,11 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) if (event_loop++ < TRBS_PER_SEGMENT / 2) continue; xhci_update_erst_dequeue(xhci, event_ring_deq); + + /* ring is half-full, force isoc trbs to interrupt more often */ + if (xhci->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN) + xhci->isoc_bei_interval = xhci->isoc_bei_interval / 2; + event_loop = 0; } @@ -3956,7 +3961,7 @@ static bool trb_block_event_intr(struct xhci_hcd *xhci, int num_tds, int i) * generate an event at least every 8th TD to clear the event ring */ if (i && xhci->quirks & XHCI_AVOID_BEI) - return !!(i % 8); + return !!(i % xhci->isoc_bei_interval); return true; } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 85ba326806ab..5ba01d5ccab8 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1526,6 +1526,12 @@ static inline const char *xhci_trb_type_string(u8 type) #define TRB_BUFF_LEN_UP_TO_BOUNDARY(addr) (TRB_MAX_BUFF_SIZE - \ (addr & (TRB_MAX_BUFF_SIZE - 1))) #define MAX_SOFT_RETRY 3 +/* + * Limits of consecutive isoc trbs that can Block Event Interrupt (BEI) if + * XHCI_AVOID_BEI quirk is in use. + */ +#define AVOID_BEI_INTERVAL_MIN 8 +#define AVOID_BEI_INTERVAL_MAX 32 struct xhci_segment { union xhci_trb *trbs; @@ -1768,6 +1774,7 @@ struct xhci_hcd { u8 isoc_threshold; /* imod_interval in ns (I * 250ns) */ u32 imod_interval; + u32 isoc_bei_interval; int event_ring_max; /* 4KB min, 128MB max */ int page_size; From patchwork Thu Jun 17 15:03:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 12328131 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 47469C2B9F4 for ; Thu, 17 Jun 2021 15:01:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 26D3961406 for ; Thu, 17 Jun 2021 15:01:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233015AbhFQPD5 (ORCPT ); Thu, 17 Jun 2021 11:03:57 -0400 Received: from mga14.intel.com ([192.55.52.115]:4084 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232973AbhFQPDz (ORCPT ); Thu, 17 Jun 2021 11:03:55 -0400 IronPort-SDR: paL5nm4e3bKzdoyj7Zhhn1hyJMTVnAUDpKkipHKZiuevbUcdPudHRh9lw1QDZ1vD8/Ugx+dKO7 3zJWndGXEE3Q== X-IronPort-AV: E=McAfee;i="6200,9189,10017"; a="206204838" X-IronPort-AV: E=Sophos;i="5.83,280,1616482800"; d="scan'208";a="206204838" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2021 08:01:46 -0700 IronPort-SDR: tBF7LmQgVHjL3ztUF/DaFbdCZtuXtyC8+neG28+QMsKATEOYBkLsM8nWBNKcYEoKJZ1Fq+GyJJ 0en6SuUePkCg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,280,1616482800"; d="scan'208";a="479490859" Received: from mattu-haswell.fi.intel.com ([10.237.72.170]) by FMSMGA003.fm.intel.com with ESMTP; 17 Jun 2021 08:01:45 -0700 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 3/4] xhci: handle failed buffer copy to URB sg list and fix a W=1 copiler warning Date: Thu, 17 Jun 2021 18:03:53 +0300 Message-Id: <20210617150354.1512157-4-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210617150354.1512157-1-mathias.nyman@linux.intel.com> References: <20210617150354.1512157-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Set the urb->actual_length to bytes successfully copied in case all bytes weren't copied from a temporary buffer to the URB sg list. Also print a debug message Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 27283654ca08..9248ce8d09a4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1361,12 +1361,17 @@ static void xhci_unmap_temp_buf(struct usb_hcd *hcd, struct urb *urb) urb->transfer_buffer_length, dir); - if (usb_urb_dir_in(urb)) + if (usb_urb_dir_in(urb)) { len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, urb->transfer_buffer, buf_len, 0); - + if (len != buf_len) { + xhci_dbg(hcd_to_xhci(hcd), + "Copy from tmp buf to urb sg list failed\n"); + urb->actual_length = len; + } + } urb->transfer_flags &= ~URB_DMA_MAP_SINGLE; kfree(urb->transfer_buffer); urb->transfer_buffer = NULL; From patchwork Thu Jun 17 15:03:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 12328133 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B8754C49EA3 for ; Thu, 17 Jun 2021 15:01:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A2FDD610A5 for ; Thu, 17 Jun 2021 15:01:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232827AbhFQPD7 (ORCPT ); Thu, 17 Jun 2021 11:03:59 -0400 Received: from mga14.intel.com ([192.55.52.115]:4084 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232992AbhFQPD5 (ORCPT ); Thu, 17 Jun 2021 11:03:57 -0400 IronPort-SDR: PgW8vbWx0dOYmwhHmAuaDpqgK1hlDEmDoZYI/Si8YB3O4ie79GWBvzfFqWpIJpEKESH5gcxg3s GgFSaP4KfIEw== X-IronPort-AV: E=McAfee;i="6200,9189,10017"; a="206204845" X-IronPort-AV: E=Sophos;i="5.83,280,1616482800"; d="scan'208";a="206204845" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2021 08:01:49 -0700 IronPort-SDR: m+D+iwYW9+M+cxiIAwGg0XL2LSOI5Kf4OAb7y4dRZfFuMWBtFi+e+q6tMJaqquw1qeL7U0/lJm XkZCtkBLRk0Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,280,1616482800"; d="scan'208";a="479490865" Received: from mattu-haswell.fi.intel.com ([10.237.72.170]) by FMSMGA003.fm.intel.com with ESMTP; 17 Jun 2021 08:01:47 -0700 From: Mathias Nyman To: Cc: , "Zhangjiantao (Kirin, nanjing)" , stable@vger.kernel.org, Tao Xue , Mathias Nyman Subject: [PATCH 4/4] xhci: solve a double free problem while doing s4 Date: Thu, 17 Jun 2021 18:03:54 +0300 Message-Id: <20210617150354.1512157-5-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210617150354.1512157-1-mathias.nyman@linux.intel.com> References: <20210617150354.1512157-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org From: "Zhangjiantao (Kirin, nanjing)" when system is doing s4, the process of xhci_resume may be as below: 1、xhci_mem_cleanup 2、xhci_init->xhci_mem_init->xhci_mem_cleanup(when memory is not enough). xhci_mem_cleanup will be executed twice when system is out of memory. xhci->port_caps is freed in xhci_mem_cleanup,but it isn't set to NULL. It will be freed twice when xhci_mem_cleanup is called the second time. We got following bug when system resumes from s4: kernel BUG at mm/slub.c:309! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP CPU: 0 PID: 5929 Tainted: G S W 5.4.96-arm64-desktop #1 pc : __slab_free+0x5c/0x424 lr : kfree+0x30c/0x32c Call trace: __slab_free+0x5c/0x424 kfree+0x30c/0x32c xhci_mem_cleanup+0x394/0x3cc xhci_mem_init+0x9ac/0x1070 xhci_init+0x8c/0x1d0 xhci_resume+0x1cc/0x5fc xhci_plat_resume+0x64/0x70 platform_pm_thaw+0x28/0x60 dpm_run_callback+0x54/0x24c device_resume+0xd0/0x200 async_resume+0x24/0x60 async_run_entry_fn+0x44/0x110 process_one_work+0x1f0/0x490 worker_thread+0x5c/0x450 kthread+0x158/0x160 ret_from_fork+0x10/0x24 Original patch that caused this issue was backported to 4.4 stable, so this should be backported to 4.4 stabe as well. Fixes: cf0ee7c60c89 ("xhci: Fix memory leak when caching protocol extended capability PSI tables - take 2") Cc: stable@vger.kernel.org # v4.4+ Signed-off-by: Jiantao Zhang Signed-off-by: Tao Xue Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 2f6da35e7977..0e312066c5c6 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1924,6 +1924,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->hw_ports = NULL; xhci->rh_bw = NULL; xhci->ext_caps = NULL; + xhci->port_caps = NULL; xhci->page_size = 0; xhci->page_shift = 0;