From 2515a52669b46d90ca1cabb4c70b81a4a7e1c59e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Jun 2014 14:55:38 -0700 Subject: [PATCH] 3.14-stable patches added patches: intel_pstate-add-sample-time-scaling.patch intel_pstate-correct-rounding-in-busy-calculation.patch intel_pstate-improve-initial-busy-calculation.patch intel_pstate-remove-c0-tracking.patch intel_pstate-remove-unneeded-sample-buffers.patch percpu-refcount-fix-usage-of-this_cpu_ops.patch --- ...intel_pstate-add-sample-time-scaling.patch | 80 ++++++++++++++++ ...correct-rounding-in-busy-calculation.patch | 70 ++++++++++++++ ...ate-improve-initial-busy-calculation.patch | 48 ++++++++++ .../intel_pstate-remove-c0-tracking.patch | 92 +++++++++++++++++++ ...state-remove-unneeded-sample-buffers.patch | 83 +++++++++++++++++ ...u-refcount-fix-usage-of-this_cpu_ops.patch | 68 ++++++++++++++ queue-3.14/series | 6 ++ 7 files changed, 447 insertions(+) create mode 100644 queue-3.14/intel_pstate-add-sample-time-scaling.patch create mode 100644 queue-3.14/intel_pstate-correct-rounding-in-busy-calculation.patch create mode 100644 queue-3.14/intel_pstate-improve-initial-busy-calculation.patch create mode 100644 queue-3.14/intel_pstate-remove-c0-tracking.patch create mode 100644 queue-3.14/intel_pstate-remove-unneeded-sample-buffers.patch create mode 100644 queue-3.14/percpu-refcount-fix-usage-of-this_cpu_ops.patch diff --git a/queue-3.14/intel_pstate-add-sample-time-scaling.patch b/queue-3.14/intel_pstate-add-sample-time-scaling.patch new file mode 100644 index 00000000000..4bab5e7b96f --- /dev/null +++ b/queue-3.14/intel_pstate-add-sample-time-scaling.patch @@ -0,0 +1,80 @@ +From c4ee841f602e5eef8eab673295c49c5b49d7732b Mon Sep 17 00:00:00 2001 +From: Dirk Brandewie +Date: Thu, 29 May 2014 09:32:24 -0700 +Subject: intel_pstate: add sample time scaling + +From: Dirk Brandewie + +commit c4ee841f602e5eef8eab673295c49c5b49d7732b upstream. + +The PID assumes that samples are of equal time, which for a deferable +timers this is not true when the system goes idle. This causes the +PID to take a long time to converge to the min P state and depending +on the pattern of the idle load can make the P state appear stuck. + +The hold-off value of three sample times before using the scaling is +to give a grace period for applications that have high performance +requirements and spend a lot of time idle, The poster child for this +behavior is the ffmpeg benchmark in the Phoronix test suite. + +Signed-off-by: Dirk Brandewie +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/intel_pstate.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -60,6 +60,7 @@ struct sample { + u64 aperf; + u64 mperf; + int freq; ++ ktime_t time; + }; + + struct pstate_data { +@@ -97,6 +98,7 @@ struct cpudata { + struct vid_data vid; + struct _pid pid; + ++ ktime_t last_sample_time; + u64 prev_aperf; + u64 prev_mperf; + struct sample sample; +@@ -583,6 +585,8 @@ static inline void intel_pstate_sample(s + aperf = aperf >> FRAC_BITS; + mperf = mperf >> FRAC_BITS; + ++ cpu->last_sample_time = cpu->sample.time; ++ cpu->sample.time = ktime_get(); + cpu->sample.aperf = aperf; + cpu->sample.mperf = mperf; + cpu->sample.aperf -= cpu->prev_aperf; +@@ -605,12 +609,24 @@ static inline void intel_pstate_set_samp + + static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu) + { +- int32_t core_busy, max_pstate, current_pstate; ++ int32_t core_busy, max_pstate, current_pstate, sample_ratio; ++ u32 duration_us; ++ u32 sample_time; + + core_busy = cpu->sample.core_pct_busy; + max_pstate = int_tofp(cpu->pstate.max_pstate); + current_pstate = int_tofp(cpu->pstate.current_pstate); + core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); ++ ++ sample_time = (pid_params.sample_rate_ms * USEC_PER_MSEC); ++ duration_us = (u32) ktime_us_delta(cpu->sample.time, ++ cpu->last_sample_time); ++ if (duration_us > sample_time * 3) { ++ sample_ratio = div_fp(int_tofp(sample_time), ++ int_tofp(duration_us)); ++ core_busy = mul_fp(core_busy, sample_ratio); ++ } ++ + return core_busy; + } + diff --git a/queue-3.14/intel_pstate-correct-rounding-in-busy-calculation.patch b/queue-3.14/intel_pstate-correct-rounding-in-busy-calculation.patch new file mode 100644 index 00000000000..0eb397092c5 --- /dev/null +++ b/queue-3.14/intel_pstate-correct-rounding-in-busy-calculation.patch @@ -0,0 +1,70 @@ +From f0fe3cd7e12d8290c82284b5c8aee723cbd0371a Mon Sep 17 00:00:00 2001 +From: Dirk Brandewie +Date: Thu, 29 May 2014 09:32:23 -0700 +Subject: intel_pstate: Correct rounding in busy calculation + +From: Dirk Brandewie + +commit f0fe3cd7e12d8290c82284b5c8aee723cbd0371a upstream. + +Changing to fixed point math throughout the busy calculation in +commit e66c1768 (Change busy calculation to use fixed point +math.) Introduced some inaccuracies by rounding the busy value at two +points in the calculation. This change removes roundings and moves +the rounding to the output of the PID where the calculations are +complete and the value returned as an integer. + +Fixes: e66c17683746 (intel_pstate: Change busy calculation to use fixed point math.) +Reported-by: Doug Smythies +Signed-off-by: Dirk Brandewie +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/intel_pstate.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -40,10 +40,10 @@ + #define BYT_TURBO_VIDS 0x66d + + +-#define FRAC_BITS 6 ++#define FRAC_BITS 8 + #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) + #define fp_toint(X) ((X) >> FRAC_BITS) +-#define FP_ROUNDUP(X) ((X) += 1 << FRAC_BITS) ++ + + static inline int32_t mul_fp(int32_t x, int32_t y) + { +@@ -198,7 +198,10 @@ static signed int pid_calc(struct _pid * + pid->last_err = fp_error; + + result = pterm + mul_fp(pid->integral, pid->i_gain) + dterm; +- ++ if (result >= 0) ++ result = result + (1 << (FRAC_BITS-1)); ++ else ++ result = result - (1 << (FRAC_BITS-1)); + return (signed int)fp_toint(result); + } + +@@ -563,7 +566,6 @@ static inline void intel_pstate_calc_bus + core_pct = div_fp(int_tofp((sample->aperf)), + int_tofp((sample->mperf))); + core_pct = mul_fp(core_pct, int_tofp(100)); +- FP_ROUNDUP(core_pct); + + sample->freq = fp_toint( + mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); +@@ -609,7 +611,7 @@ static inline int32_t intel_pstate_get_s + max_pstate = int_tofp(cpu->pstate.max_pstate); + current_pstate = int_tofp(cpu->pstate.current_pstate); + core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); +- return FP_ROUNDUP(core_busy); ++ return core_busy; + } + + static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) diff --git a/queue-3.14/intel_pstate-improve-initial-busy-calculation.patch b/queue-3.14/intel_pstate-improve-initial-busy-calculation.patch new file mode 100644 index 00000000000..3c6288c34cb --- /dev/null +++ b/queue-3.14/intel_pstate-improve-initial-busy-calculation.patch @@ -0,0 +1,48 @@ +From bf8102228a8bf053051f311e5486042fe0542894 Mon Sep 17 00:00:00 2001 +From: Doug Smythies +Date: Fri, 30 May 2014 10:10:57 -0700 +Subject: intel_pstate: Improve initial busy calculation + +From: Doug Smythies + +commit bf8102228a8bf053051f311e5486042fe0542894 upstream. + +This change makes the busy calculation using 64 bit math which prevents +overflow for large values of aperf/mperf. + +Signed-off-by: Doug Smythies +Signed-off-by: Dirk Brandewie +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/intel_pstate.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -563,16 +563,19 @@ static void intel_pstate_get_cpu_pstates + static inline void intel_pstate_calc_busy(struct cpudata *cpu, + struct sample *sample) + { +- int32_t core_pct; ++ int64_t core_pct; ++ int32_t rem; + +- core_pct = div_fp(int_tofp((sample->aperf)), +- int_tofp((sample->mperf))); +- core_pct = mul_fp(core_pct, int_tofp(100)); ++ core_pct = int_tofp(sample->aperf) * int_tofp(100); ++ core_pct = div_u64_rem(core_pct, int_tofp(sample->mperf), &rem); ++ ++ if ((rem << 1) >= int_tofp(sample->mperf)) ++ core_pct += 1; + + sample->freq = fp_toint( + mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); + +- sample->core_pct_busy = core_pct; ++ sample->core_pct_busy = (int32_t)core_pct; + } + + static inline void intel_pstate_sample(struct cpudata *cpu) diff --git a/queue-3.14/intel_pstate-remove-c0-tracking.patch b/queue-3.14/intel_pstate-remove-c0-tracking.patch new file mode 100644 index 00000000000..fc26ef2fdcc --- /dev/null +++ b/queue-3.14/intel_pstate-remove-c0-tracking.patch @@ -0,0 +1,92 @@ +From adacdf3f2b8e65aa441613cf61c4f598e9042690 Mon Sep 17 00:00:00 2001 +From: Dirk Brandewie +Date: Thu, 29 May 2014 09:32:22 -0700 +Subject: intel_pstate: Remove C0 tracking + +From: Dirk Brandewie + +commit adacdf3f2b8e65aa441613cf61c4f598e9042690 upstream. + +Commit fcb6a15c (intel_pstate: Take core C0 time into account for core +busy calculation) introduced a regression referenced below. The issue +with "lockup" after suspend that this commit was addressing is now dealt +with in the suspend path. + +Fixes: fcb6a15c2e7e (intel_pstate: Take core C0 time into account for core busy calculation) +Link: https://bugzilla.kernel.org/show_bug.cgi?id=66581 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=75121 +Reported-by: Doug Smythies +Signed-off-by: Dirk Brandewie +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/intel_pstate.c | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -59,7 +59,6 @@ struct sample { + int32_t core_pct_busy; + u64 aperf; + u64 mperf; +- unsigned long long tsc; + int freq; + }; + +@@ -100,7 +99,6 @@ struct cpudata { + + u64 prev_aperf; + u64 prev_mperf; +- unsigned long long prev_tsc; + struct sample sample; + }; + +@@ -561,46 +559,37 @@ static inline void intel_pstate_calc_bus + struct sample *sample) + { + int32_t core_pct; +- int32_t c0_pct; + + core_pct = div_fp(int_tofp((sample->aperf)), + int_tofp((sample->mperf))); + core_pct = mul_fp(core_pct, int_tofp(100)); + FP_ROUNDUP(core_pct); + +- c0_pct = div_fp(int_tofp(sample->mperf), int_tofp(sample->tsc)); +- + sample->freq = fp_toint( + mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); + +- sample->core_pct_busy = mul_fp(core_pct, c0_pct); ++ sample->core_pct_busy = core_pct; + } + + static inline void intel_pstate_sample(struct cpudata *cpu) + { + u64 aperf, mperf; +- unsigned long long tsc; + + rdmsrl(MSR_IA32_APERF, aperf); + rdmsrl(MSR_IA32_MPERF, mperf); +- tsc = native_read_tsc(); + + aperf = aperf >> FRAC_BITS; + mperf = mperf >> FRAC_BITS; +- tsc = tsc >> FRAC_BITS; + + cpu->sample.aperf = aperf; + cpu->sample.mperf = mperf; +- cpu->sample.tsc = tsc; + cpu->sample.aperf -= cpu->prev_aperf; + cpu->sample.mperf -= cpu->prev_mperf; +- cpu->sample.tsc -= cpu->prev_tsc; + + intel_pstate_calc_busy(cpu, &cpu->sample); + + cpu->prev_aperf = aperf; + cpu->prev_mperf = mperf; +- cpu->prev_tsc = tsc; + } + + static inline void intel_pstate_set_sample_time(struct cpudata *cpu) diff --git a/queue-3.14/intel_pstate-remove-unneeded-sample-buffers.patch b/queue-3.14/intel_pstate-remove-unneeded-sample-buffers.patch new file mode 100644 index 00000000000..c69def0b891 --- /dev/null +++ b/queue-3.14/intel_pstate-remove-unneeded-sample-buffers.patch @@ -0,0 +1,83 @@ +From d37e2b764499e092ebc493d6f980827feb952e23 Mon Sep 17 00:00:00 2001 +From: Dirk Brandewie +Date: Wed, 12 Feb 2014 10:01:04 -0800 +Subject: intel_pstate: remove unneeded sample buffers + +From: Dirk Brandewie + +commit d37e2b764499e092ebc493d6f980827feb952e23 upstream. + +Remove unneeded sample buffers, intel_pstate operates on the most +recent sample only. This save some memory and make the code more +readable. + +Signed-off-by: Dirk Brandewie +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/intel_pstate.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -101,8 +101,7 @@ struct cpudata { + u64 prev_aperf; + u64 prev_mperf; + unsigned long long prev_tsc; +- int sample_ptr; +- struct sample samples[SAMPLE_COUNT]; ++ struct sample sample; + }; + + static struct cpudata **all_cpu_data; +@@ -590,15 +589,14 @@ static inline void intel_pstate_sample(s + mperf = mperf >> FRAC_BITS; + tsc = tsc >> FRAC_BITS; + +- cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; +- cpu->samples[cpu->sample_ptr].aperf = aperf; +- cpu->samples[cpu->sample_ptr].mperf = mperf; +- cpu->samples[cpu->sample_ptr].tsc = tsc; +- cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; +- cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; +- cpu->samples[cpu->sample_ptr].tsc -= cpu->prev_tsc; ++ cpu->sample.aperf = aperf; ++ cpu->sample.mperf = mperf; ++ cpu->sample.tsc = tsc; ++ cpu->sample.aperf -= cpu->prev_aperf; ++ cpu->sample.mperf -= cpu->prev_mperf; ++ cpu->sample.tsc -= cpu->prev_tsc; + +- intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); ++ intel_pstate_calc_busy(cpu, &cpu->sample); + + cpu->prev_aperf = aperf; + cpu->prev_mperf = mperf; +@@ -618,7 +616,7 @@ static inline int32_t intel_pstate_get_s + { + int32_t core_busy, max_pstate, current_pstate; + +- core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; ++ core_busy = cpu->sample.core_pct_busy; + max_pstate = int_tofp(cpu->pstate.max_pstate); + current_pstate = int_tofp(cpu->pstate.current_pstate); + core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); +@@ -652,7 +650,7 @@ static void intel_pstate_timer_func(unsi + + intel_pstate_sample(cpu); + +- sample = &cpu->samples[cpu->sample_ptr]; ++ sample = &cpu->sample; + + intel_pstate_adjust_busy_pstate(cpu); + +@@ -727,7 +725,7 @@ static unsigned int intel_pstate_get(uns + cpu = all_cpu_data[cpu_num]; + if (!cpu) + return 0; +- sample = &cpu->samples[cpu->sample_ptr]; ++ sample = &cpu->sample; + return sample->freq; + } + diff --git a/queue-3.14/percpu-refcount-fix-usage-of-this_cpu_ops.patch b/queue-3.14/percpu-refcount-fix-usage-of-this_cpu_ops.patch new file mode 100644 index 00000000000..915a6c9e749 --- /dev/null +++ b/queue-3.14/percpu-refcount-fix-usage-of-this_cpu_ops.patch @@ -0,0 +1,68 @@ +From 0c36b390a546055b6815d4b93a2c9fed4d980ffb Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Wed, 4 Jun 2014 15:58:24 +0200 +Subject: percpu-refcount: fix usage of this_cpu_ops + +From: Sebastian Ott + +commit 0c36b390a546055b6815d4b93a2c9fed4d980ffb upstream. + +The percpu-refcount infrastructure uses the underscore variants of +this_cpu_ops in order to modify percpu reference counters. +(e.g. __this_cpu_inc()). + +However the underscore variants do not atomically update the percpu +variable, instead they may be implemented using read-modify-write +semantics (more than one instruction). Therefore it is only safe to +use the underscore variant if the context is always the same (process, +softirq, or hardirq). Otherwise it is possible to lose updates. + +This problem is something that Sebastian has seen within the aio +subsystem which uses percpu refcounters both in process and softirq +context leading to reference counts that never dropped to zeroes; even +though the number of "get" and "put" calls matched. + +Fix this by using the non-underscore this_cpu_ops variant which +provides correct per cpu atomic semantics and fixes the corrupted +reference counts. + +Cc: Kent Overstreet +Reported-by: Sebastian Ott +Signed-off-by: Heiko Carstens +Signed-off-by: Tejun Heo +References: http://lkml.kernel.org/g/alpine.LFD.2.11.1406041540520.21183@denkbrett +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/percpu-refcount.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/include/linux/percpu-refcount.h ++++ b/include/linux/percpu-refcount.h +@@ -110,7 +110,7 @@ static inline void percpu_ref_get(struct + pcpu_count = ACCESS_ONCE(ref->pcpu_count); + + if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR)) +- __this_cpu_inc(*pcpu_count); ++ this_cpu_inc(*pcpu_count); + else + atomic_inc(&ref->count); + +@@ -139,7 +139,7 @@ static inline bool percpu_ref_tryget(str + pcpu_count = ACCESS_ONCE(ref->pcpu_count); + + if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR)) { +- __this_cpu_inc(*pcpu_count); ++ this_cpu_inc(*pcpu_count); + ret = true; + } + +@@ -164,7 +164,7 @@ static inline void percpu_ref_put(struct + pcpu_count = ACCESS_ONCE(ref->pcpu_count); + + if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR)) +- __this_cpu_dec(*pcpu_count); ++ this_cpu_dec(*pcpu_count); + else if (unlikely(atomic_dec_and_test(&ref->count))) + ref->release(ref); + diff --git a/queue-3.14/series b/queue-3.14/series index 8be2a3a6cd8..49ed1f6b1c5 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -59,3 +59,9 @@ usb-serial-option-add-support-for-novatel-e371-pcie-card.patch usb-io_ti-fix-firmware-download-on-big-endian-machines-part-2.patch usb-pci-quirks-prevent-sony-vaio-t-series-from-switching-usb-ports.patch usb-avoid-runtime-suspend-loops-for-hcds-that-can-t-handle-suspend-resume.patch +percpu-refcount-fix-usage-of-this_cpu_ops.patch +intel_pstate-remove-unneeded-sample-buffers.patch +intel_pstate-remove-c0-tracking.patch +intel_pstate-correct-rounding-in-busy-calculation.patch +intel_pstate-add-sample-time-scaling.patch +intel_pstate-improve-initial-busy-calculation.patch -- 2.47.3