Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
Hello Joakim, I tried your 4 patches on a MPC855M based system: -bash-3.2# cat /proc/cpuinfo processor : 0 cpu : 8xx clock : 66.00MHz revision: 0.0 (pvr 0050 ) bogomips: 8.25 timebase: 4125000 platform: TQM8xx model : TQM8xx Memory : 32 MB -bash-3.2# cat /proc/version Linux version 2.6.33-rc6-01500-gbddcb41-dirty (h...@xpert.denx.de) (gcc version 4.2.2) #9 Tue Mar 2 18:08:49 CET 2010 -bash-3.2# First I looked for the Boottime: Booting Linux: 2.6.33 2.6.33tunned ... until "Freeing unused kernel memory" message (= enter user space) ~4s ~4s ... until "login:" message (= full multi-user mode) 56s 56s and I did a Performance test with lmbench, see: http://sourceforge.net/projects/lmbench Here the results: (The first 4 rows are the results for the kernel without your patches, the next 4 rows are the results for the kernel with your patches) make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results' L M B E N C H 3 . 0 S U M M A R Y (Alpha software, do not distribute) Basic system parameters -- Host OS Description Mhz tlb cache mem scal pages line par load bytes - - --- - - -- tqm8xxLinux 2.6.33- powerpc-linux-gnu 663216 1.04001 tqm8xxLinux 2.6.33- powerpc-linux-gnu 66 716 1.04001 tqm8xxLinux 2.6.33- powerpc-linux-gnu 66 716 1.04001 tqm8xxLinux 2.6.33- powerpc-linux-gnu 663216 1.04001 tqm8xxLinux 2.6.33- powerpc-linux-gnu 663216 1.04001 tqm8xxLinux 2.6.33- powerpc-linux-gnu 66 716 1.04001 tqm8xxLinux 2.6.33- powerpc-linux-gnu 66 716 1.04001 tqm8xxLinux 2.6.33- powerpc-linux-gnu 663216 1.04001 Processor, Processes - times in microseconds - smaller is better -- Host OS Mhz null null open slct sig sig fork exec sh call I/O stat clos TCP inst hndl proc proc proc - - tqm8xxLinux 2.6.33- 66 2.97 10.3 129. 1377 272. 21.8 91.3 6949 29.K 89.K tqm8xxLinux 2.6.33- 66 3.06 10.5 124. 1375 273. 21.8 91.3 7136 30.K 89.K tqm8xxLinux 2.6.33- 66 3.06 10.6 129. 1365 272. 21.2 96.6 6889 29.K 89.K tqm8xxLinux 2.6.33- 66 3.06 10.5 124. 1309 272. 21.8 101. 6896 29.K 89.K tqm8xxLinux 2.6.33- 66 2.97 8.86 126. 1336 273. 21.7 84.2 6785 29.K 88.K tqm8xxLinux 2.6.33- 66 3.06 8.90 130. 1343 263. 21.3 84.7 7080 29.K 88.K tqm8xxLinux 2.6.33- 66 3.52 8.97 129. 1339 270. 22.4 84.4 6823 29.K 88.K tqm8xxLinux 2.6.33- 66 2.97 8.99 127. 1333 261. 22.4 87.0 7037 29.K 87.K Basic integer operations - times in nanoseconds - smaller is better --- Host OS intgr intgr intgr intgr intgr bit addmuldivmod - - -- -- -- -- -- tqm8xxLinux 2.6.33- 15.7 18.0 1.5600 124.2 203.1 tqm8xxLinux 2.6.33- 15.7 17.4 1.5800 121.1 202.8 tqm8xxLinux 2.6.33- 15.2 17.9 1.6200 124.2 202.7 tqm8xxLinux 2.6.33- 15.2 17.9 1.6000 125.0 204.0 tqm8xxLinux 2.6.33- 15.7 18.1 1.5600 124.7 204.4 tqm8xxLinux 2.6.33- 15.7 18.1 1.5800 124.2 202.8 tqm8xxLinux 2.6.33- 15.7 17.9 1.5500 124.2 203.2 tqm8xxLinux 2.6.33- 15.7 18.1 1.5500 124.5 202.0 Basic uint64 operations - times in nanoseconds - smaller is better -- Host OS int64 int64 int64 int64 int64 bitaddmuldivmod - - -- -- -- -- -- tqm8xxLinux 2.6.33-15. 13.3 1952.2 1838.2 tqm8xxLinux 2.6.33-15. 13.2 1951.5 1837.8 tqm8xxLinux 2.6.33-15. 13.2 1886.7 1907.8 tqm8xxLinux 2.6.33-15. 13.2 1951.5 1838.2 tqm8xxLinux 2.6.33-15. 13.3 1887.0 1902.2 tqm8xxLinux 2.6.33-15. 13.3 1887.4 1901.5 tqm8xxLinux 2.6.33-15. 13.3 1886.7 1893.0 tqm8xxLinux 2.6.33-15. 13.3 1950.0 1900.4 Basic float operations - times in nanoseconds - smaller is better - Hos
Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
Heiko Schocher wrote on 2010/03/03 09:02:47: > > Hello Joakim, > > I tried your 4 patches on a MPC855M based system: Thanks a lot for testing this for me! > > -bash-3.2# cat /proc/cpuinfo > processor : 0 > cpu : 8xx > clock : 66.00MHz > revision: 0.0 (pvr 0050 ) > bogomips: 8.25 > timebase: 4125000 > platform: TQM8xx > model : TQM8xx > Memory : 32 MB > -bash-3.2# cat /proc/version > Linux version 2.6.33-rc6-01500-gbddcb41-dirty (h...@xpert.denx.de) (gcc > version > 4.2.2) #9 Tue Mar 2 18:08:49 CET 2010 > -bash-3.2# > > First I looked for the Boottime: > > Booting Linux: > >2.6.33 2.6.33tunned > ... until "Freeing unused kernel memory" message (= enter user space)~4s > ~4s > ... until "login:" message (= full multi-user mode) 56s56s > > and I did a Performance test with lmbench, see: > http://sourceforge.net/projects/lmbench > > Here the results: > (The first 4 rows are the results for the kernel without your patches, > the next 4 rows are the results for the kernel with your patches) > > make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results' I see both ups and downs in this test, don't quite understand why. What is your config w.r.t SWAP, MODULES, CPU6 and CPU15? > > L M B E N C H 3 . 0 S U M M A R Y > >(Alpha software, do not distribute) > > Basic system parameters > -- > Host OS Description Mhz tlb cache mem scal > pages line par load >bytes > - - --- - - -- > tqm8xxLinux 2.6.33- powerpc-linux-gnu 663216 1.04001 > tqm8xxLinux 2.6.33- powerpc-linux-gnu 66 716 1.04001 > tqm8xxLinux 2.6.33- powerpc-linux-gnu 66 716 1.04001 > tqm8xxLinux 2.6.33- powerpc-linux-gnu 663216 1.04001 > tqm8xxLinux 2.6.33- powerpc-linux-gnu 663216 1.04001 > tqm8xxLinux 2.6.33- powerpc-linux-gnu 66 716 1.04001 > tqm8xxLinux 2.6.33- powerpc-linux-gnu 66 716 1.04001 > tqm8xxLinux 2.6.33- powerpc-linux-gnu 663216 1.04001 > > Processor, Processes - times in microseconds - smaller is better > -- > Host OS Mhz null null open slct sig sig fork exec sh > call I/O stat clos TCP inst hndl proc proc proc > - - > tqm8xxLinux 2.6.33- 66 2.97 10.3 129. 1377 272. 21.8 91.3 6949 29.K 89.K > tqm8xxLinux 2.6.33- 66 3.06 10.5 124. 1375 273. 21.8 91.3 7136 30.K 89.K > tqm8xxLinux 2.6.33- 66 3.06 10.6 129. 1365 272. 21.2 96.6 6889 29.K 89.K > tqm8xxLinux 2.6.33- 66 3.06 10.5 124. 1309 272. 21.8 101. 6896 29.K 89.K > tqm8xxLinux 2.6.33- 66 2.97 8.86 126. 1336 273. 21.7 84.2 6785 29.K 88.K > tqm8xxLinux 2.6.33- 66 3.06 8.90 130. 1343 263. 21.3 84.7 7080 29.K 88.K > tqm8xxLinux 2.6.33- 66 3.52 8.97 129. 1339 270. 22.4 84.4 6823 29.K 88.K > tqm8xxLinux 2.6.33- 66 2.97 8.99 127. 1333 261. 22.4 87.0 7037 29.K 87.K > [SNIP integer/float test, these are not relevant] > > Context switching - times in microseconds - smaller is better > - > Host OS 2p/0K 2p/16K 2p/64K 8p/16K 8p/64K 16p/16K 16p/64K > ctxsw ctxsw ctxsw ctxsw ctxsw ctxsw ctxsw > - - -- -- -- -- -- --- --- > tqm8xxLinux 2.6.33- 92.6 109.6 110.9 137.5 173.8 151.8 199.3 > tqm8xxLinux 2.6.33- 95.8 108.5 104.7 137.1 172.7 150.9 194.7 > tqm8xxLinux 2.6.33- 95.8 118.8 97.5 146.4 162.0 160.8 190.1 > tqm8xxLinux 2.6.33- 92.9 111.9 101.0 138.1 166.6 152.3 192.0 > tqm8xxLinux 2.6.33- 90.8 108.5 116.2 134.3 171.8 147.1 210.0 > tqm8xxLinux 2.6.33- 100.1 111.4 105.0 136.4 173.1 148.3 200.8 > tqm8xxLinux 2.6.33- 98.7 111.3 111.8 135.7 172.5 147.9 200.9 > tqm8xxLinux 2.6.33- 92.0 117.9 109.9 141.6 170.4 154.9 196.4 > > *Local* Communication latencies in microseconds - smaller is better > - > Host OS 2p/0K Pipe AF UDP RPC/ TCP RPC/ TCP > ctxsw UNIX UDP TCP conn > - - - - - - - - > tqm8xxLinux 2.6.
Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
> > Heiko Schocher wrote on 2010/03/03 09:02:47: > > > > Hello Joakim, > > > > I tried your 4 patches on a MPC855M based system: > > Thanks a lot for testing this for me! > > > > > -bash-3.2# cat /proc/cpuinfo > > processor : 0 > > cpu : 8xx > > clock : 66.00MHz > > revision: 0.0 (pvr 0050 ) > > bogomips: 8.25 > > timebase: 4125000 > > platform: TQM8xx > > model : TQM8xx > > Memory : 32 MB > > -bash-3.2# cat /proc/version > > Linux version 2.6.33-rc6-01500-gbddcb41-dirty (h...@xpert.denx.de) (gcc > > version > > 4.2.2) #9 Tue Mar 2 18:08:49 CET 2010 > > -bash-3.2# > > > > First I looked for the Boottime: > > > > Booting Linux: > > > >2.6.33 2.6.33tunned > > ... until "Freeing unused kernel memory" message (= enter user space) > > ~4s~4s > > ... until "login:" message (= full multi-user mode) 56s56s > > > > and I did a Performance test with lmbench, see: > > http://sourceforge.net/projects/lmbench > > > > Here the results: > > (The first 4 rows are the results for the kernel without your patches, > > the next 4 rows are the results for the kernel with your patches) > > > > make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results' > > I see both ups and downs in this test, don't quite understand why. > What is your config w.r.t SWAP, MODULES, CPU6 and CPU15? Forgot to ask for PIN_TLB too ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
Hello Joakim, Joakim Tjernlund wrote: > Heiko Schocher wrote on 2010/03/03 09:02:47: [...] >> Here the results: >> (The first 4 rows are the results for the kernel without your patches, >> the next 4 rows are the results for the kernel with your patches) >> >> make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results' > > I see both ups and downs in this test, don't quite understand why. > What is your config w.r.t SWAP, MODULES, CPU6 and CPU15? Sorry, forgot to say, where to find the sources. You can find them here: http://git.denx.de/?p=linux-2.6-denx.git;a=shortlog;h=refs/heads/tqm8xx bye Heiko -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
Heiko Schocher wrote on 2010/03/03 11:10:10: > > Hello Joakim, > > Joakim Tjernlund wrote: > > Heiko Schocher wrote on 2010/03/03 09:02:47: > [...] > >> Here the results: > >> (The first 4 rows are the results for the kernel without your patches, > >> the next 4 rows are the results for the kernel with your patches) > >> > >> make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results' > > > > I see both ups and downs in this test, don't quite understand why. > > What is your config w.r.t SWAP, MODULES, CPU6 and CPU15? > > Sorry, forgot to say, where to find the sources. You can find them > here: > > http://git.denx.de/?p=linux-2.6-denx.git;a=shortlog;h=refs/heads/tqm8xx OK, so you got SWAP=no, MODULES=yes, CPU6=no, CPU15=no PIN_TLB isn't listed in you def config so I assume it is no? MODULES=yes nullifies one optimization. I don't understand the bad numbers for Prot Fault: File & VM system latencies in microseconds - smaller is better --- Host OS 0K File 10K File MmapProt Page 100fd Create Delete Create Delete Latency Fault Fault selct - - -- -- -- -- --- - --- - tqm8xxLinux 2.6.33- 5917.2 3968.3 31.2K 4329.0 4147.0 18.834.1 135.2 tqm8xxLinux 2.6.33- 5714.3 3937.0 32.3K 6060.6 4210.0 14.234.5 131.4 tqm8xxLinux 2.6.33- 5747.1 4000.0 31.2K 4329.0 4114.0 7.69234.0 133.1 tqm8xxLinux 2.6.33- 5747.1 4081.6 30.3K 4273.5 4100.0 18.234.2 135.0 tqm8xxLinux 2.6.33- 5714.3 3952.6 31.2K 4273.5 4130.0 33.535.1 136.1 tqm8xxLinux 2.6.33- 5714.3 3906.2 31.2K 6060.6 4105.0 25.735.5 135.9 tqm8xxLinux 2.6.33- 5681.8 3921.6 32.3K 4255.3 4144.0 23.535.0 134.9 tqm8xxLinux 2.6.33- 5649.7 3937.0 30.3K 4237.3 4116.0 21.635.3 135.3 Could you try reverting patch: 8xx: Don't touch ACCESSED when no SWAP. and see if that makes a difference? Turning on pinned TLBs(you must turn on ADVANCED_OPTIONS first) could be an improvement, regardless of my patches. Jocke ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2] hvc_console: Fix race between hvc_close and hvc_remove
Alan pointed out a race in the code where hvc_remove is invoked. The recent virtio_console work is the first user of hvc_remove(). Alan describes it thus: The hvc_console assumes that a close and remove call can't occur at the same time. In addition tty_hangup(tty) is problematic as tty_hangup is asynchronous itself So this can happen hvc_close hvc_remove hung up ? - no lock tty = hp->tty unlock lock hp->tty = NULL unlock notify del kref_put the hvc struct close completes tty is destroyed tty_hangup dead tty tty->ops will be NULL NULL->... This patch adds some tty krefs and also converts to using tty_vhangup(). Reported-by: Alan Cox Signed-off-by: Amit Shah CC: Alan Cox CC: linuxppc-...@ozlabs.org CC: Rusty Russell --- Alan, how does this version look? I've tested with multiple virtio_console ports. There's some other bug in the hvc_remove code that's unrelated: hot-removal of one console port results in all other hvc consoles to stop working. I'll look at that once this is finalised. drivers/char/hvc_console.c | 31 +-- 1 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 4c3b59b..7e94b3c 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -312,6 +312,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) spin_lock_irqsave(&hp->lock, flags); /* Check and then increment for fast path open. */ if (hp->count++ > 0) { + tty_kref_get(tty); spin_unlock_irqrestore(&hp->lock, flags); hvc_kick(); return 0; @@ -319,7 +320,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) tty->driver_data = hp; - hp->tty = tty; + hp->tty = tty_kref_get(tty); spin_unlock_irqrestore(&hp->lock, flags); @@ -336,6 +337,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) spin_lock_irqsave(&hp->lock, flags); hp->tty = NULL; spin_unlock_irqrestore(&hp->lock, flags); + tty_kref_put(tty); tty->driver_data = NULL; kref_put(&hp->kref, destroy_hvc_struct); printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); @@ -363,13 +365,18 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) return; hp = tty->driver_data; + spin_lock_irqsave(&hp->lock, flags); + tty_kref_get(tty); if (--hp->count == 0) { /* We are done with the tty pointer now. */ hp->tty = NULL; spin_unlock_irqrestore(&hp->lock, flags); + /* Put the ref obtained in hvc_open() */ + tty_kref_put(tty); + if (hp->ops->notifier_del) hp->ops->notifier_del(hp, hp->data); @@ -389,6 +396,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) spin_unlock_irqrestore(&hp->lock, flags); } + tty_kref_put(tty); kref_put(&hp->kref, destroy_hvc_struct); } @@ -424,10 +432,11 @@ static void hvc_hangup(struct tty_struct *tty) spin_unlock_irqrestore(&hp->lock, flags); if (hp->ops->notifier_hangup) - hp->ops->notifier_hangup(hp, hp->data); + hp->ops->notifier_hangup(hp, hp->data); while(temp_open_count) { --temp_open_count; + tty_kref_put(tty); kref_put(&hp->kref, destroy_hvc_struct); } } @@ -592,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp) } /* No tty attached, just skip */ - tty = hp->tty; + tty = tty_kref_get(hp->tty); if (tty == NULL) goto bail; @@ -672,6 +681,8 @@ int hvc_poll(struct hvc_struct *hp) tty_flip_buffer_push(tty); } + if (tty) + tty_kref_put(tty); return poll_mask; } @@ -807,7 +818,7 @@ int hvc_remove(struct hvc_struct *hp) struct tty_struct *tty; spin_lock_irqsave(&hp->lock, flags); - tty = hp->tty; + tty = tty_kref_get(hp->tty); if (hp->index < MAX_NR_HVC_CONSOLES) vtermnos[hp->index] = -1; @@ -819,18 +830,18 @@ int hvc_remove(struct hvc_struct *hp) /* * We 'put' the instance that was grabbed when the kref instance * was initialized using kref_init(). Let the last holder of this -* kref cause it to be removed,
Re: [PATCH v2] hvc_console: Fix race between hvc_close and hvc_remove
On Wed, 3 Mar 2010 20:59:48 +0530 Amit Shah wrote: > Alan pointed out a race in the code where hvc_remove is invoked. The > recent virtio_console work is the first user of hvc_remove(). Looks better to me. Alan ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC] powerpc: add support for new hcall H_BEST_ENERGY
Hi, A new hypervisor call H_BEST_ENERGY is supported in IBM pseries ppc64 platform in order to exports platform energy management capabilities to user space administrative tools. This hypervisor calls provides hints or suggested list of cpus to activate or deactivate for optimized energy management. The following patch add a new pseries specific device driver that will export such platform energy management related information over sysfs interface for use by user space administrative tools. The device driver exports the following sysfs files: /sys/device/system/cpu/pseries_(de)activate_hint_list and /sys/device/system/cpu/cpuN/pseries_(de)activate_hint. Typical usage: # cat /sys/devices/system/cpu/pseries_activate_hint_list 16,20,24 # cat /sys/devices/system/cpu/pseries_deactivate_hint_list 0,4,8,12 Comma separated list of recommended cpu numbers to activate or deactivate. cat /sys/device/system/cpu/cpuN/pseries_(de)activate_hint will provide a single integer value returned by the platform for that cpu. Please let me know your comments and suggestions. Thanks, Vaidy --- powerpc: add support for new hcall H_BEST_ENERGY Create sysfs interface to export data from H_BEST_ENERGY hcall that can be used by administrative tools on supported pseries platforms for energy management optimizations. /sys/device/system/cpu/pseries_(de)activate_hint_list and /sys/device/system/cpu/cpuN/pseries_(de)activate_hint will provide hints for activation and deactivation of cpus respectively. Added new driver module arch/powerpc/platforms/pseries/pseries_energy.c under new config option CONFIG_PSERIES_ENERGY Signed-off-by: Vaidyanathan Srinivasan --- arch/powerpc/include/asm/hvcall.h |3 arch/powerpc/kernel/setup-common.c |2 arch/powerpc/platforms/pseries/Kconfig | 10 + arch/powerpc/platforms/pseries/Makefile |1 arch/powerpc/platforms/pseries/pseries_energy.c | 246 +++ 5 files changed, 261 insertions(+), 1 deletions(-) create mode 100644 arch/powerpc/platforms/pseries/pseries_energy.c diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index f027581..396599f 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -230,7 +230,8 @@ #define H_ENABLE_CRQ 0x2B0 #define H_SET_MPP 0x2D0 #define H_GET_MPP 0x2D4 -#define MAX_HCALL_OPCODE H_GET_MPP +#define H_BEST_ENERGY 0x2F4 +#define MAX_HCALL_OPCODE H_BEST_ENERGY #ifndef __ASSEMBLY__ diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 03dd6a2..fbd93e3 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -359,6 +359,8 @@ void __init check_for_initrd(void) #ifdef CONFIG_SMP int threads_per_core, threads_shift; +EXPORT_SYMBOL_GPL(threads_per_core); + cpumask_t threads_core_mask; static void __init cpu_init_thread_core_maps(int tpc) diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index c667f0f..b3dd108 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -33,6 +33,16 @@ config PSERIES_MSI depends on PCI_MSI && EEH default y +config PSERIES_ENERGY + tristate "pseries energy management capabilities driver" + depends on PPC_PSERIES + default y + help + Provides interface to platform energy management capabilities + on supported PSERIES platforms. + Provides: /sys/devices/system/cpu/pseries_(de)activation_hint_list + and /sys/devices/system/cpu/cpuN/pseries_(de)activation_hint + config SCANLOG tristate "Scanlog dump interface" depends on RTAS_PROC && PPC_PSERIES diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 0ff5174..3813977 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o obj-$(CONFIG_KEXEC)+= kexec.o obj-$(CONFIG_PCI) += pci.o pci_dlpar.o obj-$(CONFIG_PSERIES_MSI) += msi.o +obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c new file mode 100644 index 000..0390188 --- /dev/null +++ b/arch/powerpc/platforms/pseries/pseries_energy.c @@ -0,0 +1,246 @@ +/* + * POWER platform energy management driver + * Copyright (C) 2010 IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2
[PATCH] gianfar: Fix TX ring processing on SMP machines
Starting with commit a3bc1f11e9b867a4f49505 ("gianfar: Revive SKB recycling") gianfar driver sooner or later stops transmitting any packets on SMP machines. start_xmit() prepares new skb for transmitting, generally it does three things: 1. sets up all BDs (marks them ready to send), except the first one. 2. stores skb into tx_queue->tx_skbuff so that clean_tx_ring() would cleanup it later. 3. sets up the first BD, i.e. marks it ready. Here is what clean_tx_ring() does: 1. reads skbs from tx_queue->tx_skbuff 2. checks if the *last* BD is ready. If it's still ready [to send] then it it isn't transmitted, so clean_tx_ring() returns. Otherwise it actually cleanups BDs. All is OK. Now, if there is just one BD, code flow: - start_xmit(): stores skb into tx_skbuff. Note that the first BD (which is also the last one) isn't marked as ready, yet. - clean_tx_ring(): sees that skb is not null, *and* its lstatus says that it is NOT ready (like if BD was sent), so it cleans it up (bad!) - start_xmit(): marks BD as ready [to send], but it's too late. We can fix this simply by reordering lstatus/tx_skbuff writes. Reported-by: Martyn Welch Bisected-by: Paul Gortmaker Signed-off-by: Anton Vorontsov Tested-by: Paul Gortmaker Tested-by: Martyn Welch Cc: Sandeep Gopalpet Cc: Stable [2.6.33] --- drivers/net/gianfar.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 8bd3c9f..cccb409 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* setup the TxBD length and buffer pointer for the first BD */ - tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); @@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) txbdp_start->lstatus = lstatus; + eieio(); /* force lstatus write before tx_skbuff */ + + tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; + /* Update the current skb pointer to the next entry we will use * (wrapping if necessary) */ tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & -- 1.7.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[Patch v.2] mpc5200b/uart: improve baud rate calculation (reach high baud rates, better accuracy)
On the MPC5200B, make very high baud rates (e.g. 3 MBaud) accessible and achieve a higher precision for high baud rates in general. This is done by selecting the appropriate prescaler (/4 or /32). As to keep the code clean, the getuartclk method has been dropped, and all calculations are done with a "virtual" /4 prescaler for all chips for maximum accuracy. A new set_divisor method scales down the divisor values found by the generic serial code appropriately. Note: only "fsl,mpc5200b-psc-uart" compatible devices benefit from these improvements. Tested on a custom 5200B based board, with up to 3 MBaud, and with both "fsl,mpc5200b-psc-uart" and "fsl,mpc5200-psc-uart" devices. Signed-off-by: Albrecht Dreà --- Changes vs. v.1: include improvements suggested by Wolfram and Grant (thanks a lot for your helpful input!!): drop getuartclk method and use the highest possible frequency for calculation, use new psc_ops for the 5200b, let the set_divisor method do all the dirty work, emit warnings if bad divisor values have been selected. --- linux-2.6.33-orig/drivers/serial/mpc52xx_uart.c 2010-02-24 19:52:17.0 +0100 +++ linux-2.6.33/drivers/serial/mpc52xx_uart.c 2010-03-03 10:52:04.0 +0100 @@ -144,7 +144,8 @@ struct psc_ops { unsigned char (*read_char)(struct uart_port *port); void(*cw_disable_ints)(struct uart_port *port); void(*cw_restore_ints)(struct uart_port *port); - unsigned long (*getuartclk)(void *p); + void(*set_divisor)(struct uart_port *port, + unsigned int divisor); }; #ifdef CONFIG_PPC_MPC52xx @@ -154,9 +155,6 @@ static void mpc52xx_psc_fifo_init(struct struct mpc52xx_psc __iomem *psc = PSC(port); struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); - /* /32 prescaler */ - out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); - out_8(&fifo->rfcntl, 0x00); out_be16(&fifo->rfalarm, 0x1ff); out_8(&fifo->tfcntl, 0x07); @@ -245,15 +243,55 @@ static void mpc52xx_psc_cw_restore_ints( out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); } -/* Search for bus-frequency property in this node or a parent */ -static unsigned long mpc52xx_getuartclk(void *p) +static void mpc52xx_psc_set_divisor(struct uart_port *port, + unsigned int divisor) { - /* -* 5200 UARTs have a / 32 prescaler -* but the generic serial code assumes 16 -* so return ipb freq / 2 -*/ - return mpc5xxx_get_bus_frequency(p) / 2; + struct mpc52xx_psc __iomem *psc = PSC(port); + + /* adjust divisor for a /32 prescaler; see note in +* mpc52xx_uart_of_probe() */ + divisor = (divisor + 4) / 8; + if (divisor > 0x) { + pr_warning("%s: divisor overflow (%x), use 0x\n", __func__, + divisor); + divisor = 0x; + } else if (divisor == 0) { + pr_warning("%s: divisor 0, use 1\n", __func__); + divisor = 1; + } + + /* prescaler */ + out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */ + + /* ctr */ + out_8(&psc->ctur, divisor >> 8); + out_8(&psc->ctlr, divisor & 0xff); +} + +static void mpc5200b_psc_set_divisor(struct uart_port *port, +unsigned int divisor) +{ + struct mpc52xx_psc __iomem *psc = PSC(port); + + /* set prescaler; see note in mpc52xx_uart_of_probe() */ + if (divisor > 0x) { + divisor = (divisor + 4) / 8; + out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */ + } else + out_be16(&psc->mpc52xx_psc_clock_select, 0xff00); /* /4 */ + + if (divisor > 0x) { + pr_warning("%s: divisor overflow (%x), use 0x\n", __func__, + divisor); + divisor = 0x; + } else if (divisor == 0) { + pr_warning("%s: divisor 0, use 1\n", __func__); + divisor = 1; + } + + /* ctr */ + out_8(&psc->ctur, divisor >> 8); + out_8(&psc->ctlr, divisor & 0xff); } static struct psc_ops mpc52xx_psc_ops = { @@ -272,7 +310,26 @@ static struct psc_ops mpc52xx_psc_ops = .read_char = mpc52xx_psc_read_char, .cw_disable_ints = mpc52xx_psc_cw_disable_ints, .cw_restore_ints = mpc52xx_psc_cw_restore_ints, - .getuartclk = mpc52xx_getuartclk, + .set_divisor = mpc52xx_psc_set_divisor, +}; + +static struct psc_ops mpc5200b_psc_ops = { + .fifo_init = mpc52xx_psc_fifo_init, + .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy, + .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy, + .rx_rdy = mpc52xx_psc_rx_rdy, + .tx_rdy = mpc52xx_psc_tx_rdy, + .tx_empty = mpc52xx_psc_tx_empty, + .stop_rx = mpc52xx_psc_stop_rx, + .start_tx = mpc52xx_psc_start_t
Re: [Patch v.2] mpc5200b/uart: improve baud rate calculation (reach high baud rates, better accuracy)
Hi Albrecht, I like this version much better. Comments below... On Wed, Mar 3, 2010 at 11:23 AM, Albrecht Dreà wrote: > On the MPC5200B, make very high baud rates (e.g. 3 MBaud) accessible and > achieve a higher precision for high baud rates in general.  This is done by > selecting the appropriate prescaler (/4 or /32).  As to keep the code clean, > the getuartclk method has been dropped, and all calculations are done with a > "virtual" /4 prescaler for all chips for maximum accuracy.  A new set_divisor > method scales down the divisor values found by the generic serial code > appropriately. > > Note: only "fsl,mpc5200b-psc-uart" compatible devices benefit from these > improvements. > > Tested on a custom 5200B based board, with up to 3 MBaud, and with both > "fsl,mpc5200b-psc-uart" and "fsl,mpc5200-psc-uart" devices. > > Signed-off-by: Albrecht Dreà > > --- > > Changes vs. v.1: include improvements suggested by Wolfram and Grant (thanks a > lot for your helpful input!!): drop getuartclk method and use the highest > possible frequency for calculation, use new psc_ops for the 5200b, let the > set_divisor method do all the dirty work, emit warnings if bad divisor values > have been selected. > > > --- linux-2.6.33-orig/drivers/serial/mpc52xx_uart.c   2010-02-24 > 19:52:17.0 +0100 > +++ linux-2.6.33/drivers/serial/mpc52xx_uart.c  2010-03-03 10:52:04.0 > +0100 > @@ -388,9 +445,25 @@ static void mpc512x_psc_cw_restore_ints( >     out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); >  } > > -static unsigned long mpc512x_getuartclk(void *p) > +static void mpc512x_psc_set_divisor(struct uart_port *port, > +                  unsigned int divisor) >  { > -    return mpc5xxx_get_bus_frequency(p); > +    struct mpc52xx_psc __iomem *psc = PSC(port); > + > +    /* adjust divisor for a /16 prescaler; see note in > +     * mpc52xx_uart_of_probe() */ > +    divisor = (divisor + 2) / 4; > +    if (divisor > 0x) { > +        pr_warning("%s: divisor overflow (%x), use 0x\n", > __func__, > +              divisor); > +        divisor = 0x; > +    } else if (divisor == 0) { > +        pr_warning("%s: divisor 0, use 1\n", __func__); > +        divisor = 1; > +    } > + > +    out_8(&psc->ctur, divisor >> 8); > +    out_8(&psc->ctlr, divisor & 0xff); Save yourself some duplicated code here. The above 14 lines can be shared between the 512x, 52xx and 5200b versions. Create yourself an internal __mpc5xxx_psc_set_divisor() function that is passed the *psc, the divisor, and the clock select register setting (both the 5200 and the 5121 have the clock select register). >  } > >  static struct psc_ops mpc512x_psc_ops = { > @@ -409,7 +482,7 @@ static struct psc_ops mpc512x_psc_ops = >     .read_char = mpc512x_psc_read_char, >     .cw_disable_ints = mpc512x_psc_cw_disable_ints, >     .cw_restore_ints = mpc512x_psc_cw_restore_ints, > -    .getuartclk = mpc512x_getuartclk, > +    .set_divisor = mpc512x_psc_set_divisor, >  }; >  #endif > > @@ -564,7 +637,6 @@ mpc52xx_uart_set_termios(struct uart_por >     struct mpc52xx_psc __iomem *psc = PSC(port); >     unsigned long flags; >     unsigned char mr1, mr2; > -    unsigned short ctr; >     unsigned int j, baud, quot; > >     /* Prepare what we're gonna write */ > @@ -604,7 +676,6 @@ mpc52xx_uart_set_termios(struct uart_por > >     baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); I'm probably nitpicking, because I don't know if the io pin will handle this speed but uartclk/16 is no longer the maximum baudrate if a /4 prescaler is used. >     quot = uart_get_divisor(port, baud); > -    ctr = quot & 0x; > >     /* Get the lock */ >     spin_lock_irqsave(&port->lock, flags); > @@ -635,8 +706,7 @@ mpc52xx_uart_set_termios(struct uart_por >     out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); >     out_8(&psc->mode, mr1); >     out_8(&psc->mode, mr2); > -    out_8(&psc->ctur, ctr >> 8); > -    out_8(&psc->ctlr, ctr & 0xff); > +    psc_ops->set_divisor(port, quot); Hmmm. The divisor calculations have some tricky bits to them. I would consider changing the set_divisor() function to accept a baud rate, and modify the set_divisor function to call uart_get_divisor(). That way each set_divisor() can do whatever makes the most sense for the divisors available to it. The 5121 for example has both a /10 and a /32 divisor, plus it can use an external clock. > >     if (UART_ENABLE_MS(port, new->c_cflag)) >         mpc52xx_uart_enable_ms(port); > @@ -1007,7 +1077,8 @@ mpc52xx_console_setup(struct console *co >         return ret; >     } > > -  Â
Re: [PATCH v2] hvc_console: Fix race between hvc_close and hvc_remove
On (Wed) Mar 03 2010 [15:55:22], Alan Cox wrote: > On Wed, 3 Mar 2010 20:59:48 +0530 > Amit Shah wrote: > > > Alan pointed out a race in the code where hvc_remove is invoked. The > > recent virtio_console work is the first user of hvc_remove(). > > Looks better to me. Thanks, Alan. Ben, can you pick this up via your tree if it looks good to you? Amit ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev