Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp2807450pxu; Mon, 14 Dec 2020 11:19:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJyC7Uu2M2GKKXE51Hm/lKTpRJJqVlc/ayGbADJW/k8CzA3RAWPhT1RzGRh+nweAj/B2yeGO X-Received: by 2002:a50:d6d3:: with SMTP id l19mr26346109edj.340.1607973579852; Mon, 14 Dec 2020 11:19:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1607973579; cv=none; d=google.com; s=arc-20160816; b=ZV7eFqjIXk4lh5dM9PNLeFacLIvX1rwcHxMVSya5RwdzEGbGz1VkppWfyVQG7foGUF rGUw6bMQsER1QyIz9+rLt79Edma22VvE78UuxS+T/BPwzLsivu6UrIRuYKntbezi12ht bmEJ0WoPpy5n1nmGg/Ksor7hmqDkHKII2NWKZCH7552jYLZiPyfspKoVB6KnWWfn4zwY uHmYmifw9PIhGzpXOSAWpJuviBqbF04m33HSU1VgNQYM3AKjSHipCZqPF7ekltivK9+F wi+wiBR20YwWtMSY5v7w+tTCrkyhOLOdQXdrld43fc+LLF/wfQfr5tTFiCOA2TfweKCk jFrA== 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; bh=EA2aOy5cvYKOSoxEo5NaE3GGBskK/urbNIGrJKPtoj8=; b=aMNOzEmVEGNAODtCVOMIKuhEHFeTGsWNTBlW6zB+ZK6sle1Jq/54iuajjmJa//IRdH 6lJoS4XCFf9KtZ3JaYuxr4SKmDtmdvgsdVbH8BLCZOg3yr15lma3Xe5bmECGtZmSsBvE NDe75zM0RP79DQnK2RlJEMjCZjr/3wJUfRCOOPt/bGecXeXXceW0Jz+BOTflD1S4Oez9 khVHAPdQZwf93IMLKCzq4wPuzBHvtKVLseIryKbKBHpVJssyzHgfu8yLJF/vVITGK3Ec Olpsxf2VhjHrSs1uciFAk1Np8nHm+uiz41DMgxhRvRv9bGvsCdD9pd8/PPeJFxgdqXYe aUjg== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (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 j10si10336170ejf.404.2020.12.14.11.19.15; Mon, 14 Dec 2020 11:19:39 -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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2502334AbgLNTF7 (ORCPT + 99 others); Mon, 14 Dec 2020 14:05:59 -0500 Received: from mail.kernel.org ([198.145.29.99]:47654 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2502194AbgLNRh3 (ORCPT ); Mon, 14 Dec 2020 12:37:29 -0500 From: Greg Kroah-Hartman Authentication-Results: mail.kernel.org; dkim=permerror (bad message/signature format) 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 5.9 040/105] iwlwifi: pcie: limit memory read spin time Date: Mon, 14 Dec 2020 18:28:14 +0100 Message-Id: <20201214172557.208545474@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201214172555.280929671@linuxfoundation.org> References: <20201214172555.280929671@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 e5160d6208688..6393e895f95c6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2155,18 +2155,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