Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp9185160pxu; Mon, 28 Dec 2020 08:42:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJwqM6bYGz8U25p1vIhqYlZEVmaklgJDBoXpMETvisUpR5vZaAUsCUGsDjcklrU6/lgxQHIZ X-Received: by 2002:a17:906:3b4d:: with SMTP id h13mr41982733ejf.289.1609173768854; Mon, 28 Dec 2020 08:42:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609173768; cv=none; d=google.com; s=arc-20160816; b=A4ANT9XwGJL6BPA69WUQOSEOpfi9uO3zUmzW5hoBqrD/z5osJKwtNzAQUFEhr8KyiU KSPRd2jUB3nVvM/g+cvvdOu75SqsJmSKVfGxdMQma1KqRUXinmmc8+A04qVKGfA7jedZ ObeEit1KiHssz0H1zq9KIOlW2th2aVuGVjwRHCPNXBRF2ijz9dQ9UTZ6EIAN+tlgOMWQ cgbhLGmR95CrMKAzLlfsJvOAReU5ObKNTXLXJX5fH49MYFtPy4MEP+tSl8pBCPXe1Zxw BUQHTu0uW5+R/rL2gYFe3FD0+qkmcumZHSCfL9fC7bU9s01mWybBlubZnaPhsuT6W08K rFrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=4uF7ZWv+Id1ExAPm0O+g2pJiUQ7RGc88HKaIdofny8U=; b=aJQaN2HxKI9/VbIncjW/OauUDDb7hvQ+4oq9W/Sz794Hn1niMJ/5i9HZMQdcGfm9uq EudpsqMXjYeogZKbWkuQcJjaA//fL/veFxHPiAAgNL/gEaERG3at7YqRm1WIuedjxPUE 9tYwcYjX/gnmc+uUg4y6GTs569vY5xWeZ/6lJlfthUUqeJVgHyWmrS6uWM29/obcJbUR AqEgJDdrP2wl7lLwq4WI3mrNqSmClyV9gSAw/uZrRZC0sJuQ35UaQsh/+MhDMPJbVa+M GerXurvLXpTi18rRTXbTe60Erayrvof58Flj3ZDTovq+q4kYgzIN0MgVAr0jZ95J506E 20CQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=KSOw5P3F; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 12si13874349edw.403.2020.12.28.08.42.25; Mon, 28 Dec 2020 08:42:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=KSOw5P3F; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2504334AbgL1QkQ (ORCPT + 99 others); Mon, 28 Dec 2020 11:40:16 -0500 Received: from mail.kernel.org ([198.145.29.99]:56030 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728568AbgL1M7s (ORCPT ); Mon, 28 Dec 2020 07:59:48 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id F409C208D5; Mon, 28 Dec 2020 12:59:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609160347; bh=g7Sk3kitM9XQWi6MRdIh2UffTECyyzRKym6NMdbl9n4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KSOw5P3FU/v2rDUtwNeTluMDdOG6Fak/1MqXbabmC2l73UCfGkmpQBATDIieVPFvX GBn2YkFx0PyKbHurDA5ucCH9V/a6Sd6vrImD585wonTcDYbaYRSAKaCAxTd+LwMLDh KCAwqBV/YRKrdGaX22NUSNGStSFMlFhUFxlSJ6vo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Johannes Berg , Mordechay Goodstein , Luca Coelho , Kalle Valo , Sasha Levin Subject: [PATCH 4.9 003/175] iwlwifi: pcie: limit memory read spin time Date: Mon, 28 Dec 2020 13:47:36 +0100 Message-Id: <20201228124853.400932464@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201228124853.216621466@linuxfoundation.org> References: <20201228124853.216621466@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Johannes Berg [ Upstream commit 04516706bb99889986ddfa3a769ed50d2dc7ac13 ] When we read device memory, we lock a spinlock, write the address we want to read from the device and then spin in a loop reading the data in 32-bit quantities from another register. As the description makes clear, this is rather inefficient, incurring a PCIe bus transaction for every read. In a typical device today, we want to read 786k SMEM if it crashes, leading to 192k register reads. Occasionally, we've seen the whole loop take over 20 seconds and then triggering the soft lockup detector. Clearly, it is unreasonable to spin here for such extended periods of time. To fix this, break the loop down into an outer and an inner loop, and break out of the inner loop if more than half a second elapsed. To avoid too much overhead, check for that only every 128 reads, though there's no particular reason for that number. Then, unlock and relock to obtain NIC access again, reprogram the start address and continue. This will keep (interrupt) latencies on the CPU down to a reasonable time. Signed-off-by: Johannes Berg Signed-off-by: Mordechay Goodstein Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/iwlwifi.20201022165103.45878a7e49aa.I3b9b9c5a10002915072312ce75b68ed5b3dc6e14@changeid Signed-off-by: Sasha Levin --- .../net/wireless/intel/iwlwifi/pcie/trans.c | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index e7b873018dca6..e1287c3421165 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1904,18 +1904,36 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, void *buf, int dwords) { unsigned long flags; - int offs, ret = 0; + int offs = 0; u32 *vals = buf; - if (iwl_trans_grab_nic_access(trans, &flags)) { - iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); - for (offs = 0; offs < dwords; offs++) - vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); - iwl_trans_release_nic_access(trans, &flags); - } else { - ret = -EBUSY; + while (offs < dwords) { + /* limit the time we spin here under lock to 1/2s */ + ktime_t timeout = ktime_add_us(ktime_get(), 500 * USEC_PER_MSEC); + + if (iwl_trans_grab_nic_access(trans, &flags)) { + iwl_write32(trans, HBUS_TARG_MEM_RADDR, + addr + 4 * offs); + + while (offs < dwords) { + vals[offs] = iwl_read32(trans, + HBUS_TARG_MEM_RDAT); + offs++; + + /* calling ktime_get is expensive so + * do it once in 128 reads + */ + if (offs % 128 == 0 && ktime_after(ktime_get(), + timeout)) + break; + } + iwl_trans_release_nic_access(trans, &flags); + } else { + return -EBUSY; + } } - return ret; + + return 0; } static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, -- 2.27.0