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: 462642 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: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: 462641 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;