At boot up, CPUfreq core performs a sanity check to see if the system is
running at a frequency defined in the frequency table of the CPU. If so,
we try to find a valid frequency (lowest frequency greater than the
currently programmed frequency) from the table and set it. When the call
reaches dev_pm_opp_set_rate(), it calls _find_freq_ceil(opp_table,
&old_freq) to find the previously configured OPP and this call also
updates the old_freq. This eventually sets the old_freq == freq (new
target requested by cpufreq core) and we skip updating the performance
state in this case.
Fix this by also updating the performance state when the old_freq ==
freq.
Fixes: ca1b5d77b1c6 ("OPP: Configure all required OPPs")
Cc: v5.0 <stable(a)vger.kernel.org> # v5.0
Reported-by: Niklas Cassel <niklas.cassel(a)linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
drivers/opp/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index d7f97167cac3..0420f7e8ad5b 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -760,7 +760,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
old_freq, freq);
/* Scaling up? Configure required OPPs before frequency */
- if (freq > old_freq) {
+ if (freq >= old_freq) {
ret = _set_required_opps(dev, opp_table, opp);
if (ret)
goto put_opp;
--
2.21.0.rc0.269.g1a574e7a288b
This series backports bugfixes already merged in linux upstream
which we found these issues in our commerical products, which
are serious and should be fixed immediately.
Note that it also includes some xarray modification since
upcoming patches heavily needs it, which can reduce more
conflicts later.
All patches have been tested again as a whole.
Thanks,
Gao Xiang
Chen Gong (1):
staging: erofs: replace BUG_ON with DBG_BUGON in data.c
Gao Xiang (11):
staging: erofs: fix a bug when appling cache strategy
staging: erofs: complete error handing of z_erofs_do_read_page
staging: erofs: drop multiref support temporarily
staging: erofs: remove the redundant d_rehash() for the root dentry
staging: erofs: fix race when the managed cache is enabled
staging: erofs: atomic_cond_read_relaxed on ref-locked workgroup
staging: erofs: fix `erofs_workgroup_{try_to_freeze, unfreeze}'
staging: erofs: add a full barrier in erofs_workgroup_unfreeze
staging: erofs: {dir,inode,super}.c: rectify BUG_ONs
staging: erofs: unzip_{pagevec.h,vle.c}: rectify BUG_ONs
staging: erofs: unzip_vle_lz4.c,utils.c: rectify BUG_ONs
drivers/staging/erofs/data.c | 31 ++++---
drivers/staging/erofs/dir.c | 7 +-
drivers/staging/erofs/inode.c | 10 ++-
drivers/staging/erofs/internal.h | 71 ++++++++++------
drivers/staging/erofs/super.c | 19 ++---
drivers/staging/erofs/unzip_pagevec.h | 2 +-
drivers/staging/erofs/unzip_vle.c | 97 ++++++++--------------
drivers/staging/erofs/unzip_vle.h | 12 +--
drivers/staging/erofs/unzip_vle_lz4.c | 2 +-
drivers/staging/erofs/utils.c | 150 +++++++++++++++++++++++-----------
include/linux/xarray.h | 48 +++++++++++
11 files changed, 271 insertions(+), 178 deletions(-)
--
2.14.4
[ Not relevant upstream, therefore no upstream commit. ]
To fix, use jiffies64_to_nsecs() directly instead of deriving the result
according to jiffies_to_usecs().
As the return type of jiffies_to_usecs() is 'unsigned int', when the return
value is more than the size of 'unsigned int', the leading 32 bits would be
discarded.
Suppose USEC_PER_SEC=1000000L and HZ=1000, below are the expected and
actual incorrect result of jiffies_to_usecs(0x7770ef70):
- expected : jiffies_to_usecs(0x7770ef70) = 0x000001d291274d80
- incorrect : jiffies_to_usecs(0x7770ef70) = 0x0000000091274d80
The leading 0x000001d200000000 is discarded.
After xen vcpu hotplug and when the new vcpu steal clock is calculated for
the first time, the result of this_rq()->prev_steal_time in
steal_account_process_tick() would be far smaller than the expected
value, due to that jiffies_to_usecs() discards the leading 32 bits.
As a result, the diff between current steal and this_rq()->prev_steal_time
is always very large. Steal usage would become 100% when the initial steal
clock obtained from xen hypervisor is very large during xen vcpu hotplug,
that is, when the guest is already up for a long time.
The bug can be detected by doing the following:
* Boot xen guest with vcpus=2 and maxvcpus=4
* Leave the guest running for a month so that the initial steal clock for
the new vcpu would be very large
* Hotplug 2 extra vcpus
* The steal time of new vcpus in /proc/stat would increase abnormally and
sometimes steal usage in top can become 100%
This was incidentally fixed in the patch set starting by
commit 93825f2ec736 ("jiffies: Reuse TICK_NSEC instead of NSEC_PER_JIFFY")
and ended with
commit b672592f0221 ("sched/cputime: Remove generic asm headers").
This version applies to the v4.9 series.
Link: https://lkml.org/lkml/2019/2/28/1373
Suggested-by: Juergen Gross <jgross(a)suse.com>
Signed-off-by: Dongli Zhang <dongli.zhang(a)oracle.com>
---
include/linux/jiffies.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 734377a..94aff43 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -287,13 +287,13 @@ extern unsigned long preset_lpj;
extern unsigned int jiffies_to_msecs(const unsigned long j);
extern unsigned int jiffies_to_usecs(const unsigned long j);
+extern u64 jiffies64_to_nsecs(u64 j);
+
static inline u64 jiffies_to_nsecs(const unsigned long j)
{
- return (u64)jiffies_to_usecs(j) * NSEC_PER_USEC;
+ return jiffies64_to_nsecs(j);
}
-extern u64 jiffies64_to_nsecs(u64 j);
-
extern unsigned long __msecs_to_jiffies(const unsigned int m);
#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
/*
--
2.7.4