| From 161c51ccb7a6faf45ffe09aa5cf1ad85ccdad503 Mon Sep 17 00:00:00 2001 |
| From: Paul Burton <paul.burton@imgtec.com> |
| Date: Thu, 2 Mar 2017 14:02:40 -0800 |
| Subject: MIPS: pm-cps: Drop manual cache-line alignment of ready_count |
| |
| From: Paul Burton <paul.burton@imgtec.com> |
| |
| commit 161c51ccb7a6faf45ffe09aa5cf1ad85ccdad503 upstream. |
| |
| We allocate memory for a ready_count variable per-CPU, which is accessed |
| via a cached non-coherent TLB mapping to perform synchronisation between |
| threads within the core using LL/SC instructions. In order to ensure |
| that the variable is contained within its own data cache line we |
| allocate 2 lines worth of memory & align the resulting pointer to a line |
| boundary. This is however unnecessary, since kmalloc is guaranteed to |
| return memory which is at least cache-line aligned (see |
| ARCH_DMA_MINALIGN). Stop the redundant manual alignment. |
| |
| Besides cleaning up the code & avoiding needless work, this has the side |
| effect of avoiding an arithmetic error found by Bryan on 64 bit systems |
| due to the 32 bit size of the former dlinesz. This led the ready_count |
| variable to have its upper 32b cleared erroneously for MIPS64 kernels, |
| causing problems when ready_count was later used on MIPS64 via cpuidle. |
| |
| Signed-off-by: Paul Burton <paul.burton@imgtec.com> |
| Fixes: 3179d37ee1ed ("MIPS: pm-cps: add PM state entry code for CPS systems") |
| Reported-by: Bryan O'Donoghue <bryan.odonoghue@imgtec.com> |
| Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@imgtec.com> |
| Tested-by: Bryan O'Donoghue <bryan.odonoghue@imgtec.com> |
| Cc: linux-mips@linux-mips.org |
| Patchwork: https://patchwork.linux-mips.org/patch/15383/ |
| Signed-off-by: Ralf Baechle <ralf@linux-mips.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/mips/kernel/pm-cps.c | 9 +-------- |
| 1 file changed, 1 insertion(+), 8 deletions(-) |
| |
| --- a/arch/mips/kernel/pm-cps.c |
| +++ b/arch/mips/kernel/pm-cps.c |
| @@ -55,7 +55,6 @@ DECLARE_BITMAP(state_support, CPS_PM_STA |
| * state. Actually per-core rather than per-CPU. |
| */ |
| static DEFINE_PER_CPU_ALIGNED(u32*, ready_count); |
| -static DEFINE_PER_CPU_ALIGNED(void*, ready_count_alloc); |
| |
| /* Indicates online CPUs coupled with the current CPU */ |
| static DEFINE_PER_CPU_ALIGNED(cpumask_t, online_coupled); |
| @@ -624,7 +623,6 @@ static int __init cps_gen_core_entries(u |
| { |
| enum cps_pm_state state; |
| unsigned core = cpu_data[cpu].core; |
| - unsigned dlinesz = cpu_data[cpu].dcache.linesz; |
| void *entry_fn, *core_rc; |
| |
| for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) { |
| @@ -644,16 +642,11 @@ static int __init cps_gen_core_entries(u |
| } |
| |
| if (!per_cpu(ready_count, core)) { |
| - core_rc = kmalloc(dlinesz * 2, GFP_KERNEL); |
| + core_rc = kmalloc(sizeof(u32), GFP_KERNEL); |
| if (!core_rc) { |
| pr_err("Failed allocate core %u ready_count\n", core); |
| return -ENOMEM; |
| } |
| - per_cpu(ready_count_alloc, core) = core_rc; |
| - |
| - /* Ensure ready_count is aligned to a cacheline boundary */ |
| - core_rc += dlinesz - 1; |
| - core_rc = (void *)((unsigned long)core_rc & ~(dlinesz - 1)); |
| per_cpu(ready_count, core) = core_rc; |
| } |
| |