From mboxrd@z Thu Jan 1 00:00:00 1970 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=-12.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,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 6723CC433DF for ; Mon, 17 Aug 2020 19:02:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 499732072D for ; Mon, 17 Aug 2020 19:02:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597690946; bh=tCeRoaRe2xPSsMOAuWeOZ6tvJVbEv7DCv9nGGGaLoUU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=iPbiyRyi6MpKTKs6JJPwlqSKyDCNwEnhmKIfw8ZE8uSjnqmGc8kxnAON71vpOgsFo O7kgs8reNMXV50itDiJGhaPzCTgqPy9ZhgvtVJ8DlUxEtLtsIYlzo/skFfbaBT752d mM7qvaNTwk35nPsDtT1WYRZJGrj6fclzJ3ZUgd5Q= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730259AbgHQTCV (ORCPT ); Mon, 17 Aug 2020 15:02:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:59370 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730817AbgHQPrV (ORCPT ); Mon, 17 Aug 2020 11:47:21 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1D31B2177B; Mon, 17 Aug 2020 15:47:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597679236; bh=tCeRoaRe2xPSsMOAuWeOZ6tvJVbEv7DCv9nGGGaLoUU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WuesfTqliRUWyZjyQ2P8DQlwx4Fp5aeBBVm3DRyxn/oqUFckMtIQ2zX5H8S2fDnXG bmaEFrqpuMg8p5K+P83/YfjS4GcIFrHnjOrPSqBbSG8AROclyteVwzwvr+rMXjal3x gT4D/4fK7AFXWw673BvNtuBPyI43zD0tq5sMi3mM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Avri Altman , Stanley Chu , "Martin K. Petersen" , Sasha Levin Subject: [PATCH 5.7 142/393] scsi: ufs: Fix imprecise load calculation in devfreq window Date: Mon, 17 Aug 2020 17:13:12 +0200 Message-Id: <20200817143826.498070174@linuxfoundation.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200817143819.579311991@linuxfoundation.org> References: <20200817143819.579311991@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Stanley Chu [ Upstream commit b1bf66d1d5a8fcb54f0e584db5d196ef015b5172 ] The UFS load calculation is based on "total_time" and "busy_time" in a devfreq window. However, the source of time is different for both parameters: "busy_time" is assigned from "jiffies" thus has different accuracy from "total_time" which is assigned from ktime_get(). In addition, the time of window boundary is not exactly the same as the starting busy time in this window if UFS is actually busy in the beginning of the window. A similar accuracy error may also happen for the end of busy time in current window. To guarantee the precision of load calculation, we need to 1. Align time accuracy of both devfreq_dev_status.total_time and devfreq_dev_status.busy_time. For example, use "ktime_get()" directly. 2. Align the following timelines: - The beginning time of devfreq windows - The beginning of busy time in a new window - The end of busy time in the current window Link: https://lore.kernel.org/r/20200611101043.6379-1-stanley.chu@mediatek.com Fixes: a3cd5ec55f6c ("scsi: ufs: add load based scaling of UFS gear") Reviewed-by: Avri Altman Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ufs/ufshcd.c | 18 ++++++++++-------- drivers/scsi/ufs/ufshcd.h | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 7ca32ede5e172..477b6cfff381b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1280,6 +1280,7 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, unsigned long flags; struct list_head *clk_list = &hba->clk_list_head; struct ufs_clk_info *clki; + ktime_t curr_t; if (!ufshcd_is_clkscaling_supported(hba)) return -EINVAL; @@ -1287,6 +1288,7 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, memset(stat, 0, sizeof(*stat)); spin_lock_irqsave(hba->host->host_lock, flags); + curr_t = ktime_get(); if (!scaling->window_start_t) goto start_window; @@ -1298,18 +1300,17 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, */ stat->current_frequency = clki->curr_freq; if (scaling->is_busy_started) - scaling->tot_busy_t += ktime_to_us(ktime_sub(ktime_get(), - scaling->busy_start_t)); + scaling->tot_busy_t += ktime_us_delta(curr_t, + scaling->busy_start_t); - stat->total_time = jiffies_to_usecs((long)jiffies - - (long)scaling->window_start_t); + stat->total_time = ktime_us_delta(curr_t, scaling->window_start_t); stat->busy_time = scaling->tot_busy_t; start_window: - scaling->window_start_t = jiffies; + scaling->window_start_t = curr_t; scaling->tot_busy_t = 0; if (hba->outstanding_reqs) { - scaling->busy_start_t = ktime_get(); + scaling->busy_start_t = curr_t; scaling->is_busy_started = true; } else { scaling->busy_start_t = 0; @@ -1860,6 +1861,7 @@ static void ufshcd_exit_clk_gating(struct ufs_hba *hba) static void ufshcd_clk_scaling_start_busy(struct ufs_hba *hba) { bool queue_resume_work = false; + ktime_t curr_t = ktime_get(); if (!ufshcd_is_clkscaling_supported(hba)) return; @@ -1875,13 +1877,13 @@ static void ufshcd_clk_scaling_start_busy(struct ufs_hba *hba) &hba->clk_scaling.resume_work); if (!hba->clk_scaling.window_start_t) { - hba->clk_scaling.window_start_t = jiffies; + hba->clk_scaling.window_start_t = curr_t; hba->clk_scaling.tot_busy_t = 0; hba->clk_scaling.is_busy_started = false; } if (!hba->clk_scaling.is_busy_started) { - hba->clk_scaling.busy_start_t = ktime_get(); + hba->clk_scaling.busy_start_t = curr_t; hba->clk_scaling.is_busy_started = true; } } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 6ffc08ad85f63..2315ecc209272 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -409,7 +409,7 @@ struct ufs_saved_pwr_info { struct ufs_clk_scaling { int active_reqs; unsigned long tot_busy_t; - unsigned long window_start_t; + ktime_t window_start_t; ktime_t busy_start_t; struct device_attribute enable_attr; struct ufs_saved_pwr_info saved_pwr_info; -- 2.25.1