Message ID | ebd9ea7d0ebb1884b15e4fe7e3e03460c1e3c52b.1585094538.git.asutoshd@codeaurora.org (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | [v1,1/3] scsi: ufshcd: Update the set frequency to devfreq | expand |
> > Currently, the frequency that devfreq provides the > driver to set always leads the clocks to be scaled up. > Hence, round the clock-rate to the nearest frequency > before deciding to scale. > > Also update the devfreq statistics of current frequency. > > Signed-off-by: Asutosh Das <asutoshd@codeaurora.org> > --- > drivers/scsi/ufs/ufshcd.c | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c > index 2a2a63b..4607bc6 100644 > --- a/drivers/scsi/ufs/ufshcd.c > +++ b/drivers/scsi/ufs/ufshcd.c > @@ -1187,6 +1187,9 @@ static int ufshcd_devfreq_target(struct device > *dev, > if (!ufshcd_is_clkscaling_supported(hba)) > return -EINVAL; > > + clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); > + /* Override with the closest supported frequency */ > + *freq = (unsigned long) clk_round_rate(clki->clk, *freq); > spin_lock_irqsave(hba->host->host_lock, irq_flags); Please remind me what the spin lock is protecting here? > if (ufshcd_eh_in_progress(hba)) { > spin_unlock_irqrestore(hba->host->host_lock, irq_flags); > @@ -1201,8 +1204,13 @@ static int ufshcd_devfreq_target(struct device > *dev, > goto out; > } > > - clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); > + /* Decide based on the rounded-off frequency and update */ > scale_up = (*freq == clki->max_freq) ? true : false; > + if (scale_up) > + *freq = clki->max_freq; This was already established 2 lines above ? > + else > + *freq = clki->min_freq; > + /* Update the frequency */ > if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) { > spin_unlock_irqrestore(hba->host->host_lock, irq_flags); > ret = 0; > @@ -1250,6 +1258,8 @@ static int ufshcd_devfreq_get_dev_status(struct > device *dev, > struct ufs_hba *hba = dev_get_drvdata(dev); > struct ufs_clk_scaling *scaling = &hba->clk_scaling; > unsigned long flags; > + struct list_head *clk_list = &hba->clk_list_head; > + struct ufs_clk_info *clki; > > if (!ufshcd_is_clkscaling_supported(hba)) > return -EINVAL; > @@ -1260,6 +1270,8 @@ static int ufshcd_devfreq_get_dev_status(struct > device *dev, > if (!scaling->window_start_t) > goto start_window; > > + clki = list_first_entry(clk_list, struct ufs_clk_info, list); > + stat->current_frequency = clki->curr_freq; Is this a bug fix? devfreq_simple_ondemand_func is trying to establish the busy period, but also uses the frequency in its calculation - which I wasn't able to understand how. Can you add a short comment why updating current_frequency is needed? Thanks, Avri
On 3/25/2020 6:11 AM, Avri Altman wrote: >> >> Currently, the frequency that devfreq provides the >> driver to set always leads the clocks to be scaled up. >> Hence, round the clock-rate to the nearest frequency >> before deciding to scale. >> >> Also update the devfreq statistics of current frequency. >> >> Signed-off-by: Asutosh Das <asutoshd@codeaurora.org> >> --- >> drivers/scsi/ufs/ufshcd.c | 14 +++++++++++++- >> 1 file changed, 13 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c >> index 2a2a63b..4607bc6 100644 >> --- a/drivers/scsi/ufs/ufshcd.c >> +++ b/drivers/scsi/ufs/ufshcd.c >> @@ -1187,6 +1187,9 @@ static int ufshcd_devfreq_target(struct device >> *dev, >> if (!ufshcd_is_clkscaling_supported(hba)) >> return -EINVAL; >> >> + clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); >> + /* Override with the closest supported frequency */ >> + *freq = (unsigned long) clk_round_rate(clki->clk, *freq); >> spin_lock_irqsave(hba->host->host_lock, irq_flags); > Please remind me what the spin lock is protecting here? Hmmm ... Nothing comes to my mind. I blamed it but it's a part of a bigger change. > >> if (ufshcd_eh_in_progress(hba)) { >> spin_unlock_irqrestore(hba->host->host_lock, irq_flags); >> @@ -1201,8 +1204,13 @@ static int ufshcd_devfreq_target(struct device >> *dev, >> goto out; >> } >> >> - clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); >> + /* Decide based on the rounded-off frequency and update */ >> scale_up = (*freq == clki->max_freq) ? true : false; >> + if (scale_up) >> + *freq = clki->max_freq; > This was already established 2 lines above ? Good point - I'll change it. > >> + else >> + *freq = clki->min_freq; >> + /* Update the frequency */ >> if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) { >> spin_unlock_irqrestore(hba->host->host_lock, irq_flags); >> ret = 0; >> @@ -1250,6 +1258,8 @@ static int ufshcd_devfreq_get_dev_status(struct >> device *dev, >> struct ufs_hba *hba = dev_get_drvdata(dev); >> struct ufs_clk_scaling *scaling = &hba->clk_scaling; >> unsigned long flags; >> + struct list_head *clk_list = &hba->clk_list_head; >> + struct ufs_clk_info *clki; >> >> if (!ufshcd_is_clkscaling_supported(hba)) >> return -EINVAL; >> @@ -1260,6 +1270,8 @@ static int ufshcd_devfreq_get_dev_status(struct >> device *dev, >> if (!scaling->window_start_t) >> goto start_window; >> >> + clki = list_first_entry(clk_list, struct ufs_clk_info, list); >> + stat->current_frequency = clki->curr_freq; > Is this a bug fix? > devfreq_simple_ondemand_func is trying to establish the busy period, > but also uses the frequency in its calculation - which I wasn't able to understand how. > Can you add a short comment why updating current_frequency is needed? > Sure - I'll add a comment. If stat->current_frequency is not updated, the governor would always ask to set the max freq because the initial frequency was unknown to it. Reference - devfreq_simple_ondemand_func(...) > > Thanks, > Avri > Thanks, -asd
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 2a2a63b..4607bc6 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1187,6 +1187,9 @@ static int ufshcd_devfreq_target(struct device *dev, if (!ufshcd_is_clkscaling_supported(hba)) return -EINVAL; + clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); + /* Override with the closest supported frequency */ + *freq = (unsigned long) clk_round_rate(clki->clk, *freq); spin_lock_irqsave(hba->host->host_lock, irq_flags); if (ufshcd_eh_in_progress(hba)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); @@ -1201,8 +1204,13 @@ static int ufshcd_devfreq_target(struct device *dev, goto out; } - clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list); + /* Decide based on the rounded-off frequency and update */ scale_up = (*freq == clki->max_freq) ? true : false; + if (scale_up) + *freq = clki->max_freq; + else + *freq = clki->min_freq; + /* Update the frequency */ if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ret = 0; @@ -1250,6 +1258,8 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_clk_scaling *scaling = &hba->clk_scaling; unsigned long flags; + struct list_head *clk_list = &hba->clk_list_head; + struct ufs_clk_info *clki; if (!ufshcd_is_clkscaling_supported(hba)) return -EINVAL; @@ -1260,6 +1270,8 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, if (!scaling->window_start_t) goto start_window; + clki = list_first_entry(clk_list, struct ufs_clk_info, list); + 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));
Currently, the frequency that devfreq provides the driver to set always leads the clocks to be scaled up. Hence, round the clock-rate to the nearest frequency before deciding to scale. Also update the devfreq statistics of current frequency. Signed-off-by: Asutosh Das <asutoshd@codeaurora.org> --- drivers/scsi/ufs/ufshcd.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)