* Re: Fw: Panic while enabling 2nd CPU core after suspend to ram on Intel Atom CPU
From: Rafael J. Wysocki @ 2011-07-26 20:03 UTC (permalink / raw)
To: Andrew Morton; +Cc: Ingo Molnar, Linux PM mailing list
In-Reply-To: <20110721140935.18e9a297.akpm@linux-foundation.org>
On Thursday, July 21, 2011, Andrew Morton wrote:
>
> who would be an appropriate person to look at this one?
>
> The suspend_test warning is Rafael, I guess. But the mwait_idle oops?
The suspend_test warning only means that the resuming of devices took
too much time.
Thanks,
Rafael
> Begin forwarded message:
>
> Date: Sun, 17 Jul 2011 17:00:14 +0200
> From: Martin Süfke <martinlkml2011@piximail.de>
> To: linux-kernel@vger.kernel.org
> Subject: Panic while enabling 2nd CPU core after suspend to ram on Intel Atom CPU
>
>
> Hello, everybody.
>
> I get the following kernel panic after my system has been sent to "suspend to ram":
> The system has an Intel Atom D525 Dual Core CPU with hyperthreading, showing up as 4 cpus in /proc/cpuinfo. After the kernel panic happened, the caps-lock and scroll-lock LED on the keyboard are blinking.
>
> $ ksymoops -m /boot/System.map-3.0.0-rc7min oops_without_timestamps.log
> ksymoops 2.4.11 on x86_64 3.0.0-rc7min. Options used
> -V (default)
> -k /proc/ksyms (default)
> -l /proc/modules (default)
> -o /lib/modules/3.0.0-rc7min/ (default)
> -m /boot/System.map-3.0.0-rc7min (specified)
>
> Error (regular_file): read_ksyms stat /proc/ksyms failed
> ksymoops: No such file or directory
> No modules in ksyms, skipping objects
> No ksyms, skipping lsmod
> CPU 1
> Pid: 0, comm: kworker/0:0 Tainted: G W 3.0.0-rc7min #14 Gigabyte Technology Co., Ltd. D525TUD/D525TUD
> RIP: 0010:[<ffffffff810088cf>] [<ffffffff810088cf>] mwait_idle+0xd2/0x159
> Using defaults from ksymoops -t elf64-x86-64 -a i386:x86-64
> RSP: 0000:ffff88013f515ef8 EFLAGS: 00010046
> RAX: ffff88013f514010 RBX: ffff88013f515fd8 RCX: 0000000000000000
> RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff818df108
> RBP: ffff88013f515f08 R08: 0000000000000000 R09: 0000000000000000
> R10: 7fffffffffffffff R11: ffffffff8184e4d0 R12: 0000000000000001
> R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> FS: 0000000000000000(0000) GS:ffff88013fc80000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> CR2: 0000000000000000 CR3: 0000000001803000 CR4: 00000000000006e0
> ffffffff818525a0 ffff88013f514010 ffff88013f515f28 ffffffff81001c88
> 0000000000000001 0000000000000000 ffff88013f515f48 ffffffff81411371
> 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> Call Trace:
> [<ffffffff81001c88>] cpu_idle+0x5a/0x91
> [<ffffffff81411371>] start_secondary+0x19c/0x1a0
> Code: c2 74 13 65 48 8b 04 25 88 b5 00 00 48 2d d8 1f 00 00 0f ae 78 10 31 d2 65 48 8b 1c 25 88 b5 00 00 48 89 d1 48 8d 83 38 e0 ff ff <0f> 01 c8 0f ae f0 48 8b 83 38 e0 ff ff a8 08 75 08 31 c0 fb 0f
>
>
> >>RIP; ffffffff810088cf <mwait_idle+d2/159> <=====
>
> >>RAX; ffff88013f514010 <phys_startup_64+ffff88013e514010/ffffffff80000000>
> >>RBX; ffff88013f515fd8 <phys_startup_64+ffff88013e515fd8/ffffffff80000000>
> >>RDI; ffffffff818df108 <idle_notifier+8/10>
> >>RBP; ffff88013f515f08 <phys_startup_64+ffff88013e515f08/ffffffff80000000>
> >>R10; 7fffffffffffffff <phys_startup_64+7ffffffffeffffff/ffffffff80000000>
> >>R11; ffffffff8184e4d0 <migration_notifier+0/20>
>
> Trace; ffffffff81001c88 <cpu_idle+5a/91>
> Trace; ffffffff81411371 <start_secondary+19c/1a0>
>
> Code; ffffffff810088a4 <mwait_idle+a7/159>
> 0000000000000000 <_RIP>:
> Code; ffffffff810088a4 <mwait_idle+a7/159>
> 0: c2 74 13 retq $0x1374
> Code; ffffffff810088a7 <mwait_idle+aa/159>
> 3: 65 48 8b 04 25 88 b5 mov %gs:0xb588,%rax
> Code; ffffffff810088ae <mwait_idle+b1/159>
> a: 00 00
> Code; ffffffff810088b0 <mwait_idle+b3/159>
> c: 48 2d d8 1f 00 00 sub $0x1fd8,%rax
> Code; ffffffff810088b6 <mwait_idle+b9/159>
> 12: 0f ae 78 10 clflush 0x10(%rax)
> Code; ffffffff810088ba <mwait_idle+bd/159>
> 16: 31 d2 xor %edx,%edx
> Code; ffffffff810088bc <mwait_idle+bf/159>
> 18: 65 48 8b 1c 25 88 b5 mov %gs:0xb588,%rbx
> Code; ffffffff810088c3 <mwait_idle+c6/159>
> 1f: 00 00
> Code; ffffffff810088c5 <mwait_idle+c8/159>
> 21: 48 89 d1 mov %rdx,%rcx
> Code; ffffffff810088c8 <mwait_idle+cb/159>
> 24: 48 8d 83 38 e0 ff ff lea -0x1fc8(%rbx),%rax
> Code; ffffffff810088cf <mwait_idle+d2/159> <=====
> 2b: 0f 01 c8 monitor %rax,%rcx,%rdx <=====
> Code; ffffffff810088d2 <mwait_idle+d5/159>
> 2e: 0f ae f0 mfence
> Code; ffffffff810088d5 <mwait_idle+d8/159>
> 31: 48 8b 83 38 e0 ff ff mov -0x1fc8(%rbx),%rax
> Code; ffffffff810088dc <mwait_idle+df/159>
> 38: a8 08 test $0x8,%al
> Code; ffffffff810088de <mwait_idle+e1/159>
> 3a: 75 08 jne 44 <_RIP+0x44>
> Code; ffffffff810088e0 <mwait_idle+e3/159>
> 3c: 31 c0 xor %eax,%eax
> Code; ffffffff810088e2 <mwait_idle+e5/159>
> 3e: fb sti
> Code; ffffffff810088e3 <mwait_idle+e6/159>
> 3f:
>
> Kernel panic - not syncing: Attempted to kill the idle task!
> Pid: 0, comm: kworker/0:0 Tainted: G D W 3.0.0-rc7min #14
> Call Trace:
> [<ffffffff81414bc4>] panic+0x8c/0x199
> [<ffffffff810343d5>] do_exit+0xab/0x737
> [<ffffffff8103137a>] ? kmsg_dump+0x44/0xe3
> [<ffffffff81004fe4>] oops_end+0xb1/0xb9
> [<ffffffff810050d2>] die+0x55/0x5e
> [<ffffffff81002bce>] do_trap+0x11c/0x12b
> [<ffffffff81002f4e>] do_invalid_op+0x91/0x9a
> [<ffffffff810088cf>] ? mwait_idle+0xd2/0x159
> [<ffffffff81016a71>] ? __setup_APIC_LVTT+0x67/0x88
> [<ffffffff81052939>] ? ktime_get+0x5f/0xb5
> [<ffffffff81016aaa>] ? lapic_next_event+0x18/0x1c
> [<ffffffff81056a4a>] ? clockevents_program_event+0x75/0x7e
> [<ffffffff81056d77>] ? tick_setup_periodic+0x6f/0x81
> [<ffffffff814186d5>] invalid_op+0x15/0x20
> [<ffffffff810088cf>] ? mwait_idle+0xd2/0x159
> [<ffffffff8104f5dc>] ? atomic_notifier_call_chain+0x13/0x15
> [<ffffffff81001c88>] cpu_idle+0x5a/0x91
> [<ffffffff81411371>] start_secondary+0x19c/0x1a0
> Warning (Oops_read): Code line not seen, dumping what data is available
>
>
> Trace; ffffffff81414bc4 <panic+8c/199>
> Trace; ffffffff810343d5 <do_exit+ab/737>
> Trace; ffffffff8103137a <kmsg_dump+44/e3>
> Trace; ffffffff81004fe4 <oops_end+b1/b9>
> Trace; ffffffff810050d2 <die+55/5e>
> Trace; ffffffff81002bce <do_trap+11c/12b>
> Trace; ffffffff81002f4e <do_invalid_op+91/9a>
> Trace; ffffffff810088cf <mwait_idle+d2/159>
> Trace; ffffffff81016a71 <__setup_APIC_LVTT+67/88>
> Trace; ffffffff81052939 <ktime_get+5f/b5>
> Trace; ffffffff81016aaa <lapic_next_event+18/1c>
> Trace; ffffffff81056a4a <clockevents_program_event+75/7e>
> Trace; ffffffff81056d77 <tick_setup_periodic+6f/81>
> Trace; ffffffff814186d5 <invalid_op+15/20>
> Trace; ffffffff810088cf <mwait_idle+d2/159>
> Trace; ffffffff8104f5dc <atomic_notifier_call_chain+13/15>
> Trace; ffffffff81001c88 <cpu_idle+5a/91>
> Trace; ffffffff81411371 <start_secondary+19c/1a0>
> 1 warning and 1 error issued. Results may not be reliable.
>
> To get there, I do the following:
> 1) disable cpu1 and cpu2 (both on cpu core 1 if I got it right) with:
> $ echo 0 > /sys/devices/system/cpu/cpu1/online
> $ echo 0 > /sys/devices/system/cpu/cpu2/online
> this leaves me with cpu0 and cpu3 which are both hyperthreads on
>
> 2) suspend to ram, then resume the system
> $ echo mem > /sys/power/state
> (system goes into suspend, resumable by pressing the power button)
>
> 2a) During supend, a warning is issuted. My guess is that the harddisk is simply slow to spin up. Is that guess right ?
> $ dmesg
> [ 104.092215] PM: Syncing filesystems ... done.
> [ 104.096763] PM: Preparing system for mem sleep
> [ 104.104047] Freezing user space processes ... (elapsed 0.01 seconds) done.
> [ 104.121723] Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
> [ 104.139774] PM: Entering mem sleep
> [ 104.143700] sd 1:0:0:0: [sdb] Synchronizing SCSI cache
> [ 104.143721] sd 0:0:0:0: [sda] Synchronizing SCSI cache
> [ 104.143878] sd 0:0:0:0: [sda] Stopping disk
> [ 104.158499] sd 1:0:0:0: [sdb] Stopping disk
> [ 104.169431] serial 00:08: disabled
> [ 104.172946] serial 00:08: wake-up capability disabled by ACPI
> [ 108.652030] serial 00:08: activated
> [ 108.963044] ata6: SATA link down (SStatus 0 SControl 300)
> [ 108.968599] ata5: SATA link down (SStatus 0 SControl 300)
> [ 110.156028] ata1: link is slow to respond, please be patient (ready=0)
> [ 110.162673] ata2: link is slow to respond, please be patient (ready=0)
> [ 113.943040] ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
> [ 113.951711] ata2.00: configured for UDMA/133
> [ 114.803024] ata1: COMRESET failed (errno=-16)
> [ 117.050031] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
> [ 117.086293] ata1.00: configured for UDMA/133
> [ 117.100984] PM: resume of devices complete after 12306.735 msecs
> [ 117.107275] PM: resume devices took 12.313 seconds
> [ 117.112177] ------------[ cut here ]------------
> [ 117.116910] WARNING: at kernel/power/suspend_test.c:53 suspend_test_finish+0x7b/0x84()
> [ 117.125009] Hardware name: D525TUD
> [ 117.128511] Component: resume devices, time: 12313
> [ 117.133414] Pid: 3612, comm: echo Not tainted 3.0.0-rc7min #14
> [ 117.139352] Call Trace:
> [ 117.141905] [<ffffffff81030f02>] warn_slowpath_common+0x7b/0x93
> [ 117.148024] [<ffffffff81030fae>] warn_slowpath_fmt+0x41/0x43
> [ 117.153882] [<ffffffff8105dabb>] suspend_test_finish+0x7b/0x84
> [ 117.159918] [<ffffffff8105d853>] suspend_devices_and_enter+0x1d9/0x236
> [ 117.166642] [<ffffffff8105d98f>] enter_state+0xdf/0x135
> [ 117.172062] [<ffffffff8105d062>] state_store+0xb1/0xce
> [ 117.177403] [<ffffffff81210ee3>] kobj_attr_store+0x17/0x19
> [ 117.183088] [<ffffffff81113a97>] sysfs_write_file+0xef/0x12b
> [ 117.188947] [<ffffffff810c5687>] vfs_write+0xae/0x153
> [ 117.194196] [<ffffffff810c57e5>] sys_write+0x45/0x6c
> [ 117.199362] [<ffffffff81417afb>] system_call_fastpath+0x16/0x1b
> [ 117.205481] ---[ end trace 27f1f84a48a28b3a ]---
> [ 117.210220] PM: Finishing wakeup.
> [ 117.213636] Restarting tasks ... done.
>
> 3) Now enabling the cpu1 or cpu2 (on core 1) leads to the panic:
> $ echo 1 > /sys/devices/system/cpu/cpu1/online
> [ 162.550537] Booting Node 0 Processor 1 APIC 0x2
> [ 162.555190] smpboot cpu 1: start_ip = 9a000
> [ 28.795663] Disabled fast string operations
> [ 162.638260] invalid opcode: 0000 [#1] SMP
> [ 162.638260] CPU 1
> [ 162.638260] Pid: 0, comm: kworker/0:0 Tainted: G W 3.0.0-rc7min #14 Gigabyte Technology Co., Ltd. D525TUD/D525TUD
> ... this is the oops which is at the beginnin ot the message ...
>
> Attached: kernel .config, cpuinfo, content of /sys/power/* and content of /sys/devices/system/cpu/*
>
> More info:
> enabling and disabling cpu1, cpu2 and/or cpu3 in any combination or sequence works without errror if the system had not been suspended to ram before.
> Suspend to disk works, also works if all cpus are enabled
> Testing suspend to ram with /sys/power/pm_test works with all tests, including "core" even if all cpus are enabled
> suspend to ram does not work with all cpus enabled, the system will only show the VGA BIOS greeting message and blinking keyboard leds.
>
> If CONFIG_INTEL_IDLE is set in kernel config, the oops trace will include "intel_idle" instead of "mwait_idle" but not differ much otherwise. I can provide an oops trace with intel_idle if it helps.
>
> I have tested kernels 2.6.35.10 2.6.36.2 2.6.37-rc6 2.6.39-git all with the same problem half a year ago.
> Back then, the system had BIOS revision F3, this got upgraded to F4 for the tests with the 3.0.0-rc7 kernel.
>
> Earlier, I had tried posting the problem to the linux-pm mailing list
> https://lists.linux-foundation.org/pipermail/linux-pm/2010-December/029654.html
> https://lists.linux-foundation.org/pipermail/linux-pm/2010-December/029655.html
> https://lists.linux-foundation.org/pipermail/linux-pm/2010-December/029656.html
> However, I got the only answer I got was to try it on the LKML
>
> Any help is appreciated.
>
> I am NOT on the LKML, so please CC me in replies.
> -Martin
>
> ------------------ Kernel config -------------
> CONFIG_64BIT=y
> CONFIG_X86_64=y
> CONFIG_X86=y
> CONFIG_INSTRUCTION_DECODER=y
> CONFIG_OUTPUT_FORMAT="elf64-x86-64"
> CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
> CONFIG_GENERIC_CMOS_UPDATE=y
> CONFIG_CLOCKSOURCE_WATCHDOG=y
> CONFIG_GENERIC_CLOCKEVENTS=y
> CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
> CONFIG_LOCKDEP_SUPPORT=y
> CONFIG_STACKTRACE_SUPPORT=y
> CONFIG_HAVE_LATENCYTOP_SUPPORT=y
> CONFIG_MMU=y
> CONFIG_ZONE_DMA=y
> CONFIG_NEED_DMA_MAP_STATE=y
> CONFIG_NEED_SG_DMA_LENGTH=y
> CONFIG_GENERIC_ISA_DMA=y
> CONFIG_GENERIC_IOMAP=y
> CONFIG_GENERIC_BUG=y
> CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
> CONFIG_GENERIC_HWEIGHT=y
> CONFIG_ARCH_MAY_HAVE_PC_FDC=y
> CONFIG_RWSEM_XCHGADD_ALGORITHM=y
> CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
> CONFIG_GENERIC_CALIBRATE_DELAY=y
> CONFIG_GENERIC_TIME_VSYSCALL=y
> CONFIG_ARCH_HAS_CPU_RELAX=y
> CONFIG_ARCH_HAS_DEFAULT_IDLE=y
> CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
> CONFIG_HAVE_SETUP_PER_CPU_AREA=y
> CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
> CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
> CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y
> CONFIG_ARCH_HIBERNATION_POSSIBLE=y
> CONFIG_ARCH_SUSPEND_POSSIBLE=y
> CONFIG_ZONE_DMA32=y
> CONFIG_ARCH_POPULATES_NODE_MAP=y
> CONFIG_AUDIT_ARCH=y
> CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
> CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
> CONFIG_X86_64_SMP=y
> CONFIG_X86_HT=y
> CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
> CONFIG_ARCH_CPU_PROBE_RELEASE=y
> CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
> CONFIG_HAVE_IRQ_WORK=y
> CONFIG_IRQ_WORK=y
> CONFIG_EXPERIMENTAL=y
> CONFIG_INIT_ENV_ARG_LIMIT=32
> CONFIG_CROSS_COMPILE=""
> CONFIG_LOCALVERSION="min"
> CONFIG_HAVE_KERNEL_GZIP=y
> CONFIG_HAVE_KERNEL_BZIP2=y
> CONFIG_HAVE_KERNEL_LZMA=y
> CONFIG_HAVE_KERNEL_XZ=y
> CONFIG_HAVE_KERNEL_LZO=y
> CONFIG_KERNEL_GZIP=y
> CONFIG_DEFAULT_HOSTNAME="behemoth"
> CONFIG_SWAP=y
> CONFIG_SYSVIPC=y
> CONFIG_SYSVIPC_SYSCTL=y
> CONFIG_POSIX_MQUEUE=y
> CONFIG_POSIX_MQUEUE_SYSCTL=y
> CONFIG_BSD_PROCESS_ACCT=y
> CONFIG_FHANDLE=y
> CONFIG_TASKSTATS=y
> CONFIG_TASK_DELAY_ACCT=y
> CONFIG_TASK_XACCT=y
> CONFIG_TASK_IO_ACCOUNTING=y
> CONFIG_AUDIT=y
> CONFIG_AUDITSYSCALL=y
> CONFIG_AUDIT_WATCH=y
> CONFIG_AUDIT_TREE=y
> CONFIG_HAVE_GENERIC_HARDIRQS=y
> CONFIG_GENERIC_HARDIRQS=y
> CONFIG_HAVE_SPARSE_IRQ=y
> CONFIG_GENERIC_IRQ_PROBE=y
> CONFIG_GENERIC_IRQ_SHOW=y
> CONFIG_GENERIC_PENDING_IRQ=y
> CONFIG_IRQ_FORCED_THREADING=y
> CONFIG_SPARSE_IRQ=y
> CONFIG_TREE_RCU=y
> CONFIG_RCU_FANOUT=32
> CONFIG_IKCONFIG=y
> CONFIG_IKCONFIG_PROC=y
> CONFIG_LOG_BUF_SHIFT=20
> CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
> CONFIG_NAMESPACES=y
> CONFIG_UTS_NS=y
> CONFIG_IPC_NS=y
> CONFIG_USER_NS=y
> CONFIG_PID_NS=y
> CONFIG_NET_NS=y
> CONFIG_RELAY=y
> CONFIG_BLK_DEV_INITRD=y
> CONFIG_INITRAMFS_SOURCE=""
> CONFIG_RD_GZIP=y
> CONFIG_RD_BZIP2=y
> CONFIG_RD_LZMA=y
> CONFIG_RD_XZ=y
> CONFIG_RD_LZO=y
> CONFIG_CC_OPTIMIZE_FOR_SIZE=y
> CONFIG_SYSCTL=y
> CONFIG_ANON_INODES=y
> CONFIG_SYSCTL_SYSCALL=y
> CONFIG_KALLSYMS=y
> CONFIG_HOTPLUG=y
> CONFIG_PRINTK=y
> CONFIG_BUG=y
> CONFIG_ELF_CORE=y
> CONFIG_PCSPKR_PLATFORM=y
> CONFIG_BASE_FULL=y
> CONFIG_FUTEX=y
> CONFIG_EPOLL=y
> CONFIG_SIGNALFD=y
> CONFIG_TIMERFD=y
> CONFIG_EVENTFD=y
> CONFIG_SHMEM=y
> CONFIG_AIO=y
> CONFIG_HAVE_PERF_EVENTS=y
> CONFIG_PERF_EVENTS=y
> CONFIG_VM_EVENT_COUNTERS=y
> CONFIG_PCI_QUIRKS=y
> CONFIG_SLAB=y
> CONFIG_TRACEPOINTS=y
> CONFIG_HAVE_OPROFILE=y
> CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
> CONFIG_HAVE_IOREMAP_PROT=y
> CONFIG_HAVE_KPROBES=y
> CONFIG_HAVE_KRETPROBES=y
> CONFIG_HAVE_OPTPROBES=y
> CONFIG_HAVE_ARCH_TRACEHOOK=y
> CONFIG_HAVE_DMA_ATTRS=y
> CONFIG_USE_GENERIC_SMP_HELPERS=y
> CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
> CONFIG_HAVE_DMA_API_DEBUG=y
> CONFIG_HAVE_HW_BREAKPOINT=y
> CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
> CONFIG_HAVE_USER_RETURN_NOTIFIER=y
> CONFIG_HAVE_PERF_EVENTS_NMI=y
> CONFIG_HAVE_ARCH_JUMP_LABEL=y
> CONFIG_SLABINFO=y
> CONFIG_RT_MUTEXES=y
> CONFIG_BASE_SMALL=0
> CONFIG_STOP_MACHINE=y
> CONFIG_BLOCK=y
> CONFIG_BLK_DEV_BSG=y
> CONFIG_IOSCHED_NOOP=y
> CONFIG_IOSCHED_DEADLINE=y
> CONFIG_IOSCHED_CFQ=y
> CONFIG_DEFAULT_CFQ=y
> CONFIG_DEFAULT_IOSCHED="cfq"
> CONFIG_INLINE_SPIN_UNLOCK=y
> CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
> CONFIG_INLINE_READ_UNLOCK=y
> CONFIG_INLINE_READ_UNLOCK_IRQ=y
> CONFIG_INLINE_WRITE_UNLOCK=y
> CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
> CONFIG_MUTEX_SPIN_ON_OWNER=y
> CONFIG_FREEZER=y
> CONFIG_TICK_ONESHOT=y
> CONFIG_NO_HZ=y
> CONFIG_HIGH_RES_TIMERS=y
> CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
> CONFIG_SMP=y
> CONFIG_X86_MPPARSE=y
> CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
> CONFIG_SCHED_OMIT_FRAME_POINTER=y
> CONFIG_NO_BOOTMEM=y
> CONFIG_MATOM=y
> CONFIG_X86_INTERNODE_CACHE_SHIFT=6
> CONFIG_X86_CMPXCHG=y
> CONFIG_CMPXCHG_LOCAL=y
> CONFIG_X86_L1_CACHE_SHIFT=6
> CONFIG_X86_XADD=y
> CONFIG_X86_WP_WORKS_OK=y
> CONFIG_X86_USE_PPRO_CHECKSUM=y
> CONFIG_X86_TSC=y
> CONFIG_X86_CMPXCHG64=y
> CONFIG_X86_CMOV=y
> CONFIG_X86_MINIMUM_CPU_FAMILY=64
> CONFIG_X86_DEBUGCTLMSR=y
> CONFIG_CPU_SUP_INTEL=y
> CONFIG_CPU_SUP_AMD=y
> CONFIG_CPU_SUP_CENTAUR=y
> CONFIG_HPET_TIMER=y
> CONFIG_HPET_EMULATE_RTC=y
> CONFIG_DMI=y
> CONFIG_GART_IOMMU=y
> CONFIG_SWIOTLB=y
> CONFIG_IOMMU_HELPER=y
> CONFIG_NR_CPUS=4
> CONFIG_SCHED_MC=y
> CONFIG_PREEMPT_NONE=y
> CONFIG_X86_LOCAL_APIC=y
> CONFIG_X86_IO_APIC=y
> CONFIG_X86_MCE=y
> CONFIG_X86_MCE_INTEL=y
> CONFIG_X86_MCE_THRESHOLD=y
> CONFIG_X86_THERMAL_VECTOR=y
> CONFIG_MICROCODE=y
> CONFIG_MICROCODE_INTEL=y
> CONFIG_MICROCODE_OLD_INTERFACE=y
> CONFIG_X86_MSR=y
> CONFIG_X86_CPUID=y
> CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
> CONFIG_ARCH_DMA_ADDR_T_64BIT=y
> CONFIG_DIRECT_GBPAGES=y
> CONFIG_ARCH_SPARSEMEM_ENABLE=y
> CONFIG_ARCH_SPARSEMEM_DEFAULT=y
> CONFIG_ARCH_SELECT_MEMORY_MODEL=y
> CONFIG_ARCH_PROC_KCORE_TEXT=y
> CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
> CONFIG_SELECT_MEMORY_MODEL=y
> CONFIG_SPARSEMEM_MANUAL=y
> CONFIG_SPARSEMEM=y
> CONFIG_HAVE_MEMORY_PRESENT=y
> CONFIG_SPARSEMEM_EXTREME=y
> CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
> CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
> CONFIG_SPARSEMEM_VMEMMAP=y
> CONFIG_HAVE_MEMBLOCK=y
> CONFIG_PAGEFLAGS_EXTENDED=y
> CONFIG_SPLIT_PTLOCK_CPUS=4
> CONFIG_COMPACTION=y
> CONFIG_MIGRATION=y
> CONFIG_PHYS_ADDR_T_64BIT=y
> CONFIG_ZONE_DMA_FLAG=1
> CONFIG_BOUNCE=y
> CONFIG_VIRT_TO_BUS=y
> CONFIG_KSM=y
> CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
> CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
> CONFIG_CLEANCACHE=y
> CONFIG_X86_CHECK_BIOS_CORRUPTION=y
> CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
> CONFIG_X86_RESERVE_LOW=64
> CONFIG_MTRR=y
> CONFIG_MTRR_SANITIZER=y
> CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
> CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
> CONFIG_X86_PAT=y
> CONFIG_ARCH_USES_PG_UNCACHED=y
> CONFIG_SECCOMP=y
> CONFIG_HZ_1000=y
> CONFIG_HZ=1000
> CONFIG_SCHED_HRTICK=y
> CONFIG_KEXEC=y
> CONFIG_CRASH_DUMP=y
> CONFIG_PHYSICAL_START=0x1000000
> CONFIG_RELOCATABLE=y
> CONFIG_PHYSICAL_ALIGN=0x1000000
> CONFIG_HOTPLUG_CPU=y
> CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
> CONFIG_ARCH_HIBERNATION_HEADER=y
> CONFIG_SUSPEND=y
> CONFIG_SUSPEND_FREEZER=y
> CONFIG_HIBERNATE_CALLBACKS=y
> CONFIG_HIBERNATION=y
> CONFIG_PM_STD_PARTITION=""
> CONFIG_PM_SLEEP=y
> CONFIG_PM_SLEEP_SMP=y
> CONFIG_PM_RUNTIME=y
> CONFIG_PM=y
> CONFIG_PM_DEBUG=y
> CONFIG_PM_ADVANCED_DEBUG=y
> CONFIG_PM_TEST_SUSPEND=y
> CONFIG_CAN_PM_TRACE=y
> CONFIG_PM_TRACE=y
> CONFIG_PM_TRACE_RTC=y
> CONFIG_ACPI=y
> CONFIG_ACPI_SLEEP=y
> CONFIG_ACPI_PROC_EVENT=y
> CONFIG_ACPI_BUTTON=y
> CONFIG_ACPI_PROCESSOR=y
> CONFIG_ACPI_HOTPLUG_CPU=y
> CONFIG_ACPI_PROCESSOR_AGGREGATOR=y
> CONFIG_ACPI_THERMAL=y
> CONFIG_ACPI_BLACKLIST_YEAR=0
> CONFIG_X86_PM_TIMER=y
> CONFIG_ACPI_CONTAINER=y
> CONFIG_ACPI_CUSTOM_METHOD=y
> CONFIG_CPU_IDLE=y
> CONFIG_CPU_IDLE_GOV_LADDER=y
> CONFIG_CPU_IDLE_GOV_MENU=y
> CONFIG_PCI=y
> CONFIG_PCI_DIRECT=y
> CONFIG_PCI_MMCONFIG=y
> CONFIG_PCI_DOMAINS=y
> CONFIG_PCIEPORTBUS=y
> CONFIG_PCIEAER=y
> CONFIG_PCIEASPM=y
> CONFIG_PCIE_PME=y
> CONFIG_ARCH_SUPPORTS_MSI=y
> CONFIG_PCI_MSI=y
> CONFIG_HT_IRQ=y
> CONFIG_PCI_IOAPIC=y
> CONFIG_PCI_LABEL=y
> CONFIG_ISA_DMA_API=y
> CONFIG_AMD_NB=y
> CONFIG_BINFMT_ELF=y
> CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
> CONFIG_BINFMT_MISC=y
> CONFIG_HAVE_TEXT_POKE_SMP=y
> CONFIG_NET=y
> CONFIG_PACKET=y
> CONFIG_UNIX=y
> CONFIG_XFRM=y
> CONFIG_XFRM_USER=y
> CONFIG_INET=y
> CONFIG_IP_MULTICAST=y
> CONFIG_IP_ADVANCED_ROUTER=y
> CONFIG_IP_MULTIPLE_TABLES=y
> CONFIG_IP_ROUTE_MULTIPATH=y
> CONFIG_IP_ROUTE_VERBOSE=y
> CONFIG_IP_PNP=y
> CONFIG_IP_PNP_DHCP=y
> CONFIG_IP_PNP_BOOTP=y
> CONFIG_IP_PNP_RARP=y
> CONFIG_IP_MROUTE=y
> CONFIG_IP_PIMSM_V1=y
> CONFIG_IP_PIMSM_V2=y
> CONFIG_SYN_COOKIES=y
> CONFIG_INET_TUNNEL=y
> CONFIG_INET_LRO=y
> CONFIG_TCP_CONG_ADVANCED=y
> CONFIG_TCP_CONG_CUBIC=y
> CONFIG_DEFAULT_CUBIC=y
> CONFIG_DEFAULT_TCP_CONG="cubic"
> CONFIG_TCP_MD5SIG=y
> CONFIG_IPV6=y
> CONFIG_INET6_AH=y
> CONFIG_INET6_ESP=y
> CONFIG_INET6_XFRM_MODE_TRANSPORT=y
> CONFIG_INET6_XFRM_MODE_TUNNEL=y
> CONFIG_INET6_XFRM_MODE_BEET=y
> CONFIG_IPV6_SIT=y
> CONFIG_IPV6_NDISC_NODETYPE=y
> CONFIG_NETWORK_SECMARK=y
> CONFIG_NETFILTER=y
> CONFIG_NETFILTER_NETLINK=y
> CONFIG_NETFILTER_NETLINK_LOG=y
> CONFIG_NF_CONNTRACK=y
> CONFIG_NF_CONNTRACK_SECMARK=y
> CONFIG_NF_CONNTRACK_FTP=y
> CONFIG_NF_CONNTRACK_IRC=y
> CONFIG_NF_CONNTRACK_SIP=y
> CONFIG_NF_CT_NETLINK=y
> CONFIG_NETFILTER_XTABLES=y
> CONFIG_NETFILTER_XT_MARK=y
> CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
> CONFIG_NETFILTER_XT_TARGET_NFLOG=y
> CONFIG_NETFILTER_XT_TARGET_SECMARK=y
> CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
> CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
> CONFIG_NETFILTER_XT_MATCH_POLICY=y
> CONFIG_NETFILTER_XT_MATCH_STATE=y
> CONFIG_NF_DEFRAG_IPV4=y
> CONFIG_NF_CONNTRACK_IPV4=y
> CONFIG_NF_CONNTRACK_PROC_COMPAT=y
> CONFIG_IP_NF_IPTABLES=y
> CONFIG_IP_NF_FILTER=y
> CONFIG_IP_NF_TARGET_REJECT=y
> CONFIG_IP_NF_TARGET_LOG=y
> CONFIG_IP_NF_TARGET_ULOG=y
> CONFIG_NF_NAT=y
> CONFIG_NF_NAT_NEEDED=y
> CONFIG_IP_NF_TARGET_MASQUERADE=y
> CONFIG_NF_NAT_FTP=y
> CONFIG_NF_NAT_IRC=y
> CONFIG_NF_NAT_SIP=y
> CONFIG_IP_NF_MANGLE=y
> CONFIG_NF_DEFRAG_IPV6=y
> CONFIG_NF_CONNTRACK_IPV6=y
> CONFIG_IP6_NF_IPTABLES=y
> CONFIG_IP6_NF_MATCH_IPV6HEADER=y
> CONFIG_IP6_NF_TARGET_LOG=y
> CONFIG_IP6_NF_FILTER=y
> CONFIG_IP6_NF_TARGET_REJECT=y
> CONFIG_IP6_NF_MANGLE=y
> CONFIG_IP_SCTP=y
> CONFIG_SCTP_HMAC_MD5=y
> CONFIG_NET_SCHED=y
> CONFIG_NET_CLS=y
> CONFIG_NET_EMATCH=y
> CONFIG_NET_EMATCH_STACK=32
> CONFIG_NET_CLS_ACT=y
> CONFIG_NET_SCH_FIFO=y
> CONFIG_DNS_RESOLVER=y
> CONFIG_RPS=y
> CONFIG_RFS_ACCEL=y
> CONFIG_XPS=y
> CONFIG_HAVE_BPF_JIT=y
> CONFIG_FIB_RULES=y
> CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
> CONFIG_STANDALONE=y
> CONFIG_PREVENT_FIRMWARE_BUILD=y
> CONFIG_FW_LOADER=y
> CONFIG_FIRMWARE_IN_KERNEL=y
> CONFIG_EXTRA_FIRMWARE=""
> CONFIG_PNP=y
> CONFIG_PNP_DEBUG_MESSAGES=y
> CONFIG_PNPACPI=y
> CONFIG_BLK_DEV=y
> CONFIG_BLK_DEV_LOOP=y
> CONFIG_BLK_DEV_NBD=y
> CONFIG_BLK_DEV_RAM=y
> CONFIG_BLK_DEV_RAM_COUNT=16
> CONFIG_BLK_DEV_RAM_SIZE=16384
> CONFIG_HAVE_IDE=y
> CONFIG_SCSI_MOD=y
> CONFIG_RAID_ATTRS=y
> CONFIG_SCSI=y
> CONFIG_SCSI_DMA=y
> CONFIG_SCSI_PROC_FS=y
> CONFIG_BLK_DEV_SD=y
> CONFIG_ATA=y
> CONFIG_ATA_VERBOSE_ERROR=y
> CONFIG_ATA_ACPI=y
> CONFIG_SATA_AHCI=y
> CONFIG_ATA_SFF=y
> CONFIG_ATA_BMDMA=y
> CONFIG_PATA_JMICRON=y
> CONFIG_ATA_GENERIC=y
> CONFIG_MD=y
> CONFIG_BLK_DEV_MD=y
> CONFIG_MD_AUTODETECT=y
> CONFIG_MD_RAID0=y
> CONFIG_MD_RAID1=y
> CONFIG_BLK_DEV_DM=y
> CONFIG_DM_SNAPSHOT=y
> CONFIG_DM_MIRROR=y
> CONFIG_NETDEVICES=y
> CONFIG_MII=y
> CONFIG_NETDEV_1000=y
> CONFIG_R8169=y
> CONFIG_NETCONSOLE=y
> CONFIG_NETCONSOLE_DYNAMIC=y
> CONFIG_NETPOLL=y
> CONFIG_NET_POLL_CONTROLLER=y
> CONFIG_INPUT=y
> CONFIG_INPUT_FF_MEMLESS=y
> CONFIG_INPUT_POLLDEV=y
> CONFIG_INPUT_SPARSEKMAP=y
> CONFIG_INPUT_MOUSEDEV=y
> CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
> CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
> CONFIG_INPUT_EVDEV=y
> CONFIG_INPUT_KEYBOARD=y
> CONFIG_KEYBOARD_ATKBD=y
> CONFIG_INPUT_MOUSE=y
> CONFIG_MOUSE_PS2=y
> CONFIG_MOUSE_PS2_ALPS=y
> CONFIG_MOUSE_PS2_LOGIPS2PP=y
> CONFIG_MOUSE_PS2_SYNAPTICS=y
> CONFIG_MOUSE_PS2_LIFEBOOK=y
> CONFIG_MOUSE_PS2_TRACKPOINT=y
> CONFIG_INPUT_JOYSTICK=y
> CONFIG_INPUT_TABLET=y
> CONFIG_INPUT_TOUCHSCREEN=y
> CONFIG_INPUT_MISC=y
> CONFIG_SERIO=y
> CONFIG_SERIO_I8042=y
> CONFIG_SERIO_SERPORT=y
> CONFIG_SERIO_LIBPS2=y
> CONFIG_SERIO_RAW=y
> CONFIG_VT=y
> CONFIG_CONSOLE_TRANSLATIONS=y
> CONFIG_VT_CONSOLE=y
> CONFIG_HW_CONSOLE=y
> CONFIG_VT_HW_CONSOLE_BINDING=y
> CONFIG_UNIX98_PTYS=y
> CONFIG_SERIAL_NONSTANDARD=y
> CONFIG_DEVKMEM=y
> CONFIG_SERIAL_8250=y
> CONFIG_SERIAL_8250_CONSOLE=y
> CONFIG_FIX_EARLYCON_MEM=y
> CONFIG_SERIAL_8250_PCI=y
> CONFIG_SERIAL_8250_PNP=y
> CONFIG_SERIAL_8250_NR_UARTS=32
> CONFIG_SERIAL_8250_RUNTIME_UARTS=4
> CONFIG_SERIAL_8250_EXTENDED=y
> CONFIG_SERIAL_8250_MANY_PORTS=y
> CONFIG_SERIAL_8250_SHARE_IRQ=y
> CONFIG_SERIAL_8250_DETECT_IRQ=y
> CONFIG_SERIAL_8250_RSA=y
> CONFIG_SERIAL_CORE=y
> CONFIG_SERIAL_CORE_CONSOLE=y
> CONFIG_HW_RANDOM=y
> CONFIG_HW_RANDOM_INTEL=y
> CONFIG_HW_RANDOM_AMD=y
> CONFIG_HW_RANDOM_VIA=y
> CONFIG_NVRAM=y
> CONFIG_HPET=y
> CONFIG_HANGCHECK_TIMER=y
> CONFIG_DEVPORT=y
> CONFIG_RAMOOPS=y
> CONFIG_I2C=y
> CONFIG_I2C_BOARDINFO=y
> CONFIG_I2C_COMPAT=y
> CONFIG_I2C_HELPER_AUTO=y
> CONFIG_I2C_ALGOBIT=y
> CONFIG_I2C_I801=y
> CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
> CONFIG_HWMON=y
> CONFIG_THERMAL=y
> CONFIG_SSB_POSSIBLE=y
> CONFIG_BCMA_POSSIBLE=y
> CONFIG_AGP=y
> CONFIG_AGP_INTEL=y
> CONFIG_VGA_ARB=y
> CONFIG_VGA_ARB_MAX_GPUS=16
> CONFIG_DRM=y
> CONFIG_BACKLIGHT_LCD_SUPPORT=y
> CONFIG_BACKLIGHT_CLASS_DEVICE=y
> CONFIG_BACKLIGHT_GENERIC=y
> CONFIG_VGA_CONSOLE=y
> CONFIG_VGACON_SOFT_SCROLLBACK=y
> CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
> CONFIG_DUMMY_CONSOLE=y
> CONFIG_RTC_LIB=y
> CONFIG_RTC_CLASS=y
> CONFIG_RTC_INTF_SYSFS=y
> CONFIG_RTC_INTF_PROC=y
> CONFIG_RTC_INTF_DEV=y
> CONFIG_RTC_DRV_CMOS=y
> CONFIG_FIRMWARE_MEMMAP=y
> CONFIG_EXT2_FS=y
> CONFIG_EXT2_FS_XATTR=y
> CONFIG_EXT2_FS_POSIX_ACL=y
> CONFIG_EXT2_FS_SECURITY=y
> CONFIG_EXT2_FS_XIP=y
> CONFIG_EXT3_FS=y
> CONFIG_EXT3_FS_XATTR=y
> CONFIG_EXT3_FS_POSIX_ACL=y
> CONFIG_EXT3_FS_SECURITY=y
> CONFIG_EXT4_FS=y
> CONFIG_EXT4_FS_XATTR=y
> CONFIG_EXT4_FS_POSIX_ACL=y
> CONFIG_EXT4_FS_SECURITY=y
> CONFIG_FS_XIP=y
> CONFIG_JBD=y
> CONFIG_JBD2=y
> CONFIG_FS_MBCACHE=y
> CONFIG_REISERFS_FS=y
> CONFIG_REISERFS_PROC_INFO=y
> CONFIG_REISERFS_FS_XATTR=y
> CONFIG_REISERFS_FS_POSIX_ACL=y
> CONFIG_REISERFS_FS_SECURITY=y
> CONFIG_FS_POSIX_ACL=y
> CONFIG_EXPORTFS=y
> CONFIG_FILE_LOCKING=y
> CONFIG_FSNOTIFY=y
> CONFIG_DNOTIFY=y
> CONFIG_INOTIFY_USER=y
> CONFIG_FANOTIFY=y
> CONFIG_QUOTA=y
> CONFIG_QUOTA_NETLINK_INTERFACE=y
> CONFIG_QUOTACTL=y
> CONFIG_AUTOFS4_FS=y
> CONFIG_FUSE_FS=y
> CONFIG_GENERIC_ACL=y
> CONFIG_FSCACHE=y
> CONFIG_FSCACHE_STATS=y
> CONFIG_FSCACHE_HISTOGRAM=y
> CONFIG_CACHEFILES=y
> CONFIG_CACHEFILES_HISTOGRAM=y
> CONFIG_ISO9660_FS=y
> CONFIG_JOLIET=y
> CONFIG_ZISOFS=y
> CONFIG_FAT_FS=y
> CONFIG_MSDOS_FS=y
> CONFIG_VFAT_FS=y
> CONFIG_FAT_DEFAULT_CODEPAGE=850
> CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
> CONFIG_NTFS_FS=y
> CONFIG_NTFS_RW=y
> CONFIG_PROC_FS=y
> CONFIG_PROC_KCORE=y
> CONFIG_PROC_VMCORE=y
> CONFIG_PROC_SYSCTL=y
> CONFIG_PROC_PAGE_MONITOR=y
> CONFIG_SYSFS=y
> CONFIG_TMPFS=y
> CONFIG_TMPFS_POSIX_ACL=y
> CONFIG_TMPFS_XATTR=y
> CONFIG_CONFIGFS_FS=y
> CONFIG_PARTITION_ADVANCED=y
> CONFIG_MSDOS_PARTITION=y
> CONFIG_BSD_DISKLABEL=y
> CONFIG_MINIX_SUBPARTITION=y
> CONFIG_SOLARIS_X86_PARTITION=y
> CONFIG_UNIXWARE_DISKLABEL=y
> CONFIG_LDM_PARTITION=y
> CONFIG_SUN_PARTITION=y
> CONFIG_EFI_PARTITION=y
> CONFIG_NLS=y
> CONFIG_NLS_DEFAULT="utf8"
> CONFIG_NLS_CODEPAGE_437=y
> CONFIG_NLS_CODEPAGE_850=y
> CONFIG_NLS_ASCII=y
> CONFIG_NLS_ISO8859_1=y
> CONFIG_NLS_ISO8859_15=y
> CONFIG_NLS_UTF8=y
> CONFIG_TRACE_IRQFLAGS_SUPPORT=y
> CONFIG_PRINTK_TIME=y
> CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7
> CONFIG_ENABLE_MUST_CHECK=y
> CONFIG_FRAME_WARN=2048
> CONFIG_MAGIC_SYSRQ=y
> CONFIG_DEBUG_FS=y
> CONFIG_DEBUG_KERNEL=y
> CONFIG_LOCKUP_DETECTOR=y
> CONFIG_HARDLOCKUP_DETECTOR=y
> CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
> CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
> CONFIG_STACKTRACE=y
> CONFIG_DEBUG_BUGVERBOSE=y
> CONFIG_DEBUG_INFO=y
> CONFIG_DEBUG_INFO_REDUCED=y
> CONFIG_DEBUG_MEMORY_INIT=y
> CONFIG_ARCH_WANT_FRAME_POINTERS=y
> CONFIG_FRAME_POINTER=y
> CONFIG_BOOT_PRINTK_DELAY=y
> CONFIG_RCU_CPU_STALL_TIMEOUT=60
> CONFIG_LKDTM=y
> CONFIG_CPU_NOTIFIER_ERROR_INJECT=y
> CONFIG_SYSCTL_SYSCALL_CHECK=y
> CONFIG_USER_STACKTRACE_SUPPORT=y
> CONFIG_NOP_TRACER=y
> CONFIG_HAVE_FUNCTION_TRACER=y
> CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
> CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
> CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
> CONFIG_HAVE_DYNAMIC_FTRACE=y
> CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
> CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
> CONFIG_HAVE_C_RECORDMCOUNT=y
> CONFIG_RING_BUFFER=y
> CONFIG_EVENT_TRACING=y
> CONFIG_EVENT_POWER_TRACING_DEPRECATED=y
> CONFIG_CONTEXT_SWITCH_TRACER=y
> CONFIG_TRACING=y
> CONFIG_GENERIC_TRACER=y
> CONFIG_TRACING_SUPPORT=y
> CONFIG_FTRACE=y
> CONFIG_BRANCH_PROFILE_NONE=y
> CONFIG_BLK_DEV_IO_TRACE=y
> CONFIG_HAVE_ARCH_KGDB=y
> CONFIG_HAVE_ARCH_KMEMCHECK=y
> CONFIG_STRICT_DEVMEM=y
> CONFIG_X86_VERBOSE_BOOTUP=y
> CONFIG_EARLY_PRINTK=y
> CONFIG_DEBUG_RODATA=y
> CONFIG_HAVE_MMIOTRACE_SUPPORT=y
> CONFIG_IO_DELAY_TYPE_0X80=0
> CONFIG_IO_DELAY_TYPE_0XED=1
> CONFIG_IO_DELAY_TYPE_UDELAY=2
> CONFIG_IO_DELAY_TYPE_NONE=3
> CONFIG_IO_DELAY_0X80=y
> CONFIG_DEFAULT_IO_DELAY_TYPE=0
> CONFIG_KEYS=y
> CONFIG_DEFAULT_SECURITY_DAC=y
> CONFIG_DEFAULT_SECURITY=""
> CONFIG_CRYPTO=y
> CONFIG_CRYPTO_ALGAPI=y
> CONFIG_CRYPTO_ALGAPI2=y
> CONFIG_CRYPTO_AEAD=y
> CONFIG_CRYPTO_AEAD2=y
> CONFIG_CRYPTO_BLKCIPHER=y
> CONFIG_CRYPTO_BLKCIPHER2=y
> CONFIG_CRYPTO_HASH=y
> CONFIG_CRYPTO_HASH2=y
> CONFIG_CRYPTO_RNG2=y
> CONFIG_CRYPTO_PCOMP2=y
> CONFIG_CRYPTO_MANAGER=y
> CONFIG_CRYPTO_MANAGER2=y
> CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
> CONFIG_CRYPTO_WORKQUEUE=y
> CONFIG_CRYPTO_AUTHENC=y
> CONFIG_CRYPTO_CBC=y
> CONFIG_CRYPTO_HMAC=y
> CONFIG_CRYPTO_CRC32C=y
> CONFIG_CRYPTO_MD5=y
> CONFIG_CRYPTO_SHA1=y
> CONFIG_CRYPTO_AES=y
> CONFIG_CRYPTO_DES=y
> CONFIG_HAVE_KVM=y
> CONFIG_BINARY_PRINTF=y
> CONFIG_BITREVERSE=y
> CONFIG_GENERIC_FIND_FIRST_BIT=y
> CONFIG_CRC16=y
> CONFIG_CRC32=y
> CONFIG_LIBCRC32C=y
> CONFIG_ZLIB_INFLATE=y
> CONFIG_LZO_COMPRESS=y
> CONFIG_LZO_DECOMPRESS=y
> CONFIG_XZ_DEC=y
> CONFIG_XZ_DEC_X86=y
> CONFIG_XZ_DEC_POWERPC=y
> CONFIG_XZ_DEC_IA64=y
> CONFIG_XZ_DEC_ARM=y
> CONFIG_XZ_DEC_ARMTHUMB=y
> CONFIG_XZ_DEC_SPARC=y
> CONFIG_XZ_DEC_BCJ=y
> CONFIG_DECOMPRESS_GZIP=y
> CONFIG_DECOMPRESS_BZIP2=y
> CONFIG_DECOMPRESS_LZMA=y
> CONFIG_DECOMPRESS_XZ=y
> CONFIG_DECOMPRESS_LZO=y
> CONFIG_HAS_IOMEM=y
> CONFIG_HAS_IOPORT=y
> CONFIG_HAS_DMA=y
> CONFIG_CHECK_SIGNATURE=y
> CONFIG_CPU_RMAP=y
> CONFIG_NLATTR=y
> ----------------
>
> ------ contents of /sys/devices/system/cpu/* after cpu 1 and cpu2 have been turned off -----------
> $ grep -r . /sys/devices/system/cpu/
> grep: /sys/devices/system/cpu/probe: Permission denied
> grep: /sys/devices/system/cpu/release: Permission denied
> /sys/devices/system/cpu/online:0,3
> /sys/devices/system/cpu/possible:0-3
> /sys/devices/system/cpu/present:0-3
> /sys/devices/system/cpu/kernel_max:3
> /sys/devices/system/cpu/offline:1-2
> /sys/devices/system/cpu/cpuidle/current_driver:intel_idle
> /sys/devices/system/cpu/cpuidle/current_governor_ro:menu
> /sys/devices/system/cpu/cpu0/crash_notes:13fc14a10
> /sys/devices/system/cpu/cpu0/cache/index0/type:Data
> /sys/devices/system/cpu/cpu0/cache/index0/level:1
> /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size:64
> /sys/devices/system/cpu/cpu0/cache/index0/physical_line_partition:1
> /sys/devices/system/cpu/cpu0/cache/index0/ways_of_associativity:6
> /sys/devices/system/cpu/cpu0/cache/index0/number_of_sets:64
> /sys/devices/system/cpu/cpu0/cache/index0/size:24K
> /sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_map:9
> /sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list:0,3
> /sys/devices/system/cpu/cpu0/cache/index1/type:Instruction
> /sys/devices/system/cpu/cpu0/cache/index1/level:1
> /sys/devices/system/cpu/cpu0/cache/index1/coherency_line_size:64
> /sys/devices/system/cpu/cpu0/cache/index1/physical_line_partition:1
> /sys/devices/system/cpu/cpu0/cache/index1/ways_of_associativity:8
> /sys/devices/system/cpu/cpu0/cache/index1/number_of_sets:64
> /sys/devices/system/cpu/cpu0/cache/index1/size:32K
> /sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_map:9
> /sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_list:0,3
> /sys/devices/system/cpu/cpu0/cache/index2/type:Unified
> /sys/devices/system/cpu/cpu0/cache/index2/level:2
> /sys/devices/system/cpu/cpu0/cache/index2/coherency_line_size:64
> /sys/devices/system/cpu/cpu0/cache/index2/physical_line_partition:1
> /sys/devices/system/cpu/cpu0/cache/index2/ways_of_associativity:8
> /sys/devices/system/cpu/cpu0/cache/index2/number_of_sets:1024
> /sys/devices/system/cpu/cpu0/cache/index2/size:512K
> /sys/devices/system/cpu/cpu0/cache/index2/shared_cpu_map:9
> /sys/devices/system/cpu/cpu0/cache/index2/shared_cpu_list:0,3
> /sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count:0
> grep: /sys/devices/system/cpu/cpu0/microcode/reload: Permission denied
> /sys/devices/system/cpu/cpu0/microcode/version:0x107
> /sys/devices/system/cpu/cpu0/microcode/processor_flags:0x8
> /sys/devices/system/cpu/cpu0/cpuidle/state0/name:POLL
> /sys/devices/system/cpu/cpu0/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
> /sys/devices/system/cpu/cpu0/cpuidle/state0/latency:0
> /sys/devices/system/cpu/cpu0/cpuidle/state0/power:4294967295
> /sys/devices/system/cpu/cpu0/cpuidle/state0/usage:8
> /sys/devices/system/cpu/cpu0/cpuidle/state0/time:1838938
> /sys/devices/system/cpu/cpu0/cpuidle/state1/name:C1-ATM
> /sys/devices/system/cpu/cpu0/cpuidle/state1/desc:MWAIT 0x00
> /sys/devices/system/cpu/cpu0/cpuidle/state1/latency:1
> /sys/devices/system/cpu/cpu0/cpuidle/state1/power:4294967294
> /sys/devices/system/cpu/cpu0/cpuidle/state1/usage:15944
> /sys/devices/system/cpu/cpu0/cpuidle/state1/time:167329609
> /sys/devices/system/cpu/cpu0/topology/physical_package_id:0
> /sys/devices/system/cpu/cpu0/topology/core_id:0
> /sys/devices/system/cpu/cpu0/topology/thread_siblings:9
> /sys/devices/system/cpu/cpu0/topology/thread_siblings_list:0,3
> /sys/devices/system/cpu/cpu0/topology/core_siblings:9
> /sys/devices/system/cpu/cpu0/topology/core_siblings_list:0,3
> /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq:225000
> /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq:1800000
> /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency:10000001
> /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq:225000
> /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq:1800000
> /sys/devices/system/cpu/cpu0/cpufreq/affected_cpus:0 3
> /sys/devices/system/cpu/cpu0/cpufreq/related_cpus:0 3
> /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor:userspace
> /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver:p4-clockmod
> /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors:ondemand userspace performance
> /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed:1800000
> /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies:225000 450000 675000 900000 1125000 1350000 1575000 1800000
> /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq:1800000
> /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq:1800000
> /sys/devices/system/cpu/cpu1/online:0
> /sys/devices/system/cpu/cpu1/crash_notes:13fc94a10
> /sys/devices/system/cpu/cpu1/cpuidle/state0/name:POLL
> /sys/devices/system/cpu/cpu1/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
> /sys/devices/system/cpu/cpu1/cpuidle/state0/latency:0
> /sys/devices/system/cpu/cpu1/cpuidle/state0/power:4294967295
> /sys/devices/system/cpu/cpu1/cpuidle/state0/usage:10
> /sys/devices/system/cpu/cpu1/cpuidle/state0/time:3742
> /sys/devices/system/cpu/cpu1/cpuidle/state1/name:C1-ATM
> /sys/devices/system/cpu/cpu1/cpuidle/state1/desc:MWAIT 0x00
> /sys/devices/system/cpu/cpu1/cpuidle/state1/latency:1
> /sys/devices/system/cpu/cpu1/cpuidle/state1/power:4294967294
> /sys/devices/system/cpu/cpu1/cpuidle/state1/usage:3388
> /sys/devices/system/cpu/cpu1/cpuidle/state1/time:24732806
> /sys/devices/system/cpu/cpu2/online:0
> /sys/devices/system/cpu/cpu2/crash_notes:13fd14a10
> /sys/devices/system/cpu/cpu2/cpuidle/state0/name:POLL
> /sys/devices/system/cpu/cpu2/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
> /sys/devices/system/cpu/cpu2/cpuidle/state0/latency:0
> /sys/devices/system/cpu/cpu2/cpuidle/state0/power:4294967295
> /sys/devices/system/cpu/cpu2/cpuidle/state0/usage:12
> /sys/devices/system/cpu/cpu2/cpuidle/state0/time:855620
> /sys/devices/system/cpu/cpu2/cpuidle/state1/name:C1-ATM
> /sys/devices/system/cpu/cpu2/cpuidle/state1/desc:MWAIT 0x00
> /sys/devices/system/cpu/cpu2/cpuidle/state1/latency:1
> /sys/devices/system/cpu/cpu2/cpuidle/state1/power:4294967294
> /sys/devices/system/cpu/cpu2/cpuidle/state1/usage:4455
> /sys/devices/system/cpu/cpu2/cpuidle/state1/time:27807198
> /sys/devices/system/cpu/cpu3/online:1
> /sys/devices/system/cpu/cpu3/crash_notes:13fd94a10
> /sys/devices/system/cpu/cpu3/thermal_throttle/core_throttle_count:0
> /sys/devices/system/cpu/cpu3/topology/physical_package_id:0
> /sys/devices/system/cpu/cpu3/topology/core_id:0
> /sys/devices/system/cpu/cpu3/topology/thread_siblings:9
> /sys/devices/system/cpu/cpu3/topology/thread_siblings_list:0,3
> /sys/devices/system/cpu/cpu3/topology/core_siblings:9
> /sys/devices/system/cpu/cpu3/topology/core_siblings_list:0,3
> /sys/devices/system/cpu/cpu3/cache/index0/type:Data
> /sys/devices/system/cpu/cpu3/cache/index0/level:1
> /sys/devices/system/cpu/cpu3/cache/index0/coherency_line_size:64
> /sys/devices/system/cpu/cpu3/cache/index0/physical_line_partition:1
> /sys/devices/system/cpu/cpu3/cache/index0/ways_of_associativity:6
> /sys/devices/system/cpu/cpu3/cache/index0/number_of_sets:64
> /sys/devices/system/cpu/cpu3/cache/index0/size:24K
> /sys/devices/system/cpu/cpu3/cache/index0/shared_cpu_map:9
> /sys/devices/system/cpu/cpu3/cache/index0/shared_cpu_list:0,3
> /sys/devices/system/cpu/cpu3/cache/index1/type:Instruction
> /sys/devices/system/cpu/cpu3/cache/index1/level:1
> /sys/devices/system/cpu/cpu3/cache/index1/coherency_line_size:64
> /sys/devices/system/cpu/cpu3/cache/index1/physical_line_partition:1
> /sys/devices/system/cpu/cpu3/cache/index1/ways_of_associativity:8
> /sys/devices/system/cpu/cpu3/cache/index1/number_of_sets:64
> /sys/devices/system/cpu/cpu3/cache/index1/size:32K
> /sys/devices/system/cpu/cpu3/cache/index1/shared_cpu_map:9
> /sys/devices/system/cpu/cpu3/cache/index1/shared_cpu_list:0,3
> /sys/devices/system/cpu/cpu3/cache/index2/type:Unified
> /sys/devices/system/cpu/cpu3/cache/index2/level:2
> /sys/devices/system/cpu/cpu3/cache/index2/coherency_line_size:64
> /sys/devices/system/cpu/cpu3/cache/index2/physical_line_partition:1
> /sys/devices/system/cpu/cpu3/cache/index2/ways_of_associativity:8
> /sys/devices/system/cpu/cpu3/cache/index2/number_of_sets:1024
> /sys/devices/system/cpu/cpu3/cache/index2/size:512K
> /sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_map:9
> /sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_list:0,3
> grep: /sys/devices/system/cpu/cpu3/microcode/reload: Permission denied
> /sys/devices/system/cpu/cpu3/microcode/version:0x107
> /sys/devices/system/cpu/cpu3/microcode/processor_flags:0x8
> /sys/devices/system/cpu/cpu3/cpuidle/state0/name:POLL
> /sys/devices/system/cpu/cpu3/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
> /sys/devices/system/cpu/cpu3/cpuidle/state0/latency:0
> /sys/devices/system/cpu/cpu3/cpuidle/state0/power:4294967295
> /sys/devices/system/cpu/cpu3/cpuidle/state0/usage:21
> /sys/devices/system/cpu/cpu3/cpuidle/state0/time:2055565
> /sys/devices/system/cpu/cpu3/cpuidle/state1/name:C1-ATM
> /sys/devices/system/cpu/cpu3/cpuidle/state1/desc:MWAIT 0x00
> /sys/devices/system/cpu/cpu3/cpuidle/state1/latency:1
> /sys/devices/system/cpu/cpu3/cpuidle/state1/power:4294967294
> /sys/devices/system/cpu/cpu3/cpuidle/state1/usage:13834
> /sys/devices/system/cpu/cpu3/cpuidle/state1/time:166939905
> ---------------------
>
> ------------------------------ contents of /sys/power/* -----------------
> $ grep -r . /sys/power/
> /sys/power/state:mem disk
> /sys/power/pm_trace:0
> /sys/power/pm_async:1
> /sys/power/wakeup_count:0
> /sys/power/pm_test:[none] core processors platform devices freezer
> /sys/power/disk:[platform] test testproc shutdown reboot
> /sys/power/resume:8:2
> /sys/power/image_size:1628569600
> /sys/power/reserved_size:1048576
> --------------------------------------------------------------------
>
>
> ______________________________________________________
> PixiMail - The secret Freedom
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
>
^ permalink raw reply
* Re: PM / hibernate xfs lock up / xfs_reclaim_inodes_ag
From: Rafael J. Wysocki @ 2011-07-26 20:28 UTC (permalink / raw)
To: Dave Chinner; +Cc: Christoph, Linux PM mailing list, xfs
In-Reply-To: <20110713000332.GM23038@dastard>
On Wednesday, July 13, 2011, Dave Chinner wrote:
> On Tue, Jul 12, 2011 at 06:05:01PM +0200, Christoph wrote:
> > Hi!
> >
> > I'd like you to have a look into this issue:
> >
> > pm-hibernate locks up when using xfs while "Preallocating image memory".
> >
> > https://bugzilla.kernel.org/show_bug.cgi?id=33622
> >
> > I got at least this backtrace (2.6.39.3)
> >
> > tia
> >
> > chris
> >
> >
> >
> > SysRq : Show Blocked State
> >
> > pm-hibernate D 0000000000000000 0 3638 3637 0x00000000
> > ffff8800017bf918 0000000000000082 ffff8800017be010 ffff880000000000
> > ffff8800017be010 ffff88000b8a6170 0000000000013900 ffff8800017bffd8
> > ffff8800017bffd8 0000000000013900 ffffffff8148b020 ffff88000b8a6170
> > Call Trace:
> > [<ffffffff81344ce2>] schedule_timeout+0x22/0xbb
> > [<ffffffff81344b64>] wait_for_common+0xcb/0x148
> > [<ffffffff810408ea>] ? try_to_wake_up+0x18c/0x18c
> > [<ffffffff81345527>] ? down_write+0x2d/0x31
> > [<ffffffff81344c7b>] wait_for_completion+0x18/0x1a
> > [<ffffffffa02374da>] xfs_reclaim_inode+0x74/0x258 [xfs]
> > [<ffffffffa0237853>] xfs_reclaim_inodes_ag+0x195/0x264 [xfs]
> > [<ffffffffa0237974>] xfs_reclaim_inode_shrink+0x52/0x90 [xfs]
> > [<ffffffff810c4e21>] shrink_slab+0xdb/0x151
> > [<ffffffff810c625a>] do_try_to_free_pages+0x204/0x39a
> > [<ffffffff8134ce4e>] ? apic_timer_interrupt+0xe/0x20
> > [<ffffffff810c647f>] shrink_all_memory+0x8f/0xa8
> > [<ffffffff810cc41a>] ? next_online_pgdat+0x20/0x41
> > [<ffffffff8107937d>] hibernate_preallocate_memory+0x1c4/0x30f
> > [<ffffffff811a8fa2>] ? kobject_put+0x47/0x4b
> > [<ffffffff81077eb2>] hibernation_snapshot+0x45/0x281
> > [<ffffffff810781bf>] hibernate+0xd1/0x1b8
> > [<ffffffff81076c58>] state_store+0x57/0xce
> > [<ffffffff811a8d0b>] kobj_attr_store+0x17/0x19
> > [<ffffffff81152bda>] sysfs_write_file+0xfc/0x138
> > [<ffffffff810fca74>] vfs_write+0xa9/0x105
> > [<ffffffff810fcb89>] sys_write+0x45/0x6c
> > [<ffffffff8134c492>] system_call_fastpath+0x16/0x1b
>
> It's waiting for IO completion, and holding an AG scan lock.
>
> And IO completion requires a workqueue to run. Just FYI, this
> process of inode reclaim can dirty the filesystem, long after
> hibernate have assumed that it is clean due to the sys_sync() call
> you do after freezing the processes. I pointed out this flaw in
> using sync to write dirty data prior to hibernate a couple of years
> ago.
However, attempts to remove the sys_sync() from the hibernate code
were objected to by some developers, since they believe it will increase
the probability of data loss in case of a failing hibernation in general.
> Anyway, it's a good thing that XFS doesn't use freezable work
> queues, otherwise it would hang on every hibernate. Perhaps I should
> do that to force hibernate to do things properly in filesystems
> land.
Well, I'd say it's a very well known fact that filesystems are not
handled in any special way during hibernation, which is not a good
thing. Nevertheless, I've never seen anyone from the filesystems land
pay any kind of attention to this issue.
> However, it is entirely possible that something else that XFS relies
> on for IO completion has been put to sleep by this point.
>
> /me finds the smoking cannon:
>
> [ 648.794455] xfsbufd/sda3 D 0000000000000000 0 192 2 0x00000000
> [ 648.794455] ffff88003720be00 0000000000000046 ffff88003720bd90 ffffffff00000000
> [ 648.794455] ffff88003720a010 ffff880056bc3580 0000000000013900 ffff88003720bfd8
> [ 648.794455] ffff88003720bfd8 0000000000013900 ffffffff8148b020 ffff880056bc3580
> [ 648.794455] Call Trace:
> [ 648.794455] [<ffffffff81065c0a>] refrigerator+0xbd/0xd3
> [ 648.794455] [<ffffffffa022d072>] xfsbufd+0x93/0x14d [xfs]
> [ 648.794455] [<ffffffffa022cfdf>] ? xfs_free_buftarg+0x4c/0x4c [xfs]
> [ 648.794455] [<ffffffff8105f25a>] kthread+0x7d/0x85
> [ 648.794455] [<ffffffff8134d6e4>] kernel_thread_helper+0x4/0x10
> [ 648.794455] [<ffffffff8105f1dd>] ? kthread_worker_fn+0x148/0x148
> [ 648.794455] [<ffffffff8134d6e0>] ? gs_change+0x13/0x13
>
> The xfsbufd, responsible for pushing out dirty metadata, has been
> been frozen. sys_sync() does not push out dirty metadata because it
> is already on stable storage in the journal. If the flush lock is
> already held on the inode, then inode reclaim will wait for the
> xfsbufd to flush the backing buffer because reclaim can't do it
> directly. And hibernate has already frozen the xfsbufd.
>
> IOWs, what hibernate does is:
>
> freeze_processes()
> sys_sync()
> allocate a large amount of memory
>
> Freezing the processes causes parts of filesystems to be put in the
> fridge, which means there is no guarantee that sys_sync() actually
> does what it is supposed to. As it is, sys_sync() really only
> guarantees file data is clean in memory - metadata does not need to
> be clean as long s it has been journalled and the journal is safe on
> disk.
>
> Further, allocating memory can cause memory reclaim to enter the
> filesystem and try to free memory held by the filesystem. In XFS (at
> least) this can cause the filesystem to issue tranactions and
> metadata IO to clean the dirty metadata to enable it to be
> reclaimed. So hibernate is effectively guaranteed to dirty the
> filesystem after it has frozen all the worker threads the filesystem
> might rely on.
>
> Also, by this point kswapd has already been frozen, so hibernate is
> relying totally on direct memory reclaim to free up the memory it
> requires. I'm not sure that's a good idea.
>
> IOWs, hibernate is still broken by design - and broken in exactly
> the way that was pointed out a couple of years ago by myself and
> others in the filesystem world: sys_sync() does not quiesce or
> guarantee a clean filesystem in memory after it completes.
>
> There is a solution to this, and it already exists - it's called
> freezing the filesystem. Effectively hibernate needs to allocate
> memory before it freezes kernel/filesystem worker threads:
>
> freeze_userspace_processes()
>
> // just to clean the page cache quickly
> sys_sync()
>
> // optionally to free page/inode/dentry caches:
> iterate_supers(drop_pagecache_sb, NULL);
> drop_slab()
>
> allocate a large amount of memory
>
> // Now quiesce the filesystems and clean remaining metadata
> iterate_supers(freeze_super, NULL);
>
> freeze_remaining_processes()
>
> This guarantees that filesystems are still working when memory
> reclaim comes along to free memory for the hibernate image, and that
> once it is allocated that filesystems will not be changed until
> thawed on the hibernate wakeup.
>
> So, like I said a couple of years ago: fix hibernate to quiesce
> filesystems properly, and the hibernate will be much more reliable
> and robust and less likely to break randomly in the future.
Why don't you simply submit a patch to do that?
Rafael
^ permalink raw reply
* Re: [PATCH v2] PM: runtime: add might_sleep to PM runtime functions
From: Rafael J. Wysocki @ 2011-07-26 22:14 UTC (permalink / raw)
To: Colin Cross; +Cc: linux-pm, linux-kernel
In-Reply-To: <1311627344-8097-1-git-send-email-ccross@android.com>
On Monday, July 25, 2011, Colin Cross wrote:
> Some of the entry points to pm runtime are not safe to
> call in atomic context unless pm_runtime_irq_safe() has
> been called. Inspecting the code, it is not immediately
> obvious that the functions sleep at all, as they run
> inside a spin_lock_irqsave, but under some conditions
> they can drop the lock and turn on irqs.
>
> If a driver incorrectly calls the pm_runtime apis, it can
> cause sleeping and irq processing when it expects to stay
> in atomic context.
>
> Add might_sleep_if to all the __pm_runtime_* entry points
> to enforce correct usage.
>
> Add pm_runtime_put_sync_autosuspend to the list of
> functions that can be called in atomic context.
>
> Signed-off-by: Colin Cross <ccross@android.com>
> ---
> Documentation/power/runtime_pm.txt | 1 +
> drivers/base/power/runtime.c | 15 ++++++++++++---
> 2 files changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
> index c291233..1ad507c 100644
> --- a/Documentation/power/runtime_pm.txt
> +++ b/Documentation/power/runtime_pm.txt
> @@ -469,6 +469,7 @@ pm_runtime_resume()
> pm_runtime_get_sync()
> pm_runtime_put_sync()
> pm_runtime_put_sync_suspend()
> +pm_runtime_put_sync_autosuspend()
>
> 5. Run-time PM Initialization, Device Probing and Removal
>
> diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> index 2e746f8..f3d8583 100644
> --- a/drivers/base/power/runtime.c
> +++ b/drivers/base/power/runtime.c
> @@ -731,13 +731,16 @@ EXPORT_SYMBOL_GPL(pm_schedule_suspend);
> * return immediately if it is larger than zero. Then carry out an idle
> * notification, either synchronous or asynchronous.
> *
> - * This routine may be called in atomic context if the RPM_ASYNC flag is set.
> + * This routine may be called in atomic context if the RPM_ASYNC flag is set,
> + * or if pm_runtime_irq_safe() has been called.
> */
> int __pm_runtime_idle(struct device *dev, int rpmflags)
> {
> unsigned long flags;
> int retval;
>
> + might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
> +
Now that I think of it, perhaps it's better to put the might_sleep()
annotations into the actual code paths that should trigger them instead of
checking the conditions upfront on every call? This way we'll avoid quite
some overhead that's only necessary for debugging.
Thanks,
Rafael
^ permalink raw reply
* Re: better oopsing when frozen
From: Rafael J. Wysocki @ 2011-07-26 22:24 UTC (permalink / raw)
To: Oliver Neukum; +Cc: linux-pm, linux-kernel, Andrew Morton
In-Reply-To: <201107251043.19932.oneukum@suse.de>
Hi,
On Monday, July 25, 2011, Oliver Neukum wrote:
> Hi Rafael,
>
> I had a problem with the kernel stopping the machine forever because I got an
> oops while tasks were frozen. It seems to me that we should thaw when this
> happens. How about this approach?
Well, we do something like this already for the OOM killer (see
oom_killer_disable() and friends), so I think it would be better to
simply extend/modify that mechanism instead of adding a new one
doing almost exactly the same thing.
I have no complaints about adding thaw_in_oops(), though, so long as
Andrew thinks it makes sense.
Thanks,
Rafael
> From 6f3b5e7a5c7ccf3564bdd2e703eba7eee753ecdc Mon Sep 17 00:00:00 2001
> From: Oliver Neukum <oliver@neukum.org>
> Date: Fri, 22 Jul 2011 11:20:19 +0200
> Subject: [PATCH] unfreeze tasks if an oops happens while tasks are frozen
>
> If an oops kills the task suspending or snapshotting
> is system, the system is dead because the action is
> never completed and the tasks never thawed.
>
> Signed-off-by: Oliver Neukum <oneukum@suse.de>
> ---
> include/linux/freezer.h | 1 +
> kernel/panic.c | 2 ++
> kernel/power/process.c | 11 +++++++++++
> 3 files changed, 14 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/freezer.h b/include/linux/freezer.h
> index 1effc8b..9907cf6 100644
> --- a/include/linux/freezer.h
> +++ b/include/linux/freezer.h
> @@ -50,6 +50,7 @@ extern int thaw_process(struct task_struct *p);
> extern void refrigerator(void);
> extern int freeze_processes(void);
> extern void thaw_processes(void);
> +extern void thaw_in_oops(void);
>
> static inline int try_to_freeze(void)
> {
> diff --git a/kernel/panic.c b/kernel/panic.c
> index 6923167..255e662 100644
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -23,6 +23,7 @@
> #include <linux/init.h>
> #include <linux/nmi.h>
> #include <linux/dmi.h>
> +#include <linux/freezer.h>
>
> #define PANIC_TIMER_STEP 100
> #define PANIC_BLINK_SPD 18
> @@ -355,6 +356,7 @@ void oops_exit(void)
> do_oops_enter_exit();
> print_oops_end_marker();
> kmsg_dump(KMSG_DUMP_OOPS);
> + thaw_in_oops();
> }
>
> #ifdef WANT_WARN_ON_SLOWPATH
> diff --git a/kernel/power/process.c b/kernel/power/process.c
> index 0cf3a27..20994cd 100644
> --- a/kernel/power/process.c
> +++ b/kernel/power/process.c
> @@ -22,6 +22,9 @@
> */
> #define TIMEOUT (20 * HZ)
>
> +/* in case we oops while processes are frozen */
> +static bool tasks_fozen = false;
> +
> static inline int freezable(struct task_struct * p)
> {
> if ((p == current) ||
> @@ -131,6 +134,7 @@ static int try_to_freeze_tasks(bool sig_only)
> elapsed_csecs % 100);
> }
>
> + tasks_fozen = (todo == 0);
> return todo ? -EBUSY : 0;
> }
>
> @@ -189,7 +193,14 @@ void thaw_processes(void)
> thaw_workqueues();
> thaw_tasks(true);
> thaw_tasks(false);
> + tasks_fozen = false;
> schedule();
> printk("done.\n");
> }
>
> +void thaw_in_oops(void)
> +{
> + if (tasks_fozen)
> + thaw_processes();
> +}
> +
>
^ permalink raw reply
* Re: better oopsing when frozen
From: Andrew Morton @ 2011-07-26 22:45 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Oliver Neukum, linux-pm, linux-kernel
In-Reply-To: <201107270024.11194.rjw@sisk.pl>
On Wed, 27 Jul 2011 00:24:11 +0200
"Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> > Hi Rafael,
> >
> > I had a problem with the kernel stopping the machine forever because I got an
> > oops while tasks were frozen. It seems to me that we should thaw when this
> > happens. How about this approach?
>
> Well, we do something like this already for the OOM killer (see
> oom_killer_disable() and friends), so I think it would be better to
> simply extend/modify that mechanism instead of adding a new one
> doing almost exactly the same thing.
>
> I have no complaints about adding thaw_in_oops(), though, so long as
> Andrew thinks it makes sense.
mm... The patch as proposed is very simple, direct, explicit. I
suspect that trying to embed this operation within some other one would
end up producing a less clear result. Sometimes we do exceptional and
weird things, and leaving the code exceptional and weird-looking is
better than hiding it in some framework, if you follow what I mean.
It does need some code comments to explain to people what it's doing
and more importantly why it's doing it. Also, something which doesn't
break the build when CONFIG_FREEZER=n would be nice.
^ permalink raw reply
* Re: [PATCH v2] PM: runtime: add might_sleep to PM runtime functions
From: Colin Cross @ 2011-07-26 22:55 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: linux-pm, linux-kernel
In-Reply-To: <201107270014.36910.rjw@sisk.pl>
On Tue, Jul 26, 2011 at 3:14 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, July 25, 2011, Colin Cross wrote:
>> Some of the entry points to pm runtime are not safe to
>> call in atomic context unless pm_runtime_irq_safe() has
>> been called. Inspecting the code, it is not immediately
>> obvious that the functions sleep at all, as they run
>> inside a spin_lock_irqsave, but under some conditions
>> they can drop the lock and turn on irqs.
>>
>> If a driver incorrectly calls the pm_runtime apis, it can
>> cause sleeping and irq processing when it expects to stay
>> in atomic context.
>>
>> Add might_sleep_if to all the __pm_runtime_* entry points
>> to enforce correct usage.
>>
>> Add pm_runtime_put_sync_autosuspend to the list of
>> functions that can be called in atomic context.
>>
>> Signed-off-by: Colin Cross <ccross@android.com>
>> ---
>> Documentation/power/runtime_pm.txt | 1 +
>> drivers/base/power/runtime.c | 15 ++++++++++++---
>> 2 files changed, 13 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
>> index c291233..1ad507c 100644
>> --- a/Documentation/power/runtime_pm.txt
>> +++ b/Documentation/power/runtime_pm.txt
>> @@ -469,6 +469,7 @@ pm_runtime_resume()
>> pm_runtime_get_sync()
>> pm_runtime_put_sync()
>> pm_runtime_put_sync_suspend()
>> +pm_runtime_put_sync_autosuspend()
>>
>> 5. Run-time PM Initialization, Device Probing and Removal
>>
>> diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
>> index 2e746f8..f3d8583 100644
>> --- a/drivers/base/power/runtime.c
>> +++ b/drivers/base/power/runtime.c
>> @@ -731,13 +731,16 @@ EXPORT_SYMBOL_GPL(pm_schedule_suspend);
>> * return immediately if it is larger than zero. Then carry out an idle
>> * notification, either synchronous or asynchronous.
>> *
>> - * This routine may be called in atomic context if the RPM_ASYNC flag is set.
>> + * This routine may be called in atomic context if the RPM_ASYNC flag is set,
>> + * or if pm_runtime_irq_safe() has been called.
>> */
>> int __pm_runtime_idle(struct device *dev, int rpmflags)
>> {
>> unsigned long flags;
>> int retval;
>>
>> + might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
>> +
>
> Now that I think of it, perhaps it's better to put the might_sleep()
> annotations into the actual code paths that should trigger them instead of
> checking the conditions upfront on every call? This way we'll avoid quite
> some overhead that's only necessary for debugging.
>
You can't put the might_sleep after the spin_lock_irqsave(), because
you are always in atomic context, and you can't put it after the
spin_unlock_irq() that triggers the problem because you have already
unconditionally left atomic context.
Anyways, the sleeps happen in a farily rare case, so putting the
might_sleep in a more specific location will hide the errors when
developers perform simple tests. For example, every kmalloc ends up
calling might_sleep_if(flags & __GFP_WAIT), so that putting
kmalloc(..., GFP_KERNEL) will print a stack trace every time, instead
of only the very rare case when kmalloc has to block in a low memory
condition.
The calls are very low overhead - the condition in the
might_sleep_if(), and then in the common case:
if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) || ...)
return;
^ permalink raw reply
* Re: [PATCH v2] PM: runtime: add might_sleep to PM runtime functions
From: Kevin Hilman @ 2011-07-27 0:26 UTC (permalink / raw)
To: Colin Cross; +Cc: linux-pm, linux-kernel
In-Reply-To: <1311627344-8097-1-git-send-email-ccross@android.com>
Colin Cross <ccross@android.com> writes:
> Some of the entry points to pm runtime are not safe to
> call in atomic context unless pm_runtime_irq_safe() has
> been called. Inspecting the code, it is not immediately
> obvious that the functions sleep at all, as they run
> inside a spin_lock_irqsave, but under some conditions
> they can drop the lock and turn on irqs.
>
> If a driver incorrectly calls the pm_runtime apis, it can
> cause sleeping and irq processing when it expects to stay
> in atomic context.
>
> Add might_sleep_if to all the __pm_runtime_* entry points
> to enforce correct usage.
Minor: s/all/most of/, or something similar since in v2, it doesn't
annotate all of the functions anymore, just the main ones likely to be
(mis)used by drivers.
Other than that, looks good...
> Add pm_runtime_put_sync_autosuspend to the list of
> functions that can be called in atomic context.
>
> Signed-off-by: Colin Cross <ccross@android.com>
Reviewed-by: Kevin Hilman <khilman@ti.com>
Kevin
^ permalink raw reply
* Re: [RFC/PATCH v2] PM / Runtime: allow _put_sync() from interrupts-disabled context
From: Kevin Hilman @ 2011-07-27 0:28 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: linux-pm, linux-omap, linux-arm-kernel, Colin Cross
In-Reply-To: <201107240102.09698.rjw@sisk.pl>
"Rafael J. Wysocki" <rjw@sisk.pl> writes:
> On Friday, July 22, 2011, Kevin Hilman wrote:
>> Currently the use of pm_runtime_put_sync() is not safe from
>> interrupts-disabled context because rpm_idle() will release the
>> spinlock and enable interrupts for the idle callbacks. This enables
>> interrupts during a time where interrupts were expected to be
>> disabled, and can have strange side effects on drivers that expected
>> interrupts to be disabled.
>>
>> This is not a bug since the documentation clearly states that only
>> _put_sync_suspend() is safe in IRQ-safe mode.
>>
>> However, pm_runtime_put_sync() could be made safe when in IRQ-safe
>> mode by releasing the spinlock but not re-enabling interrupts, which
>> is what this patch aims to do.
>>
>> Problem was found when using some buggy drivers that set
>> pm_runtime_irq_safe() and used _put_sync() in interrupts-disabled
>> context.
>>
>> The offending drivers have been fixed to use _put_sync_suspend(),
>> But this patch is an RFC to see if it might make sense to allow
>> using _put_sync() from interrupts-disabled context.
>
> OK, I'm going to take this for 3.2.
>
OK, great. Thanks.
Might want to just drop the last paragraph from the changelog since it
doesn't really belong in the permanant history.
Kevin
^ permalink raw reply
* Re: PM / hibernate xfs lock up / xfs_reclaim_inodes_ag
From: Dave Chinner @ 2011-07-27 0:45 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Christoph, Linux PM mailing list, xfs
In-Reply-To: <201107262228.12099.rjw@sisk.pl>
On Tue, Jul 26, 2011 at 10:28:11PM +0200, Rafael J. Wysocki wrote:
> On Wednesday, July 13, 2011, Dave Chinner wrote:
> > On Tue, Jul 12, 2011 at 06:05:01PM +0200, Christoph wrote:
.....
> > > SysRq : Show Blocked State
> > >
> > > pm-hibernate D 0000000000000000 0 3638 3637 0x00000000
> > > ffff8800017bf918 0000000000000082 ffff8800017be010 ffff880000000000
> > > ffff8800017be010 ffff88000b8a6170 0000000000013900 ffff8800017bffd8
> > > ffff8800017bffd8 0000000000013900 ffffffff8148b020 ffff88000b8a6170
> > > Call Trace:
> > > [<ffffffff81344ce2>] schedule_timeout+0x22/0xbb
> > > [<ffffffff81344b64>] wait_for_common+0xcb/0x148
> > > [<ffffffff810408ea>] ? try_to_wake_up+0x18c/0x18c
> > > [<ffffffff81345527>] ? down_write+0x2d/0x31
> > > [<ffffffff81344c7b>] wait_for_completion+0x18/0x1a
> > > [<ffffffffa02374da>] xfs_reclaim_inode+0x74/0x258 [xfs]
> > > [<ffffffffa0237853>] xfs_reclaim_inodes_ag+0x195/0x264 [xfs]
> > > [<ffffffffa0237974>] xfs_reclaim_inode_shrink+0x52/0x90 [xfs]
> > > [<ffffffff810c4e21>] shrink_slab+0xdb/0x151
> > > [<ffffffff810c625a>] do_try_to_free_pages+0x204/0x39a
> > > [<ffffffff8134ce4e>] ? apic_timer_interrupt+0xe/0x20
> > > [<ffffffff810c647f>] shrink_all_memory+0x8f/0xa8
> > > [<ffffffff810cc41a>] ? next_online_pgdat+0x20/0x41
> > > [<ffffffff8107937d>] hibernate_preallocate_memory+0x1c4/0x30f
> > > [<ffffffff811a8fa2>] ? kobject_put+0x47/0x4b
> > > [<ffffffff81077eb2>] hibernation_snapshot+0x45/0x281
> > > [<ffffffff810781bf>] hibernate+0xd1/0x1b8
> > > [<ffffffff81076c58>] state_store+0x57/0xce
> > > [<ffffffff811a8d0b>] kobj_attr_store+0x17/0x19
> > > [<ffffffff81152bda>] sysfs_write_file+0xfc/0x138
> > > [<ffffffff810fca74>] vfs_write+0xa9/0x105
> > > [<ffffffff810fcb89>] sys_write+0x45/0x6c
> > > [<ffffffff8134c492>] system_call_fastpath+0x16/0x1b
> >
> > It's waiting for IO completion, and holding an AG scan lock.
> >
> > And IO completion requires a workqueue to run. Just FYI, this
> > process of inode reclaim can dirty the filesystem, long after
> > hibernate have assumed that it is clean due to the sys_sync() call
> > you do after freezing the processes. I pointed out this flaw in
> > using sync to write dirty data prior to hibernate a couple of years
> > ago.
>
> However, attempts to remove the sys_sync() from the hibernate code
> were objected to by some developers, since they believe it will increase
> the probability of data loss in case of a failing hibernation in general.
I'm not suggesting it gets removed, I'm suggesting it gets replaced
because it doesn't give the guarantees that you want or need.
> > Anyway, it's a good thing that XFS doesn't use freezable work
> > queues, otherwise it would hang on every hibernate. Perhaps I should
> > do that to force hibernate to do things properly in filesystems
> > land.
>
> Well, I'd say it's a very well known fact that filesystems are not
> handled in any special way during hibernation, which is not a good
> thing. Nevertheless, I've never seen anyone from the filesystems land
> pay any kind of attention to this issue.
I beg to differ. We went through this exact clas of bugs with swsusp
back in 2006:
https://lkml.org/lkml/2006/11/12/144
And this patch:
https://lkml.org/lkml/2006/11/1/155
([PATCH -mm] swsusp: Freeze filesystems during suspend)
"This is needed by swsusp, because some filesystems (eg. XFS) use
work queues and worker_threads run with PF_NOFREEZE set, so they can
cause some writes to be performed after the suspend image has been
created which may corrupt the filesystem. The additional benefit of
it is that if the resume fails, the filesystems will be in a
consistent state and there won't be any journal replays needed."
--
And the patch essentially does:
- sys_sync();
+ freeze_filesystems();
But, Pavel didn't like freezing filesystems to quiesce them
correctly, so the sys_sync() and all it's problems have remained
until this day, where we still have users tripping over the same
"filesystem not idle" problems.
[....]
> > IOWs, what hibernate does is:
> >
> > freeze_processes()
> > sys_sync()
> > allocate a large amount of memory
> >
> > Freezing the processes causes parts of filesystems to be put in the
> > fridge, which means there is no guarantee that sys_sync() actually
> > does what it is supposed to. As it is, sys_sync() really only
> > guarantees file data is clean in memory - metadata does not need to
> > be clean as long s it has been journalled and the journal is safe on
> > disk.
> >
> > Further, allocating memory can cause memory reclaim to enter the
> > filesystem and try to free memory held by the filesystem. In XFS (at
> > least) this can cause the filesystem to issue tranactions and
> > metadata IO to clean the dirty metadata to enable it to be
> > reclaimed. So hibernate is effectively guaranteed to dirty the
> > filesystem after it has frozen all the worker threads the filesystem
> > might rely on.
> >
> > Also, by this point kswapd has already been frozen, so hibernate is
> > relying totally on direct memory reclaim to free up the memory it
> > requires. I'm not sure that's a good idea.
> >
> > IOWs, hibernate is still broken by design - and broken in exactly
> > the way that was pointed out a couple of years ago by myself and
> > others in the filesystem world: sys_sync() does not quiesce or
> > guarantee a clean filesystem in memory after it completes.
> >
> > There is a solution to this, and it already exists - it's called
> > freezing the filesystem. Effectively hibernate needs to allocate
> > memory before it freezes kernel/filesystem worker threads:
> >
> > freeze_userspace_processes()
> >
> > // just to clean the page cache quickly
> > sys_sync()
> >
> > // optionally to free page/inode/dentry caches:
> > iterate_supers(drop_pagecache_sb, NULL);
> > drop_slab()
> >
> > allocate a large amount of memory
> >
> > // Now quiesce the filesystems and clean remaining metadata
> > iterate_supers(freeze_super, NULL);
> >
> > freeze_remaining_processes()
> >
> > This guarantees that filesystems are still working when memory
> > reclaim comes along to free memory for the hibernate image, and that
> > once it is allocated that filesystems will not be changed until
> > thawed on the hibernate wakeup.
> >
> > So, like I said a couple of years ago: fix hibernate to quiesce
> > filesystems properly, and the hibernate will be much more reliable
> > and robust and less likely to break randomly in the future.
>
> Why don't you simply submit a patch to do that?
a) I don't know how to test suspend/hibernate
b) I don't have any hardware I can test it on.
c) I don't scale to solving every problem Linux has
d) you guys need to decide how you're going to fix this because the
problem has already been solved once before and it didn't get merged
because nobody in the swsusp/hibernate world could agree on anything
at the time.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
^ permalink raw reply
* Re: better oopsing when frozen
From: Rafael J. Wysocki @ 2011-07-27 9:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: Oliver Neukum, linux-pm, linux-kernel
In-Reply-To: <20110726154502.14c7b51b.akpm@linux-foundation.org>
On Wednesday, July 27, 2011, Andrew Morton wrote:
> On Wed, 27 Jul 2011 00:24:11 +0200
> "Rafael J. Wysocki" <rjw@sisk.pl> wrote:
>
> > > Hi Rafael,
> > >
> > > I had a problem with the kernel stopping the machine forever because I got an
> > > oops while tasks were frozen. It seems to me that we should thaw when this
> > > happens. How about this approach?
> >
> > Well, we do something like this already for the OOM killer (see
> > oom_killer_disable() and friends), so I think it would be better to
> > simply extend/modify that mechanism instead of adding a new one
> > doing almost exactly the same thing.
> >
> > I have no complaints about adding thaw_in_oops(), though, so long as
> > Andrew thinks it makes sense.
>
> mm... The patch as proposed is very simple, direct, explicit. I
> suspect that trying to embed this operation within some other one would
> end up producing a less clear result. Sometimes we do exceptional and
> weird things, and leaving the code exceptional and weird-looking is
> better than hiding it in some framework, if you follow what I mean.
My point is that instead of using the oom_killer_disabled variable in
page_alloc.c, we could use a oom_killer_disabled() function returning
the value of the new tasks_are_frozen variable. Then,
oom_killer_disable/enable() won't be necessary any more.
> It does need some code comments to explain to people what it's doing
> and more importantly why it's doing it. Also, something which doesn't
> break the build when CONFIG_FREEZER=n would be nice.
Right.
Thanks,
Rafael
^ permalink raw reply
* Re: [RFC/PATCH v2] PM / Runtime: allow _put_sync() from interrupts-disabled context
From: Rafael J. Wysocki @ 2011-07-27 9:22 UTC (permalink / raw)
To: Kevin Hilman; +Cc: linux-pm, linux-omap, linux-arm-kernel, Colin Cross
In-Reply-To: <87r55cpnwo.fsf@ti.com>
On Wednesday, July 27, 2011, Kevin Hilman wrote:
> "Rafael J. Wysocki" <rjw@sisk.pl> writes:
>
> > On Friday, July 22, 2011, Kevin Hilman wrote:
> >> Currently the use of pm_runtime_put_sync() is not safe from
> >> interrupts-disabled context because rpm_idle() will release the
> >> spinlock and enable interrupts for the idle callbacks. This enables
> >> interrupts during a time where interrupts were expected to be
> >> disabled, and can have strange side effects on drivers that expected
> >> interrupts to be disabled.
> >>
> >> This is not a bug since the documentation clearly states that only
> >> _put_sync_suspend() is safe in IRQ-safe mode.
> >>
> >> However, pm_runtime_put_sync() could be made safe when in IRQ-safe
> >> mode by releasing the spinlock but not re-enabling interrupts, which
> >> is what this patch aims to do.
> >>
> >> Problem was found when using some buggy drivers that set
> >> pm_runtime_irq_safe() and used _put_sync() in interrupts-disabled
> >> context.
> >>
> >> The offending drivers have been fixed to use _put_sync_suspend(),
> >> But this patch is an RFC to see if it might make sense to allow
> >> using _put_sync() from interrupts-disabled context.
> >
> > OK, I'm going to take this for 3.2.
> >
>
> OK, great. Thanks.
>
> Might want to just drop the last paragraph from the changelog since it
> doesn't really belong in the permanant history.
OK
Thanks,
Rafael
^ permalink raw reply
* Re: PM / hibernate xfs lock up / xfs_reclaim_inodes_ag
From: Rafael J. Wysocki @ 2011-07-27 9:35 UTC (permalink / raw)
To: Dave Chinner; +Cc: Christoph, Linux PM mailing list, xfs
In-Reply-To: <20110727004543.GE8048@dastard>
On Wednesday, July 27, 2011, Dave Chinner wrote:
> On Tue, Jul 26, 2011 at 10:28:11PM +0200, Rafael J. Wysocki wrote:
> > On Wednesday, July 13, 2011, Dave Chinner wrote:
> > > On Tue, Jul 12, 2011 at 06:05:01PM +0200, Christoph wrote:
> .....
> > > > SysRq : Show Blocked State
> > > >
> > > > pm-hibernate D 0000000000000000 0 3638 3637 0x00000000
> > > > ffff8800017bf918 0000000000000082 ffff8800017be010 ffff880000000000
> > > > ffff8800017be010 ffff88000b8a6170 0000000000013900 ffff8800017bffd8
> > > > ffff8800017bffd8 0000000000013900 ffffffff8148b020 ffff88000b8a6170
> > > > Call Trace:
> > > > [<ffffffff81344ce2>] schedule_timeout+0x22/0xbb
> > > > [<ffffffff81344b64>] wait_for_common+0xcb/0x148
> > > > [<ffffffff810408ea>] ? try_to_wake_up+0x18c/0x18c
> > > > [<ffffffff81345527>] ? down_write+0x2d/0x31
> > > > [<ffffffff81344c7b>] wait_for_completion+0x18/0x1a
> > > > [<ffffffffa02374da>] xfs_reclaim_inode+0x74/0x258 [xfs]
> > > > [<ffffffffa0237853>] xfs_reclaim_inodes_ag+0x195/0x264 [xfs]
> > > > [<ffffffffa0237974>] xfs_reclaim_inode_shrink+0x52/0x90 [xfs]
> > > > [<ffffffff810c4e21>] shrink_slab+0xdb/0x151
> > > > [<ffffffff810c625a>] do_try_to_free_pages+0x204/0x39a
> > > > [<ffffffff8134ce4e>] ? apic_timer_interrupt+0xe/0x20
> > > > [<ffffffff810c647f>] shrink_all_memory+0x8f/0xa8
> > > > [<ffffffff810cc41a>] ? next_online_pgdat+0x20/0x41
> > > > [<ffffffff8107937d>] hibernate_preallocate_memory+0x1c4/0x30f
> > > > [<ffffffff811a8fa2>] ? kobject_put+0x47/0x4b
> > > > [<ffffffff81077eb2>] hibernation_snapshot+0x45/0x281
> > > > [<ffffffff810781bf>] hibernate+0xd1/0x1b8
> > > > [<ffffffff81076c58>] state_store+0x57/0xce
> > > > [<ffffffff811a8d0b>] kobj_attr_store+0x17/0x19
> > > > [<ffffffff81152bda>] sysfs_write_file+0xfc/0x138
> > > > [<ffffffff810fca74>] vfs_write+0xa9/0x105
> > > > [<ffffffff810fcb89>] sys_write+0x45/0x6c
> > > > [<ffffffff8134c492>] system_call_fastpath+0x16/0x1b
> > >
> > > It's waiting for IO completion, and holding an AG scan lock.
> > >
> > > And IO completion requires a workqueue to run. Just FYI, this
> > > process of inode reclaim can dirty the filesystem, long after
> > > hibernate have assumed that it is clean due to the sys_sync() call
> > > you do after freezing the processes. I pointed out this flaw in
> > > using sync to write dirty data prior to hibernate a couple of years
> > > ago.
> >
> > However, attempts to remove the sys_sync() from the hibernate code
> > were objected to by some developers, since they believe it will increase
> > the probability of data loss in case of a failing hibernation in general.
>
> I'm not suggesting it gets removed, I'm suggesting it gets replaced
> because it doesn't give the guarantees that you want or need.
>
> > > Anyway, it's a good thing that XFS doesn't use freezable work
> > > queues, otherwise it would hang on every hibernate. Perhaps I should
> > > do that to force hibernate to do things properly in filesystems
> > > land.
> >
> > Well, I'd say it's a very well known fact that filesystems are not
> > handled in any special way during hibernation, which is not a good
> > thing. Nevertheless, I've never seen anyone from the filesystems land
> > pay any kind of attention to this issue.
>
> I beg to differ. We went through this exact clas of bugs with swsusp
> back in 2006:
>
> https://lkml.org/lkml/2006/11/12/144
You're right, sorry. We discussed this 5 years ago, but the context
was a bit different (the hibernation code was using a different
mechanism for freeing memory).
> And this patch:
>
> https://lkml.org/lkml/2006/11/1/155
>
> ([PATCH -mm] swsusp: Freeze filesystems during suspend)
>
> "This is needed by swsusp, because some filesystems (eg. XFS) use
> work queues and worker_threads run with PF_NOFREEZE set, so they can
> cause some writes to be performed after the suspend image has been
> created which may corrupt the filesystem. The additional benefit of
> it is that if the resume fails, the filesystems will be in a
> consistent state and there won't be any journal replays needed."
>
> --
>
> And the patch essentially does:
>
> - sys_sync();
> + freeze_filesystems();
Well, if you still think the patch does the right thing, I can rebase it
on top of the current freezer code and resubmit.
> But, Pavel didn't like freezing filesystems to quiesce them
> correctly, so the sys_sync() and all it's problems have remained
> until this day, where we still have users tripping over the same
> "filesystem not idle" problems.
The problem seems to be quite specific to XFS, though.
The Pavel's objection, if I remember it correctly, was that some
(or the majority of?) filesystems didn't implement the freezing operation,
so they would be more vulnerable to data loss in case of a failing hibernation
after this change. However, that's better than actively causing pain to XFS
users.
>
> [....]
>
> > > IOWs, what hibernate does is:
> > >
> > > freeze_processes()
> > > sys_sync()
> > > allocate a large amount of memory
> > >
> > > Freezing the processes causes parts of filesystems to be put in the
> > > fridge, which means there is no guarantee that sys_sync() actually
> > > does what it is supposed to. As it is, sys_sync() really only
> > > guarantees file data is clean in memory - metadata does not need to
> > > be clean as long s it has been journalled and the journal is safe on
> > > disk.
> > >
> > > Further, allocating memory can cause memory reclaim to enter the
> > > filesystem and try to free memory held by the filesystem. In XFS (at
> > > least) this can cause the filesystem to issue tranactions and
> > > metadata IO to clean the dirty metadata to enable it to be
> > > reclaimed. So hibernate is effectively guaranteed to dirty the
> > > filesystem after it has frozen all the worker threads the filesystem
> > > might rely on.
> > >
> > > Also, by this point kswapd has already been frozen, so hibernate is
> > > relying totally on direct memory reclaim to free up the memory it
> > > requires. I'm not sure that's a good idea.
> > >
> > > IOWs, hibernate is still broken by design - and broken in exactly
> > > the way that was pointed out a couple of years ago by myself and
> > > others in the filesystem world: sys_sync() does not quiesce or
> > > guarantee a clean filesystem in memory after it completes.
> > >
> > > There is a solution to this, and it already exists - it's called
> > > freezing the filesystem. Effectively hibernate needs to allocate
> > > memory before it freezes kernel/filesystem worker threads:
> > >
> > > freeze_userspace_processes()
> > >
> > > // just to clean the page cache quickly
> > > sys_sync()
> > >
> > > // optionally to free page/inode/dentry caches:
> > > iterate_supers(drop_pagecache_sb, NULL);
> > > drop_slab()
> > >
> > > allocate a large amount of memory
> > >
> > > // Now quiesce the filesystems and clean remaining metadata
> > > iterate_supers(freeze_super, NULL);
> > >
> > > freeze_remaining_processes()
> > >
> > > This guarantees that filesystems are still working when memory
> > > reclaim comes along to free memory for the hibernate image, and that
> > > once it is allocated that filesystems will not be changed until
> > > thawed on the hibernate wakeup.
> > >
> > > So, like I said a couple of years ago: fix hibernate to quiesce
> > > filesystems properly, and the hibernate will be much more reliable
> > > and robust and less likely to break randomly in the future.
> >
> > Why don't you simply submit a patch to do that?
>
> a) I don't know how to test suspend/hibernate
> b) I don't have any hardware I can test it on.
> c) I don't scale to solving every problem Linux has
> d) you guys need to decide how you're going to fix this because the
> problem has already been solved once before and it didn't get merged
> because nobody in the swsusp/hibernate world could agree on anything
> at the time.
OK, I'm not a filesystem expert in turn.
As I said, I can revive the Nigel's patch if you think it's better than
the code we have, but I'm afraid that's all I can do without any help from
the filesystems people.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH v2] PM: runtime: add might_sleep to PM runtime functions
From: Rafael J. Wysocki @ 2011-07-27 9:37 UTC (permalink / raw)
To: Colin Cross; +Cc: linux-pm, linux-kernel
In-Reply-To: <CAMbhsRTrnPxXUt8Q-VDz5GG8=607QSpcoXJsPLQtPaAZfHKjRA@mail.gmail.com>
On Wednesday, July 27, 2011, Colin Cross wrote:
> On Tue, Jul 26, 2011 at 3:14 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Monday, July 25, 2011, Colin Cross wrote:
> >> Some of the entry points to pm runtime are not safe to
> >> call in atomic context unless pm_runtime_irq_safe() has
> >> been called. Inspecting the code, it is not immediately
> >> obvious that the functions sleep at all, as they run
> >> inside a spin_lock_irqsave, but under some conditions
> >> they can drop the lock and turn on irqs.
> >>
> >> If a driver incorrectly calls the pm_runtime apis, it can
> >> cause sleeping and irq processing when it expects to stay
> >> in atomic context.
> >>
> >> Add might_sleep_if to all the __pm_runtime_* entry points
> >> to enforce correct usage.
> >>
> >> Add pm_runtime_put_sync_autosuspend to the list of
> >> functions that can be called in atomic context.
> >>
> >> Signed-off-by: Colin Cross <ccross@android.com>
> >> ---
> >> Documentation/power/runtime_pm.txt | 1 +
> >> drivers/base/power/runtime.c | 15 ++++++++++++---
> >> 2 files changed, 13 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
> >> index c291233..1ad507c 100644
> >> --- a/Documentation/power/runtime_pm.txt
> >> +++ b/Documentation/power/runtime_pm.txt
> >> @@ -469,6 +469,7 @@ pm_runtime_resume()
> >> pm_runtime_get_sync()
> >> pm_runtime_put_sync()
> >> pm_runtime_put_sync_suspend()
> >> +pm_runtime_put_sync_autosuspend()
> >>
> >> 5. Run-time PM Initialization, Device Probing and Removal
> >>
> >> diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> >> index 2e746f8..f3d8583 100644
> >> --- a/drivers/base/power/runtime.c
> >> +++ b/drivers/base/power/runtime.c
> >> @@ -731,13 +731,16 @@ EXPORT_SYMBOL_GPL(pm_schedule_suspend);
> >> * return immediately if it is larger than zero. Then carry out an idle
> >> * notification, either synchronous or asynchronous.
> >> *
> >> - * This routine may be called in atomic context if the RPM_ASYNC flag is set.
> >> + * This routine may be called in atomic context if the RPM_ASYNC flag is set,
> >> + * or if pm_runtime_irq_safe() has been called.
> >> */
> >> int __pm_runtime_idle(struct device *dev, int rpmflags)
> >> {
> >> unsigned long flags;
> >> int retval;
> >>
> >> + might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
> >> +
> >
> > Now that I think of it, perhaps it's better to put the might_sleep()
> > annotations into the actual code paths that should trigger them instead of
> > checking the conditions upfront on every call? This way we'll avoid quite
> > some overhead that's only necessary for debugging.
> >
>
> You can't put the might_sleep after the spin_lock_irqsave(), because
> you are always in atomic context, and you can't put it after the
> spin_unlock_irq() that triggers the problem because you have already
> unconditionally left atomic context.
>
> Anyways, the sleeps happen in a farily rare case, so putting the
> might_sleep in a more specific location will hide the errors when
> developers perform simple tests. For example, every kmalloc ends up
> calling might_sleep_if(flags & __GFP_WAIT), so that putting
> kmalloc(..., GFP_KERNEL) will print a stack trace every time, instead
> of only the very rare case when kmalloc has to block in a low memory
> condition.
>
> The calls are very low overhead - the condition in the
> might_sleep_if(), and then in the common case:
> if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) || ...)
> return;
OK, I'm going to take the $subject patch for 3.2.
Thanks,
Rafael
^ permalink raw reply
* [PATCHv4 04/11] PM: Use *_dec_not_zero instead of *_add_unless
From: Sven Eckelmann @ 2011-07-27 9:47 UTC (permalink / raw)
To: linux-arch; +Cc: Len Brown, linux-kernel, linux-pm, Sven Eckelmann
In-Reply-To: <1311760070-21532-1-git-send-email-sven@narfation.org>
atomic_dec_not_zero is defined for each architecture through
<linux/atomic.h> to provide the functionality of
atomic_add_unless(x, -1, 0).
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Cc: Len Brown <len.brown@intel.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: linux-pm@lists.linux-foundation.org
---
drivers/base/power/runtime.c | 4 ++--
include/linux/pm_runtime.h | 2 +-
kernel/power/hibernate.c | 4 ++--
kernel/power/user.c | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 8dc247c..bda10d9 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -401,7 +401,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
if (dev->parent) {
parent = dev->parent;
- atomic_add_unless(&parent->power.child_count, -1, 0);
+ atomic_dec_not_zero(&parent->power.child_count);
}
}
wake_up_all(&dev->power.wait_queue);
@@ -841,7 +841,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
if (status == RPM_SUSPENDED) {
/* It always is possible to set the status to 'suspended'. */
if (parent) {
- atomic_add_unless(&parent->power.child_count, -1, 0);
+ atomic_dec_not_zero(&parent->power.child_count);
notify_parent = !parent->power.ignore_children;
}
goto out_set;
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index daac05d..3b4931c 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -63,7 +63,7 @@ static inline void pm_runtime_get_noresume(struct device *dev)
static inline void pm_runtime_put_noidle(struct device *dev)
{
- atomic_add_unless(&dev->power.usage_count, -1, 0);
+ atomic_dec_not_zero(&dev->power.usage_count);
}
static inline bool device_run_wake(struct device *dev)
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 8f7b1db..0ba8d87 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -606,7 +606,7 @@ int hibernate(void)
mutex_lock(&pm_mutex);
/* The snapshot device should not be opened while we're running */
- if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
+ if (!atomic_dec_not_zero(&snapshot_device_available)) {
error = -EBUSY;
goto Unlock;
}
@@ -756,7 +756,7 @@ static int software_resume(void)
goto Unlock;
/* The snapshot device should not be opened while we're running */
- if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
+ if (!atomic_dec_not_zero(&snapshot_device_available)) {
error = -EBUSY;
swsusp_close(FMODE_READ);
goto Unlock;
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 42ddbc6..1c1cc01 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -72,7 +72,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
mutex_lock(&pm_mutex);
- if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
+ if (!atomic_dec_not_zero(&snapshot_device_available)) {
error = -EBUSY;
goto Unlock;
}
--
1.7.5.4
^ permalink raw reply related
* Re: better oopsing when frozen
From: Oliver Neukum @ 2011-07-27 10:23 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Andrew Morton, linux-pm, linux-kernel
In-Reply-To: <201107271121.21348.rjw@sisk.pl>
Am Mittwoch, 27. Juli 2011, 11:21:21 schrieb Rafael J. Wysocki:
> > mm... The patch as proposed is very simple, direct, explicit. I
> > suspect that trying to embed this operation within some other one would
> > end up producing a less clear result. Sometimes we do exceptional and
> > weird things, and leaving the code exceptional and weird-looking is
> > better than hiding it in some framework, if you follow what I mean.
>
> My point is that instead of using the oom_killer_disabled variable in
> page_alloc.c, we could use a oom_killer_disabled() function returning
> the value of the new tasks_are_frozen variable. Then,
> oom_killer_disable/enable() won't be necessary any more.
Well, if we do this, it'll be a separate change. Not that I disagree.
Regards
Oliver
--
- - -
SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg)
Maxfeldstraße 5
90409 Nürnberg
Germany
- - -
^ permalink raw reply
* Re: PM / hibernate xfs lock up / xfs_reclaim_inodes_ag
From: Christoph Hellwig @ 2011-07-27 10:33 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Christoph, Dave Chinner, xfs, Linux PM mailing list
In-Reply-To: <201107271135.13297.rjw@sisk.pl>
On Wed, Jul 27, 2011 at 11:35:13AM +0200, Rafael J. Wysocki wrote:
> The Pavel's objection, if I remember it correctly, was that some
> (or the majority of?) filesystems didn't implement the freezing operation,
> so they would be more vulnerable to data loss in case of a failing hibernation
> after this change. However, that's better than actively causing pain to XFS
> users.
The objection never made sense and only means he never read the code.
freeze_super (or freeze_bdev back then) always does a sync_filesystem
before even checking if we have a freeze method, and sync_filesystem is
what we iterate over for each superblock in sync().
^ permalink raw reply
* [PATCH] Unfreeze tasks after an oops in the freezer
From: Oliver Neukum @ 2011-07-27 10:35 UTC (permalink / raw)
To: Andrew Morton, Rafael J. Wysocki, linux-pm, linux-kernel
>From ee5849f0bc39d554ef91747ff80c307ac3e05cdd Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oliver@neukum.org>
Date: Wed, 27 Jul 2011 12:27:00 +0200
Subject: [PATCH] Unfreeze tasks after an oops in the freezer
If an oops kills the task suspending or snapshotting
is system, the system is dead because the action is
never completed and the tasks never thawed.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
---
include/linux/freezer.h | 2 ++
kernel/panic.c | 8 ++++++++
kernel/power/process.c | 11 +++++++++++
3 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 1effc8b..ab0168a 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -50,6 +50,7 @@ extern int thaw_process(struct task_struct *p);
extern void refrigerator(void);
extern int freeze_processes(void);
extern void thaw_processes(void);
+extern void thaw_in_oops(void);
static inline int try_to_freeze(void)
{
@@ -181,6 +182,7 @@ static inline void freezer_count(void) {}
static inline int freezer_should_skip(struct task_struct *p) { return 0; }
static inline void set_freezable(void) {}
static inline void set_freezable_with_signal(void) {}
+static inline void thaw_in_oops(void) {}
#define wait_event_freezable(wq, condition) \
wait_event_interruptible(wq, condition)
diff --git a/kernel/panic.c b/kernel/panic.c
index 6923167..ccdd834 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/nmi.h>
#include <linux/dmi.h>
+#include <linux/freezer.h>
#define PANIC_TIMER_STEP 100
#define PANIC_BLINK_SPD 18
@@ -355,6 +356,13 @@ void oops_exit(void)
do_oops_enter_exit();
print_oops_end_marker();
kmsg_dump(KMSG_DUMP_OOPS);
+ /*
+ * if we oops while tasks are frozen, the system
+ * will stop dead because the task that would thaw it
+ * has been killed. So the system must be explicitly
+ * thawed here.
+ */
+ thaw_in_oops();
}
#ifdef WANT_WARN_ON_SLOWPATH
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 0cf3a27..c03e88b 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -22,6 +22,9 @@
*/
#define TIMEOUT (20 * HZ)
+/* in case we oops while processes are frozen */
+static bool tasks_frozen = false;
+
static inline int freezable(struct task_struct * p)
{
if ((p == current) ||
@@ -131,6 +134,7 @@ static int try_to_freeze_tasks(bool sig_only)
elapsed_csecs % 100);
}
+ tasks_frozen = (todo == 0);
return todo ? -EBUSY : 0;
}
@@ -189,7 +193,14 @@ void thaw_processes(void)
thaw_workqueues();
thaw_tasks(true);
thaw_tasks(false);
+ tasks_frozen = false;
schedule();
printk("done.\n");
}
+void thaw_in_oops(void)
+{
+ if (tasks_frozen)
+ thaw_processes();
+}
+
--
1.7.1
^ permalink raw reply related
* Re: PM / hibernate xfs lock up / xfs_reclaim_inodes_ag
From: Nigel Cunningham @ 2011-07-27 12:22 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Christoph, Dave Chinner, xfs, Linux PM mailing list
In-Reply-To: <20110727103308.GA20805@infradead.org>
Hi.
On 27/07/11 20:33, Christoph Hellwig wrote:
> On Wed, Jul 27, 2011 at 11:35:13AM +0200, Rafael J. Wysocki wrote:
>> The Pavel's objection, if I remember it correctly, was that some
>> (or the majority of?) filesystems didn't implement the freezing operation,
>> so they would be more vulnerable to data loss in case of a failing hibernation
>> after this change. However, that's better than actively causing pain to XFS
>> users.
>
> The objection never made sense and only means he never read the code.
> freeze_super (or freeze_bdev back then) always does a sync_filesystem
> before even checking if we have a freeze method, and sync_filesystem is
> what we iterate over for each superblock in sync().
I've had freezing supers in TOI for a couple of years now and it has
only ever helped. To be honest, if you have a ton of dirty pages, it
does result in a big delay, but that's the worst of it.
Regards,
Nigel
--
Evolution (n): A hypothetical process whereby improbable
events occur with alarming frequency, order arises from chaos, and
no one is given credit.
^ permalink raw reply
* Re: [PATCHv4 04/11] PM: Use *_dec_not_zero instead of *_add_unless
From: Rafael J. Wysocki @ 2011-07-27 19:50 UTC (permalink / raw)
To: Sven Eckelmann; +Cc: linux-arch, Len Brown, linux-pm, linux-kernel
In-Reply-To: <1311760070-21532-4-git-send-email-sven@narfation.org>
On Wednesday, July 27, 2011, Sven Eckelmann wrote:
> atomic_dec_not_zero is defined for each architecture through
> <linux/atomic.h> to provide the functionality of
> atomic_add_unless(x, -1, 0).
>
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> Cc: Len Brown <len.brown@intel.com>
> Cc: Pavel Machek <pavel@ucw.cz>
> Cc: Rafael J. Wysocki <rjw@sisk.pl>
> Cc: linux-pm@lists.linux-foundation.org
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
> ---
> drivers/base/power/runtime.c | 4 ++--
> include/linux/pm_runtime.h | 2 +-
> kernel/power/hibernate.c | 4 ++--
> kernel/power/user.c | 2 +-
> 4 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> index 8dc247c..bda10d9 100644
> --- a/drivers/base/power/runtime.c
> +++ b/drivers/base/power/runtime.c
> @@ -401,7 +401,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
>
> if (dev->parent) {
> parent = dev->parent;
> - atomic_add_unless(&parent->power.child_count, -1, 0);
> + atomic_dec_not_zero(&parent->power.child_count);
> }
> }
> wake_up_all(&dev->power.wait_queue);
> @@ -841,7 +841,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
> if (status == RPM_SUSPENDED) {
> /* It always is possible to set the status to 'suspended'. */
> if (parent) {
> - atomic_add_unless(&parent->power.child_count, -1, 0);
> + atomic_dec_not_zero(&parent->power.child_count);
> notify_parent = !parent->power.ignore_children;
> }
> goto out_set;
> diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
> index daac05d..3b4931c 100644
> --- a/include/linux/pm_runtime.h
> +++ b/include/linux/pm_runtime.h
> @@ -63,7 +63,7 @@ static inline void pm_runtime_get_noresume(struct device *dev)
>
> static inline void pm_runtime_put_noidle(struct device *dev)
> {
> - atomic_add_unless(&dev->power.usage_count, -1, 0);
> + atomic_dec_not_zero(&dev->power.usage_count);
> }
>
> static inline bool device_run_wake(struct device *dev)
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index 8f7b1db..0ba8d87 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -606,7 +606,7 @@ int hibernate(void)
>
> mutex_lock(&pm_mutex);
> /* The snapshot device should not be opened while we're running */
> - if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
> + if (!atomic_dec_not_zero(&snapshot_device_available)) {
> error = -EBUSY;
> goto Unlock;
> }
> @@ -756,7 +756,7 @@ static int software_resume(void)
> goto Unlock;
>
> /* The snapshot device should not be opened while we're running */
> - if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
> + if (!atomic_dec_not_zero(&snapshot_device_available)) {
> error = -EBUSY;
> swsusp_close(FMODE_READ);
> goto Unlock;
> diff --git a/kernel/power/user.c b/kernel/power/user.c
> index 42ddbc6..1c1cc01 100644
> --- a/kernel/power/user.c
> +++ b/kernel/power/user.c
> @@ -72,7 +72,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
>
> mutex_lock(&pm_mutex);
>
> - if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
> + if (!atomic_dec_not_zero(&snapshot_device_available)) {
> error = -EBUSY;
> goto Unlock;
> }
>
^ permalink raw reply
* Re: [PATCHv4 04/11] PM: Use *_dec_not_zero instead of *_add_unless
From: Pavel Machek @ 2011-07-27 20:36 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: linux-arch, Len Brown, linux-pm, linux-kernel, Sven Eckelmann
In-Reply-To: <201107272150.37962.rjw@sisk.pl>
Hi!
> > atomic_dec_not_zero is defined for each architecture through
> > <linux/atomic.h> to provide the functionality of
> > atomic_add_unless(x, -1, 0).
> >
> > Signed-off-by: Sven Eckelmann <sven@narfation.org>
> > Cc: Len Brown <len.brown@intel.com>
> > Cc: Pavel Machek <pavel@ucw.cz>
> > Cc: Rafael J. Wysocki <rjw@sisk.pl>
> > Cc: linux-pm@lists.linux-foundation.org
>
> Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
>
> > ---
> > drivers/base/power/runtime.c | 4 ++--
> > include/linux/pm_runtime.h | 2 +-
> > kernel/power/hibernate.c | 4 ++--
> > kernel/power/user.c | 2 +-
> > 4 files changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> > index 8dc247c..bda10d9 100644
> > --- a/drivers/base/power/runtime.c
> > +++ b/drivers/base/power/runtime.c
> > @@ -401,7 +401,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
> >
> > if (dev->parent) {
> > parent = dev->parent;
> > - atomic_add_unless(&parent->power.child_count, -1, 0);
> > + atomic_dec_not_zero(&parent->power.child_count);
I'd like to understand... Why not atomic_dec in the first place? Count
should be exact, anyway, or we run into problems, right?
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Re: Fw: Panic while enabling 2nd CPU core after suspend to ram on Intel Atom CPU
From: Andrew Morton @ 2011-07-27 22:54 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: Ingo Molnar, Linux PM mailing list
In-Reply-To: <201107262203.25816.rjw@sisk.pl>
On Tue, 26 Jul 2011 22:03:25 +0200
"Rafael J. Wysocki" <rjw@sisk.pl> wrote:
> On Thursday, July 21, 2011, Andrew Morton wrote:
> >
> > who would be an appropriate person to look at this one?
> >
> > The suspend_test warning is Rafael, I guess. But the mwait_idle oops?
>
> The suspend_test warning only means that the resuming of devices took
> too much time.
OK, but why did mwait_idle() oops?
And why do so many people just ignore so many bug reports? Do we
expect these things to solve themselves?
Sigh.
>
> > Begin forwarded message:
> >
> > Date: Sun, 17 Jul 2011 17:00:14 +0200
> > From: Martin S__fke <martinlkml2011@piximail.de>
> > To: linux-kernel@vger.kernel.org
> > Subject: Panic while enabling 2nd CPU core after suspend to ram on Intel Atom CPU
> >
> >
> > Hello, everybody.
> >
> > I get the following kernel panic after my system has been sent to "suspend to ram":
> > The system has an Intel Atom D525 Dual Core CPU with hyperthreading, showing up as 4 cpus in /proc/cpuinfo. After the kernel panic happened, the caps-lock and scroll-lock LED on the keyboard are blinking.
> >
> > $ ksymoops -m /boot/System.map-3.0.0-rc7min oops_without_timestamps.log
> > ksymoops 2.4.11 on x86_64 3.0.0-rc7min. Options used
> > -V (default)
> > -k /proc/ksyms (default)
> > -l /proc/modules (default)
> > -o /lib/modules/3.0.0-rc7min/ (default)
> > -m /boot/System.map-3.0.0-rc7min (specified)
> >
> > Error (regular_file): read_ksyms stat /proc/ksyms failed
> > ksymoops: No such file or directory
> > No modules in ksyms, skipping objects
> > No ksyms, skipping lsmod
> > CPU 1
> > Pid: 0, comm: kworker/0:0 Tainted: G W 3.0.0-rc7min #14 Gigabyte Technology Co., Ltd. D525TUD/D525TUD
> > RIP: 0010:[<ffffffff810088cf>] [<ffffffff810088cf>] mwait_idle+0xd2/0x159
> > Using defaults from ksymoops -t elf64-x86-64 -a i386:x86-64
> > RSP: 0000:ffff88013f515ef8 EFLAGS: 00010046
> > RAX: ffff88013f514010 RBX: ffff88013f515fd8 RCX: 0000000000000000
> > RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff818df108
> > RBP: ffff88013f515f08 R08: 0000000000000000 R09: 0000000000000000
> > R10: 7fffffffffffffff R11: ffffffff8184e4d0 R12: 0000000000000001
> > R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> > FS: 0000000000000000(0000) GS:ffff88013fc80000(0000) knlGS:0000000000000000
> > CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> > CR2: 0000000000000000 CR3: 0000000001803000 CR4: 00000000000006e0
> > ffffffff818525a0 ffff88013f514010 ffff88013f515f28 ffffffff81001c88
> > 0000000000000001 0000000000000000 ffff88013f515f48 ffffffff81411371
> > 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> > Call Trace:
> > [<ffffffff81001c88>] cpu_idle+0x5a/0x91
> > [<ffffffff81411371>] start_secondary+0x19c/0x1a0
> > Code: c2 74 13 65 48 8b 04 25 88 b5 00 00 48 2d d8 1f 00 00 0f ae 78 10 31 d2 65 48 8b 1c 25 88 b5 00 00 48 89 d1 48 8d 83 38 e0 ff ff <0f> 01 c8 0f ae f0 48 8b 83 38 e0 ff ff a8 08 75 08 31 c0 fb 0f
> >
> >
> > >>RIP; ffffffff810088cf <mwait_idle+d2/159> <=====
> >
> > >>RAX; ffff88013f514010 <phys_startup_64+ffff88013e514010/ffffffff80000000>
> > >>RBX; ffff88013f515fd8 <phys_startup_64+ffff88013e515fd8/ffffffff80000000>
> > >>RDI; ffffffff818df108 <idle_notifier+8/10>
> > >>RBP; ffff88013f515f08 <phys_startup_64+ffff88013e515f08/ffffffff80000000>
> > >>R10; 7fffffffffffffff <phys_startup_64+7ffffffffeffffff/ffffffff80000000>
> > >>R11; ffffffff8184e4d0 <migration_notifier+0/20>
> >
> > Trace; ffffffff81001c88 <cpu_idle+5a/91>
> > Trace; ffffffff81411371 <start_secondary+19c/1a0>
> >
> > Code; ffffffff810088a4 <mwait_idle+a7/159>
> > 0000000000000000 <_RIP>:
> > Code; ffffffff810088a4 <mwait_idle+a7/159>
> > 0: c2 74 13 retq $0x1374
> > Code; ffffffff810088a7 <mwait_idle+aa/159>
> > 3: 65 48 8b 04 25 88 b5 mov %gs:0xb588,%rax
> > Code; ffffffff810088ae <mwait_idle+b1/159>
> > a: 00 00
> > Code; ffffffff810088b0 <mwait_idle+b3/159>
> > c: 48 2d d8 1f 00 00 sub $0x1fd8,%rax
> > Code; ffffffff810088b6 <mwait_idle+b9/159>
> > 12: 0f ae 78 10 clflush 0x10(%rax)
> > Code; ffffffff810088ba <mwait_idle+bd/159>
> > 16: 31 d2 xor %edx,%edx
> > Code; ffffffff810088bc <mwait_idle+bf/159>
> > 18: 65 48 8b 1c 25 88 b5 mov %gs:0xb588,%rbx
> > Code; ffffffff810088c3 <mwait_idle+c6/159>
> > 1f: 00 00
> > Code; ffffffff810088c5 <mwait_idle+c8/159>
> > 21: 48 89 d1 mov %rdx,%rcx
> > Code; ffffffff810088c8 <mwait_idle+cb/159>
> > 24: 48 8d 83 38 e0 ff ff lea -0x1fc8(%rbx),%rax
> > Code; ffffffff810088cf <mwait_idle+d2/159> <=====
> > 2b: 0f 01 c8 monitor %rax,%rcx,%rdx <=====
> > Code; ffffffff810088d2 <mwait_idle+d5/159>
> > 2e: 0f ae f0 mfence
> > Code; ffffffff810088d5 <mwait_idle+d8/159>
> > 31: 48 8b 83 38 e0 ff ff mov -0x1fc8(%rbx),%rax
> > Code; ffffffff810088dc <mwait_idle+df/159>
> > 38: a8 08 test $0x8,%al
> > Code; ffffffff810088de <mwait_idle+e1/159>
> > 3a: 75 08 jne 44 <_RIP+0x44>
> > Code; ffffffff810088e0 <mwait_idle+e3/159>
> > 3c: 31 c0 xor %eax,%eax
> > Code; ffffffff810088e2 <mwait_idle+e5/159>
> > 3e: fb sti
> > Code; ffffffff810088e3 <mwait_idle+e6/159>
> > 3f:
> >
> > Kernel panic - not syncing: Attempted to kill the idle task!
> > Pid: 0, comm: kworker/0:0 Tainted: G D W 3.0.0-rc7min #14
> > Call Trace:
> > [<ffffffff81414bc4>] panic+0x8c/0x199
> > [<ffffffff810343d5>] do_exit+0xab/0x737
> > [<ffffffff8103137a>] ? kmsg_dump+0x44/0xe3
> > [<ffffffff81004fe4>] oops_end+0xb1/0xb9
> > [<ffffffff810050d2>] die+0x55/0x5e
> > [<ffffffff81002bce>] do_trap+0x11c/0x12b
> > [<ffffffff81002f4e>] do_invalid_op+0x91/0x9a
> > [<ffffffff810088cf>] ? mwait_idle+0xd2/0x159
> > [<ffffffff81016a71>] ? __setup_APIC_LVTT+0x67/0x88
> > [<ffffffff81052939>] ? ktime_get+0x5f/0xb5
> > [<ffffffff81016aaa>] ? lapic_next_event+0x18/0x1c
> > [<ffffffff81056a4a>] ? clockevents_program_event+0x75/0x7e
> > [<ffffffff81056d77>] ? tick_setup_periodic+0x6f/0x81
> > [<ffffffff814186d5>] invalid_op+0x15/0x20
> > [<ffffffff810088cf>] ? mwait_idle+0xd2/0x159
> > [<ffffffff8104f5dc>] ? atomic_notifier_call_chain+0x13/0x15
> > [<ffffffff81001c88>] cpu_idle+0x5a/0x91
> > [<ffffffff81411371>] start_secondary+0x19c/0x1a0
> > Warning (Oops_read): Code line not seen, dumping what data is available
> >
> >
> > Trace; ffffffff81414bc4 <panic+8c/199>
> > Trace; ffffffff810343d5 <do_exit+ab/737>
> > Trace; ffffffff8103137a <kmsg_dump+44/e3>
> > Trace; ffffffff81004fe4 <oops_end+b1/b9>
> > Trace; ffffffff810050d2 <die+55/5e>
> > Trace; ffffffff81002bce <do_trap+11c/12b>
> > Trace; ffffffff81002f4e <do_invalid_op+91/9a>
> > Trace; ffffffff810088cf <mwait_idle+d2/159>
> > Trace; ffffffff81016a71 <__setup_APIC_LVTT+67/88>
> > Trace; ffffffff81052939 <ktime_get+5f/b5>
> > Trace; ffffffff81016aaa <lapic_next_event+18/1c>
> > Trace; ffffffff81056a4a <clockevents_program_event+75/7e>
> > Trace; ffffffff81056d77 <tick_setup_periodic+6f/81>
> > Trace; ffffffff814186d5 <invalid_op+15/20>
> > Trace; ffffffff810088cf <mwait_idle+d2/159>
> > Trace; ffffffff8104f5dc <atomic_notifier_call_chain+13/15>
> > Trace; ffffffff81001c88 <cpu_idle+5a/91>
> > Trace; ffffffff81411371 <start_secondary+19c/1a0>
> > 1 warning and 1 error issued. Results may not be reliable.
> >
> > To get there, I do the following:
> > 1) disable cpu1 and cpu2 (both on cpu core 1 if I got it right) with:
> > $ echo 0 > /sys/devices/system/cpu/cpu1/online
> > $ echo 0 > /sys/devices/system/cpu/cpu2/online
> > this leaves me with cpu0 and cpu3 which are both hyperthreads on
> >
> > 2) suspend to ram, then resume the system
> > $ echo mem > /sys/power/state
> > (system goes into suspend, resumable by pressing the power button)
> >
> > 2a) During supend, a warning is issuted. My guess is that the harddisk is simply slow to spin up. Is that guess right ?
> > $ dmesg
> > [ 104.092215] PM: Syncing filesystems ... done.
> > [ 104.096763] PM: Preparing system for mem sleep
> > [ 104.104047] Freezing user space processes ... (elapsed 0.01 seconds) done.
> > [ 104.121723] Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
> > [ 104.139774] PM: Entering mem sleep
> > [ 104.143700] sd 1:0:0:0: [sdb] Synchronizing SCSI cache
> > [ 104.143721] sd 0:0:0:0: [sda] Synchronizing SCSI cache
> > [ 104.143878] sd 0:0:0:0: [sda] Stopping disk
> > [ 104.158499] sd 1:0:0:0: [sdb] Stopping disk
> > [ 104.169431] serial 00:08: disabled
> > [ 104.172946] serial 00:08: wake-up capability disabled by ACPI
> > [ 108.652030] serial 00:08: activated
> > [ 108.963044] ata6: SATA link down (SStatus 0 SControl 300)
> > [ 108.968599] ata5: SATA link down (SStatus 0 SControl 300)
> > [ 110.156028] ata1: link is slow to respond, please be patient (ready=0)
> > [ 110.162673] ata2: link is slow to respond, please be patient (ready=0)
> > [ 113.943040] ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
> > [ 113.951711] ata2.00: configured for UDMA/133
> > [ 114.803024] ata1: COMRESET failed (errno=-16)
> > [ 117.050031] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
> > [ 117.086293] ata1.00: configured for UDMA/133
> > [ 117.100984] PM: resume of devices complete after 12306.735 msecs
> > [ 117.107275] PM: resume devices took 12.313 seconds
> > [ 117.112177] ------------[ cut here ]------------
> > [ 117.116910] WARNING: at kernel/power/suspend_test.c:53 suspend_test_finish+0x7b/0x84()
> > [ 117.125009] Hardware name: D525TUD
> > [ 117.128511] Component: resume devices, time: 12313
> > [ 117.133414] Pid: 3612, comm: echo Not tainted 3.0.0-rc7min #14
> > [ 117.139352] Call Trace:
> > [ 117.141905] [<ffffffff81030f02>] warn_slowpath_common+0x7b/0x93
> > [ 117.148024] [<ffffffff81030fae>] warn_slowpath_fmt+0x41/0x43
> > [ 117.153882] [<ffffffff8105dabb>] suspend_test_finish+0x7b/0x84
> > [ 117.159918] [<ffffffff8105d853>] suspend_devices_and_enter+0x1d9/0x236
> > [ 117.166642] [<ffffffff8105d98f>] enter_state+0xdf/0x135
> > [ 117.172062] [<ffffffff8105d062>] state_store+0xb1/0xce
> > [ 117.177403] [<ffffffff81210ee3>] kobj_attr_store+0x17/0x19
> > [ 117.183088] [<ffffffff81113a97>] sysfs_write_file+0xef/0x12b
> > [ 117.188947] [<ffffffff810c5687>] vfs_write+0xae/0x153
> > [ 117.194196] [<ffffffff810c57e5>] sys_write+0x45/0x6c
> > [ 117.199362] [<ffffffff81417afb>] system_call_fastpath+0x16/0x1b
> > [ 117.205481] ---[ end trace 27f1f84a48a28b3a ]---
> > [ 117.210220] PM: Finishing wakeup.
> > [ 117.213636] Restarting tasks ... done.
> >
> > 3) Now enabling the cpu1 or cpu2 (on core 1) leads to the panic:
> > $ echo 1 > /sys/devices/system/cpu/cpu1/online
> > [ 162.550537] Booting Node 0 Processor 1 APIC 0x2
> > [ 162.555190] smpboot cpu 1: start_ip = 9a000
> > [ 28.795663] Disabled fast string operations
> > [ 162.638260] invalid opcode: 0000 [#1] SMP
> > [ 162.638260] CPU 1
> > [ 162.638260] Pid: 0, comm: kworker/0:0 Tainted: G W 3.0.0-rc7min #14 Gigabyte Technology Co., Ltd. D525TUD/D525TUD
> > ... this is the oops which is at the beginnin ot the message ...
> >
> > Attached: kernel .config, cpuinfo, content of /sys/power/* and content of /sys/devices/system/cpu/*
> >
> > More info:
> > enabling and disabling cpu1, cpu2 and/or cpu3 in any combination or sequence works without errror if the system had not been suspended to ram before.
> > Suspend to disk works, also works if all cpus are enabled
> > Testing suspend to ram with /sys/power/pm_test works with all tests, including "core" even if all cpus are enabled
> > suspend to ram does not work with all cpus enabled, the system will only show the VGA BIOS greeting message and blinking keyboard leds.
> >
> > If CONFIG_INTEL_IDLE is set in kernel config, the oops trace will include "intel_idle" instead of "mwait_idle" but not differ much otherwise. I can provide an oops trace with intel_idle if it helps.
> >
> > I have tested kernels 2.6.35.10 2.6.36.2 2.6.37-rc6 2.6.39-git all with the same problem half a year ago.
> > Back then, the system had BIOS revision F3, this got upgraded to F4 for the tests with the 3.0.0-rc7 kernel.
> >
> > Earlier, I had tried posting the problem to the linux-pm mailing list
> > https://lists.linux-foundation.org/pipermail/linux-pm/2010-December/029654.html
> > https://lists.linux-foundation.org/pipermail/linux-pm/2010-December/029655.html
> > https://lists.linux-foundation.org/pipermail/linux-pm/2010-December/029656.html
> > However, I got the only answer I got was to try it on the LKML
> >
> > Any help is appreciated.
> >
> > I am NOT on the LKML, so please CC me in replies.
> > -Martin
> >
> > ------------------ Kernel config -------------
> > CONFIG_64BIT=y
> > CONFIG_X86_64=y
> > CONFIG_X86=y
> > CONFIG_INSTRUCTION_DECODER=y
> > CONFIG_OUTPUT_FORMAT="elf64-x86-64"
> > CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
> > CONFIG_GENERIC_CMOS_UPDATE=y
> > CONFIG_CLOCKSOURCE_WATCHDOG=y
> > CONFIG_GENERIC_CLOCKEVENTS=y
> > CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
> > CONFIG_LOCKDEP_SUPPORT=y
> > CONFIG_STACKTRACE_SUPPORT=y
> > CONFIG_HAVE_LATENCYTOP_SUPPORT=y
> > CONFIG_MMU=y
> > CONFIG_ZONE_DMA=y
> > CONFIG_NEED_DMA_MAP_STATE=y
> > CONFIG_NEED_SG_DMA_LENGTH=y
> > CONFIG_GENERIC_ISA_DMA=y
> > CONFIG_GENERIC_IOMAP=y
> > CONFIG_GENERIC_BUG=y
> > CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
> > CONFIG_GENERIC_HWEIGHT=y
> > CONFIG_ARCH_MAY_HAVE_PC_FDC=y
> > CONFIG_RWSEM_XCHGADD_ALGORITHM=y
> > CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
> > CONFIG_GENERIC_CALIBRATE_DELAY=y
> > CONFIG_GENERIC_TIME_VSYSCALL=y
> > CONFIG_ARCH_HAS_CPU_RELAX=y
> > CONFIG_ARCH_HAS_DEFAULT_IDLE=y
> > CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
> > CONFIG_HAVE_SETUP_PER_CPU_AREA=y
> > CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
> > CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
> > CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y
> > CONFIG_ARCH_HIBERNATION_POSSIBLE=y
> > CONFIG_ARCH_SUSPEND_POSSIBLE=y
> > CONFIG_ZONE_DMA32=y
> > CONFIG_ARCH_POPULATES_NODE_MAP=y
> > CONFIG_AUDIT_ARCH=y
> > CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
> > CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
> > CONFIG_X86_64_SMP=y
> > CONFIG_X86_HT=y
> > CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
> > CONFIG_ARCH_CPU_PROBE_RELEASE=y
> > CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
> > CONFIG_HAVE_IRQ_WORK=y
> > CONFIG_IRQ_WORK=y
> > CONFIG_EXPERIMENTAL=y
> > CONFIG_INIT_ENV_ARG_LIMIT=32
> > CONFIG_CROSS_COMPILE=""
> > CONFIG_LOCALVERSION="min"
> > CONFIG_HAVE_KERNEL_GZIP=y
> > CONFIG_HAVE_KERNEL_BZIP2=y
> > CONFIG_HAVE_KERNEL_LZMA=y
> > CONFIG_HAVE_KERNEL_XZ=y
> > CONFIG_HAVE_KERNEL_LZO=y
> > CONFIG_KERNEL_GZIP=y
> > CONFIG_DEFAULT_HOSTNAME="behemoth"
> > CONFIG_SWAP=y
> > CONFIG_SYSVIPC=y
> > CONFIG_SYSVIPC_SYSCTL=y
> > CONFIG_POSIX_MQUEUE=y
> > CONFIG_POSIX_MQUEUE_SYSCTL=y
> > CONFIG_BSD_PROCESS_ACCT=y
> > CONFIG_FHANDLE=y
> > CONFIG_TASKSTATS=y
> > CONFIG_TASK_DELAY_ACCT=y
> > CONFIG_TASK_XACCT=y
> > CONFIG_TASK_IO_ACCOUNTING=y
> > CONFIG_AUDIT=y
> > CONFIG_AUDITSYSCALL=y
> > CONFIG_AUDIT_WATCH=y
> > CONFIG_AUDIT_TREE=y
> > CONFIG_HAVE_GENERIC_HARDIRQS=y
> > CONFIG_GENERIC_HARDIRQS=y
> > CONFIG_HAVE_SPARSE_IRQ=y
> > CONFIG_GENERIC_IRQ_PROBE=y
> > CONFIG_GENERIC_IRQ_SHOW=y
> > CONFIG_GENERIC_PENDING_IRQ=y
> > CONFIG_IRQ_FORCED_THREADING=y
> > CONFIG_SPARSE_IRQ=y
> > CONFIG_TREE_RCU=y
> > CONFIG_RCU_FANOUT=32
> > CONFIG_IKCONFIG=y
> > CONFIG_IKCONFIG_PROC=y
> > CONFIG_LOG_BUF_SHIFT=20
> > CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
> > CONFIG_NAMESPACES=y
> > CONFIG_UTS_NS=y
> > CONFIG_IPC_NS=y
> > CONFIG_USER_NS=y
> > CONFIG_PID_NS=y
> > CONFIG_NET_NS=y
> > CONFIG_RELAY=y
> > CONFIG_BLK_DEV_INITRD=y
> > CONFIG_INITRAMFS_SOURCE=""
> > CONFIG_RD_GZIP=y
> > CONFIG_RD_BZIP2=y
> > CONFIG_RD_LZMA=y
> > CONFIG_RD_XZ=y
> > CONFIG_RD_LZO=y
> > CONFIG_CC_OPTIMIZE_FOR_SIZE=y
> > CONFIG_SYSCTL=y
> > CONFIG_ANON_INODES=y
> > CONFIG_SYSCTL_SYSCALL=y
> > CONFIG_KALLSYMS=y
> > CONFIG_HOTPLUG=y
> > CONFIG_PRINTK=y
> > CONFIG_BUG=y
> > CONFIG_ELF_CORE=y
> > CONFIG_PCSPKR_PLATFORM=y
> > CONFIG_BASE_FULL=y
> > CONFIG_FUTEX=y
> > CONFIG_EPOLL=y
> > CONFIG_SIGNALFD=y
> > CONFIG_TIMERFD=y
> > CONFIG_EVENTFD=y
> > CONFIG_SHMEM=y
> > CONFIG_AIO=y
> > CONFIG_HAVE_PERF_EVENTS=y
> > CONFIG_PERF_EVENTS=y
> > CONFIG_VM_EVENT_COUNTERS=y
> > CONFIG_PCI_QUIRKS=y
> > CONFIG_SLAB=y
> > CONFIG_TRACEPOINTS=y
> > CONFIG_HAVE_OPROFILE=y
> > CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
> > CONFIG_HAVE_IOREMAP_PROT=y
> > CONFIG_HAVE_KPROBES=y
> > CONFIG_HAVE_KRETPROBES=y
> > CONFIG_HAVE_OPTPROBES=y
> > CONFIG_HAVE_ARCH_TRACEHOOK=y
> > CONFIG_HAVE_DMA_ATTRS=y
> > CONFIG_USE_GENERIC_SMP_HELPERS=y
> > CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
> > CONFIG_HAVE_DMA_API_DEBUG=y
> > CONFIG_HAVE_HW_BREAKPOINT=y
> > CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
> > CONFIG_HAVE_USER_RETURN_NOTIFIER=y
> > CONFIG_HAVE_PERF_EVENTS_NMI=y
> > CONFIG_HAVE_ARCH_JUMP_LABEL=y
> > CONFIG_SLABINFO=y
> > CONFIG_RT_MUTEXES=y
> > CONFIG_BASE_SMALL=0
> > CONFIG_STOP_MACHINE=y
> > CONFIG_BLOCK=y
> > CONFIG_BLK_DEV_BSG=y
> > CONFIG_IOSCHED_NOOP=y
> > CONFIG_IOSCHED_DEADLINE=y
> > CONFIG_IOSCHED_CFQ=y
> > CONFIG_DEFAULT_CFQ=y
> > CONFIG_DEFAULT_IOSCHED="cfq"
> > CONFIG_INLINE_SPIN_UNLOCK=y
> > CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
> > CONFIG_INLINE_READ_UNLOCK=y
> > CONFIG_INLINE_READ_UNLOCK_IRQ=y
> > CONFIG_INLINE_WRITE_UNLOCK=y
> > CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
> > CONFIG_MUTEX_SPIN_ON_OWNER=y
> > CONFIG_FREEZER=y
> > CONFIG_TICK_ONESHOT=y
> > CONFIG_NO_HZ=y
> > CONFIG_HIGH_RES_TIMERS=y
> > CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
> > CONFIG_SMP=y
> > CONFIG_X86_MPPARSE=y
> > CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
> > CONFIG_SCHED_OMIT_FRAME_POINTER=y
> > CONFIG_NO_BOOTMEM=y
> > CONFIG_MATOM=y
> > CONFIG_X86_INTERNODE_CACHE_SHIFT=6
> > CONFIG_X86_CMPXCHG=y
> > CONFIG_CMPXCHG_LOCAL=y
> > CONFIG_X86_L1_CACHE_SHIFT=6
> > CONFIG_X86_XADD=y
> > CONFIG_X86_WP_WORKS_OK=y
> > CONFIG_X86_USE_PPRO_CHECKSUM=y
> > CONFIG_X86_TSC=y
> > CONFIG_X86_CMPXCHG64=y
> > CONFIG_X86_CMOV=y
> > CONFIG_X86_MINIMUM_CPU_FAMILY=64
> > CONFIG_X86_DEBUGCTLMSR=y
> > CONFIG_CPU_SUP_INTEL=y
> > CONFIG_CPU_SUP_AMD=y
> > CONFIG_CPU_SUP_CENTAUR=y
> > CONFIG_HPET_TIMER=y
> > CONFIG_HPET_EMULATE_RTC=y
> > CONFIG_DMI=y
> > CONFIG_GART_IOMMU=y
> > CONFIG_SWIOTLB=y
> > CONFIG_IOMMU_HELPER=y
> > CONFIG_NR_CPUS=4
> > CONFIG_SCHED_MC=y
> > CONFIG_PREEMPT_NONE=y
> > CONFIG_X86_LOCAL_APIC=y
> > CONFIG_X86_IO_APIC=y
> > CONFIG_X86_MCE=y
> > CONFIG_X86_MCE_INTEL=y
> > CONFIG_X86_MCE_THRESHOLD=y
> > CONFIG_X86_THERMAL_VECTOR=y
> > CONFIG_MICROCODE=y
> > CONFIG_MICROCODE_INTEL=y
> > CONFIG_MICROCODE_OLD_INTERFACE=y
> > CONFIG_X86_MSR=y
> > CONFIG_X86_CPUID=y
> > CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
> > CONFIG_ARCH_DMA_ADDR_T_64BIT=y
> > CONFIG_DIRECT_GBPAGES=y
> > CONFIG_ARCH_SPARSEMEM_ENABLE=y
> > CONFIG_ARCH_SPARSEMEM_DEFAULT=y
> > CONFIG_ARCH_SELECT_MEMORY_MODEL=y
> > CONFIG_ARCH_PROC_KCORE_TEXT=y
> > CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
> > CONFIG_SELECT_MEMORY_MODEL=y
> > CONFIG_SPARSEMEM_MANUAL=y
> > CONFIG_SPARSEMEM=y
> > CONFIG_HAVE_MEMORY_PRESENT=y
> > CONFIG_SPARSEMEM_EXTREME=y
> > CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
> > CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
> > CONFIG_SPARSEMEM_VMEMMAP=y
> > CONFIG_HAVE_MEMBLOCK=y
> > CONFIG_PAGEFLAGS_EXTENDED=y
> > CONFIG_SPLIT_PTLOCK_CPUS=4
> > CONFIG_COMPACTION=y
> > CONFIG_MIGRATION=y
> > CONFIG_PHYS_ADDR_T_64BIT=y
> > CONFIG_ZONE_DMA_FLAG=1
> > CONFIG_BOUNCE=y
> > CONFIG_VIRT_TO_BUS=y
> > CONFIG_KSM=y
> > CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
> > CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
> > CONFIG_CLEANCACHE=y
> > CONFIG_X86_CHECK_BIOS_CORRUPTION=y
> > CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
> > CONFIG_X86_RESERVE_LOW=64
> > CONFIG_MTRR=y
> > CONFIG_MTRR_SANITIZER=y
> > CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
> > CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
> > CONFIG_X86_PAT=y
> > CONFIG_ARCH_USES_PG_UNCACHED=y
> > CONFIG_SECCOMP=y
> > CONFIG_HZ_1000=y
> > CONFIG_HZ=1000
> > CONFIG_SCHED_HRTICK=y
> > CONFIG_KEXEC=y
> > CONFIG_CRASH_DUMP=y
> > CONFIG_PHYSICAL_START=0x1000000
> > CONFIG_RELOCATABLE=y
> > CONFIG_PHYSICAL_ALIGN=0x1000000
> > CONFIG_HOTPLUG_CPU=y
> > CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
> > CONFIG_ARCH_HIBERNATION_HEADER=y
> > CONFIG_SUSPEND=y
> > CONFIG_SUSPEND_FREEZER=y
> > CONFIG_HIBERNATE_CALLBACKS=y
> > CONFIG_HIBERNATION=y
> > CONFIG_PM_STD_PARTITION=""
> > CONFIG_PM_SLEEP=y
> > CONFIG_PM_SLEEP_SMP=y
> > CONFIG_PM_RUNTIME=y
> > CONFIG_PM=y
> > CONFIG_PM_DEBUG=y
> > CONFIG_PM_ADVANCED_DEBUG=y
> > CONFIG_PM_TEST_SUSPEND=y
> > CONFIG_CAN_PM_TRACE=y
> > CONFIG_PM_TRACE=y
> > CONFIG_PM_TRACE_RTC=y
> > CONFIG_ACPI=y
> > CONFIG_ACPI_SLEEP=y
> > CONFIG_ACPI_PROC_EVENT=y
> > CONFIG_ACPI_BUTTON=y
> > CONFIG_ACPI_PROCESSOR=y
> > CONFIG_ACPI_HOTPLUG_CPU=y
> > CONFIG_ACPI_PROCESSOR_AGGREGATOR=y
> > CONFIG_ACPI_THERMAL=y
> > CONFIG_ACPI_BLACKLIST_YEAR=0
> > CONFIG_X86_PM_TIMER=y
> > CONFIG_ACPI_CONTAINER=y
> > CONFIG_ACPI_CUSTOM_METHOD=y
> > CONFIG_CPU_IDLE=y
> > CONFIG_CPU_IDLE_GOV_LADDER=y
> > CONFIG_CPU_IDLE_GOV_MENU=y
> > CONFIG_PCI=y
> > CONFIG_PCI_DIRECT=y
> > CONFIG_PCI_MMCONFIG=y
> > CONFIG_PCI_DOMAINS=y
> > CONFIG_PCIEPORTBUS=y
> > CONFIG_PCIEAER=y
> > CONFIG_PCIEASPM=y
> > CONFIG_PCIE_PME=y
> > CONFIG_ARCH_SUPPORTS_MSI=y
> > CONFIG_PCI_MSI=y
> > CONFIG_HT_IRQ=y
> > CONFIG_PCI_IOAPIC=y
> > CONFIG_PCI_LABEL=y
> > CONFIG_ISA_DMA_API=y
> > CONFIG_AMD_NB=y
> > CONFIG_BINFMT_ELF=y
> > CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
> > CONFIG_BINFMT_MISC=y
> > CONFIG_HAVE_TEXT_POKE_SMP=y
> > CONFIG_NET=y
> > CONFIG_PACKET=y
> > CONFIG_UNIX=y
> > CONFIG_XFRM=y
> > CONFIG_XFRM_USER=y
> > CONFIG_INET=y
> > CONFIG_IP_MULTICAST=y
> > CONFIG_IP_ADVANCED_ROUTER=y
> > CONFIG_IP_MULTIPLE_TABLES=y
> > CONFIG_IP_ROUTE_MULTIPATH=y
> > CONFIG_IP_ROUTE_VERBOSE=y
> > CONFIG_IP_PNP=y
> > CONFIG_IP_PNP_DHCP=y
> > CONFIG_IP_PNP_BOOTP=y
> > CONFIG_IP_PNP_RARP=y
> > CONFIG_IP_MROUTE=y
> > CONFIG_IP_PIMSM_V1=y
> > CONFIG_IP_PIMSM_V2=y
> > CONFIG_SYN_COOKIES=y
> > CONFIG_INET_TUNNEL=y
> > CONFIG_INET_LRO=y
> > CONFIG_TCP_CONG_ADVANCED=y
> > CONFIG_TCP_CONG_CUBIC=y
> > CONFIG_DEFAULT_CUBIC=y
> > CONFIG_DEFAULT_TCP_CONG="cubic"
> > CONFIG_TCP_MD5SIG=y
> > CONFIG_IPV6=y
> > CONFIG_INET6_AH=y
> > CONFIG_INET6_ESP=y
> > CONFIG_INET6_XFRM_MODE_TRANSPORT=y
> > CONFIG_INET6_XFRM_MODE_TUNNEL=y
> > CONFIG_INET6_XFRM_MODE_BEET=y
> > CONFIG_IPV6_SIT=y
> > CONFIG_IPV6_NDISC_NODETYPE=y
> > CONFIG_NETWORK_SECMARK=y
> > CONFIG_NETFILTER=y
> > CONFIG_NETFILTER_NETLINK=y
> > CONFIG_NETFILTER_NETLINK_LOG=y
> > CONFIG_NF_CONNTRACK=y
> > CONFIG_NF_CONNTRACK_SECMARK=y
> > CONFIG_NF_CONNTRACK_FTP=y
> > CONFIG_NF_CONNTRACK_IRC=y
> > CONFIG_NF_CONNTRACK_SIP=y
> > CONFIG_NF_CT_NETLINK=y
> > CONFIG_NETFILTER_XTABLES=y
> > CONFIG_NETFILTER_XT_MARK=y
> > CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
> > CONFIG_NETFILTER_XT_TARGET_NFLOG=y
> > CONFIG_NETFILTER_XT_TARGET_SECMARK=y
> > CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
> > CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
> > CONFIG_NETFILTER_XT_MATCH_POLICY=y
> > CONFIG_NETFILTER_XT_MATCH_STATE=y
> > CONFIG_NF_DEFRAG_IPV4=y
> > CONFIG_NF_CONNTRACK_IPV4=y
> > CONFIG_NF_CONNTRACK_PROC_COMPAT=y
> > CONFIG_IP_NF_IPTABLES=y
> > CONFIG_IP_NF_FILTER=y
> > CONFIG_IP_NF_TARGET_REJECT=y
> > CONFIG_IP_NF_TARGET_LOG=y
> > CONFIG_IP_NF_TARGET_ULOG=y
> > CONFIG_NF_NAT=y
> > CONFIG_NF_NAT_NEEDED=y
> > CONFIG_IP_NF_TARGET_MASQUERADE=y
> > CONFIG_NF_NAT_FTP=y
> > CONFIG_NF_NAT_IRC=y
> > CONFIG_NF_NAT_SIP=y
> > CONFIG_IP_NF_MANGLE=y
> > CONFIG_NF_DEFRAG_IPV6=y
> > CONFIG_NF_CONNTRACK_IPV6=y
> > CONFIG_IP6_NF_IPTABLES=y
> > CONFIG_IP6_NF_MATCH_IPV6HEADER=y
> > CONFIG_IP6_NF_TARGET_LOG=y
> > CONFIG_IP6_NF_FILTER=y
> > CONFIG_IP6_NF_TARGET_REJECT=y
> > CONFIG_IP6_NF_MANGLE=y
> > CONFIG_IP_SCTP=y
> > CONFIG_SCTP_HMAC_MD5=y
> > CONFIG_NET_SCHED=y
> > CONFIG_NET_CLS=y
> > CONFIG_NET_EMATCH=y
> > CONFIG_NET_EMATCH_STACK=32
> > CONFIG_NET_CLS_ACT=y
> > CONFIG_NET_SCH_FIFO=y
> > CONFIG_DNS_RESOLVER=y
> > CONFIG_RPS=y
> > CONFIG_RFS_ACCEL=y
> > CONFIG_XPS=y
> > CONFIG_HAVE_BPF_JIT=y
> > CONFIG_FIB_RULES=y
> > CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
> > CONFIG_STANDALONE=y
> > CONFIG_PREVENT_FIRMWARE_BUILD=y
> > CONFIG_FW_LOADER=y
> > CONFIG_FIRMWARE_IN_KERNEL=y
> > CONFIG_EXTRA_FIRMWARE=""
> > CONFIG_PNP=y
> > CONFIG_PNP_DEBUG_MESSAGES=y
> > CONFIG_PNPACPI=y
> > CONFIG_BLK_DEV=y
> > CONFIG_BLK_DEV_LOOP=y
> > CONFIG_BLK_DEV_NBD=y
> > CONFIG_BLK_DEV_RAM=y
> > CONFIG_BLK_DEV_RAM_COUNT=16
> > CONFIG_BLK_DEV_RAM_SIZE=16384
> > CONFIG_HAVE_IDE=y
> > CONFIG_SCSI_MOD=y
> > CONFIG_RAID_ATTRS=y
> > CONFIG_SCSI=y
> > CONFIG_SCSI_DMA=y
> > CONFIG_SCSI_PROC_FS=y
> > CONFIG_BLK_DEV_SD=y
> > CONFIG_ATA=y
> > CONFIG_ATA_VERBOSE_ERROR=y
> > CONFIG_ATA_ACPI=y
> > CONFIG_SATA_AHCI=y
> > CONFIG_ATA_SFF=y
> > CONFIG_ATA_BMDMA=y
> > CONFIG_PATA_JMICRON=y
> > CONFIG_ATA_GENERIC=y
> > CONFIG_MD=y
> > CONFIG_BLK_DEV_MD=y
> > CONFIG_MD_AUTODETECT=y
> > CONFIG_MD_RAID0=y
> > CONFIG_MD_RAID1=y
> > CONFIG_BLK_DEV_DM=y
> > CONFIG_DM_SNAPSHOT=y
> > CONFIG_DM_MIRROR=y
> > CONFIG_NETDEVICES=y
> > CONFIG_MII=y
> > CONFIG_NETDEV_1000=y
> > CONFIG_R8169=y
> > CONFIG_NETCONSOLE=y
> > CONFIG_NETCONSOLE_DYNAMIC=y
> > CONFIG_NETPOLL=y
> > CONFIG_NET_POLL_CONTROLLER=y
> > CONFIG_INPUT=y
> > CONFIG_INPUT_FF_MEMLESS=y
> > CONFIG_INPUT_POLLDEV=y
> > CONFIG_INPUT_SPARSEKMAP=y
> > CONFIG_INPUT_MOUSEDEV=y
> > CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
> > CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
> > CONFIG_INPUT_EVDEV=y
> > CONFIG_INPUT_KEYBOARD=y
> > CONFIG_KEYBOARD_ATKBD=y
> > CONFIG_INPUT_MOUSE=y
> > CONFIG_MOUSE_PS2=y
> > CONFIG_MOUSE_PS2_ALPS=y
> > CONFIG_MOUSE_PS2_LOGIPS2PP=y
> > CONFIG_MOUSE_PS2_SYNAPTICS=y
> > CONFIG_MOUSE_PS2_LIFEBOOK=y
> > CONFIG_MOUSE_PS2_TRACKPOINT=y
> > CONFIG_INPUT_JOYSTICK=y
> > CONFIG_INPUT_TABLET=y
> > CONFIG_INPUT_TOUCHSCREEN=y
> > CONFIG_INPUT_MISC=y
> > CONFIG_SERIO=y
> > CONFIG_SERIO_I8042=y
> > CONFIG_SERIO_SERPORT=y
> > CONFIG_SERIO_LIBPS2=y
> > CONFIG_SERIO_RAW=y
> > CONFIG_VT=y
> > CONFIG_CONSOLE_TRANSLATIONS=y
> > CONFIG_VT_CONSOLE=y
> > CONFIG_HW_CONSOLE=y
> > CONFIG_VT_HW_CONSOLE_BINDING=y
> > CONFIG_UNIX98_PTYS=y
> > CONFIG_SERIAL_NONSTANDARD=y
> > CONFIG_DEVKMEM=y
> > CONFIG_SERIAL_8250=y
> > CONFIG_SERIAL_8250_CONSOLE=y
> > CONFIG_FIX_EARLYCON_MEM=y
> > CONFIG_SERIAL_8250_PCI=y
> > CONFIG_SERIAL_8250_PNP=y
> > CONFIG_SERIAL_8250_NR_UARTS=32
> > CONFIG_SERIAL_8250_RUNTIME_UARTS=4
> > CONFIG_SERIAL_8250_EXTENDED=y
> > CONFIG_SERIAL_8250_MANY_PORTS=y
> > CONFIG_SERIAL_8250_SHARE_IRQ=y
> > CONFIG_SERIAL_8250_DETECT_IRQ=y
> > CONFIG_SERIAL_8250_RSA=y
> > CONFIG_SERIAL_CORE=y
> > CONFIG_SERIAL_CORE_CONSOLE=y
> > CONFIG_HW_RANDOM=y
> > CONFIG_HW_RANDOM_INTEL=y
> > CONFIG_HW_RANDOM_AMD=y
> > CONFIG_HW_RANDOM_VIA=y
> > CONFIG_NVRAM=y
> > CONFIG_HPET=y
> > CONFIG_HANGCHECK_TIMER=y
> > CONFIG_DEVPORT=y
> > CONFIG_RAMOOPS=y
> > CONFIG_I2C=y
> > CONFIG_I2C_BOARDINFO=y
> > CONFIG_I2C_COMPAT=y
> > CONFIG_I2C_HELPER_AUTO=y
> > CONFIG_I2C_ALGOBIT=y
> > CONFIG_I2C_I801=y
> > CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
> > CONFIG_HWMON=y
> > CONFIG_THERMAL=y
> > CONFIG_SSB_POSSIBLE=y
> > CONFIG_BCMA_POSSIBLE=y
> > CONFIG_AGP=y
> > CONFIG_AGP_INTEL=y
> > CONFIG_VGA_ARB=y
> > CONFIG_VGA_ARB_MAX_GPUS=16
> > CONFIG_DRM=y
> > CONFIG_BACKLIGHT_LCD_SUPPORT=y
> > CONFIG_BACKLIGHT_CLASS_DEVICE=y
> > CONFIG_BACKLIGHT_GENERIC=y
> > CONFIG_VGA_CONSOLE=y
> > CONFIG_VGACON_SOFT_SCROLLBACK=y
> > CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
> > CONFIG_DUMMY_CONSOLE=y
> > CONFIG_RTC_LIB=y
> > CONFIG_RTC_CLASS=y
> > CONFIG_RTC_INTF_SYSFS=y
> > CONFIG_RTC_INTF_PROC=y
> > CONFIG_RTC_INTF_DEV=y
> > CONFIG_RTC_DRV_CMOS=y
> > CONFIG_FIRMWARE_MEMMAP=y
> > CONFIG_EXT2_FS=y
> > CONFIG_EXT2_FS_XATTR=y
> > CONFIG_EXT2_FS_POSIX_ACL=y
> > CONFIG_EXT2_FS_SECURITY=y
> > CONFIG_EXT2_FS_XIP=y
> > CONFIG_EXT3_FS=y
> > CONFIG_EXT3_FS_XATTR=y
> > CONFIG_EXT3_FS_POSIX_ACL=y
> > CONFIG_EXT3_FS_SECURITY=y
> > CONFIG_EXT4_FS=y
> > CONFIG_EXT4_FS_XATTR=y
> > CONFIG_EXT4_FS_POSIX_ACL=y
> > CONFIG_EXT4_FS_SECURITY=y
> > CONFIG_FS_XIP=y
> > CONFIG_JBD=y
> > CONFIG_JBD2=y
> > CONFIG_FS_MBCACHE=y
> > CONFIG_REISERFS_FS=y
> > CONFIG_REISERFS_PROC_INFO=y
> > CONFIG_REISERFS_FS_XATTR=y
> > CONFIG_REISERFS_FS_POSIX_ACL=y
> > CONFIG_REISERFS_FS_SECURITY=y
> > CONFIG_FS_POSIX_ACL=y
> > CONFIG_EXPORTFS=y
> > CONFIG_FILE_LOCKING=y
> > CONFIG_FSNOTIFY=y
> > CONFIG_DNOTIFY=y
> > CONFIG_INOTIFY_USER=y
> > CONFIG_FANOTIFY=y
> > CONFIG_QUOTA=y
> > CONFIG_QUOTA_NETLINK_INTERFACE=y
> > CONFIG_QUOTACTL=y
> > CONFIG_AUTOFS4_FS=y
> > CONFIG_FUSE_FS=y
> > CONFIG_GENERIC_ACL=y
> > CONFIG_FSCACHE=y
> > CONFIG_FSCACHE_STATS=y
> > CONFIG_FSCACHE_HISTOGRAM=y
> > CONFIG_CACHEFILES=y
> > CONFIG_CACHEFILES_HISTOGRAM=y
> > CONFIG_ISO9660_FS=y
> > CONFIG_JOLIET=y
> > CONFIG_ZISOFS=y
> > CONFIG_FAT_FS=y
> > CONFIG_MSDOS_FS=y
> > CONFIG_VFAT_FS=y
> > CONFIG_FAT_DEFAULT_CODEPAGE=850
> > CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
> > CONFIG_NTFS_FS=y
> > CONFIG_NTFS_RW=y
> > CONFIG_PROC_FS=y
> > CONFIG_PROC_KCORE=y
> > CONFIG_PROC_VMCORE=y
> > CONFIG_PROC_SYSCTL=y
> > CONFIG_PROC_PAGE_MONITOR=y
> > CONFIG_SYSFS=y
> > CONFIG_TMPFS=y
> > CONFIG_TMPFS_POSIX_ACL=y
> > CONFIG_TMPFS_XATTR=y
> > CONFIG_CONFIGFS_FS=y
> > CONFIG_PARTITION_ADVANCED=y
> > CONFIG_MSDOS_PARTITION=y
> > CONFIG_BSD_DISKLABEL=y
> > CONFIG_MINIX_SUBPARTITION=y
> > CONFIG_SOLARIS_X86_PARTITION=y
> > CONFIG_UNIXWARE_DISKLABEL=y
> > CONFIG_LDM_PARTITION=y
> > CONFIG_SUN_PARTITION=y
> > CONFIG_EFI_PARTITION=y
> > CONFIG_NLS=y
> > CONFIG_NLS_DEFAULT="utf8"
> > CONFIG_NLS_CODEPAGE_437=y
> > CONFIG_NLS_CODEPAGE_850=y
> > CONFIG_NLS_ASCII=y
> > CONFIG_NLS_ISO8859_1=y
> > CONFIG_NLS_ISO8859_15=y
> > CONFIG_NLS_UTF8=y
> > CONFIG_TRACE_IRQFLAGS_SUPPORT=y
> > CONFIG_PRINTK_TIME=y
> > CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7
> > CONFIG_ENABLE_MUST_CHECK=y
> > CONFIG_FRAME_WARN=2048
> > CONFIG_MAGIC_SYSRQ=y
> > CONFIG_DEBUG_FS=y
> > CONFIG_DEBUG_KERNEL=y
> > CONFIG_LOCKUP_DETECTOR=y
> > CONFIG_HARDLOCKUP_DETECTOR=y
> > CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
> > CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
> > CONFIG_STACKTRACE=y
> > CONFIG_DEBUG_BUGVERBOSE=y
> > CONFIG_DEBUG_INFO=y
> > CONFIG_DEBUG_INFO_REDUCED=y
> > CONFIG_DEBUG_MEMORY_INIT=y
> > CONFIG_ARCH_WANT_FRAME_POINTERS=y
> > CONFIG_FRAME_POINTER=y
> > CONFIG_BOOT_PRINTK_DELAY=y
> > CONFIG_RCU_CPU_STALL_TIMEOUT=60
> > CONFIG_LKDTM=y
> > CONFIG_CPU_NOTIFIER_ERROR_INJECT=y
> > CONFIG_SYSCTL_SYSCALL_CHECK=y
> > CONFIG_USER_STACKTRACE_SUPPORT=y
> > CONFIG_NOP_TRACER=y
> > CONFIG_HAVE_FUNCTION_TRACER=y
> > CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
> > CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
> > CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
> > CONFIG_HAVE_DYNAMIC_FTRACE=y
> > CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
> > CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
> > CONFIG_HAVE_C_RECORDMCOUNT=y
> > CONFIG_RING_BUFFER=y
> > CONFIG_EVENT_TRACING=y
> > CONFIG_EVENT_POWER_TRACING_DEPRECATED=y
> > CONFIG_CONTEXT_SWITCH_TRACER=y
> > CONFIG_TRACING=y
> > CONFIG_GENERIC_TRACER=y
> > CONFIG_TRACING_SUPPORT=y
> > CONFIG_FTRACE=y
> > CONFIG_BRANCH_PROFILE_NONE=y
> > CONFIG_BLK_DEV_IO_TRACE=y
> > CONFIG_HAVE_ARCH_KGDB=y
> > CONFIG_HAVE_ARCH_KMEMCHECK=y
> > CONFIG_STRICT_DEVMEM=y
> > CONFIG_X86_VERBOSE_BOOTUP=y
> > CONFIG_EARLY_PRINTK=y
> > CONFIG_DEBUG_RODATA=y
> > CONFIG_HAVE_MMIOTRACE_SUPPORT=y
> > CONFIG_IO_DELAY_TYPE_0X80=0
> > CONFIG_IO_DELAY_TYPE_0XED=1
> > CONFIG_IO_DELAY_TYPE_UDELAY=2
> > CONFIG_IO_DELAY_TYPE_NONE=3
> > CONFIG_IO_DELAY_0X80=y
> > CONFIG_DEFAULT_IO_DELAY_TYPE=0
> > CONFIG_KEYS=y
> > CONFIG_DEFAULT_SECURITY_DAC=y
> > CONFIG_DEFAULT_SECURITY=""
> > CONFIG_CRYPTO=y
> > CONFIG_CRYPTO_ALGAPI=y
> > CONFIG_CRYPTO_ALGAPI2=y
> > CONFIG_CRYPTO_AEAD=y
> > CONFIG_CRYPTO_AEAD2=y
> > CONFIG_CRYPTO_BLKCIPHER=y
> > CONFIG_CRYPTO_BLKCIPHER2=y
> > CONFIG_CRYPTO_HASH=y
> > CONFIG_CRYPTO_HASH2=y
> > CONFIG_CRYPTO_RNG2=y
> > CONFIG_CRYPTO_PCOMP2=y
> > CONFIG_CRYPTO_MANAGER=y
> > CONFIG_CRYPTO_MANAGER2=y
> > CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
> > CONFIG_CRYPTO_WORKQUEUE=y
> > CONFIG_CRYPTO_AUTHENC=y
> > CONFIG_CRYPTO_CBC=y
> > CONFIG_CRYPTO_HMAC=y
> > CONFIG_CRYPTO_CRC32C=y
> > CONFIG_CRYPTO_MD5=y
> > CONFIG_CRYPTO_SHA1=y
> > CONFIG_CRYPTO_AES=y
> > CONFIG_CRYPTO_DES=y
> > CONFIG_HAVE_KVM=y
> > CONFIG_BINARY_PRINTF=y
> > CONFIG_BITREVERSE=y
> > CONFIG_GENERIC_FIND_FIRST_BIT=y
> > CONFIG_CRC16=y
> > CONFIG_CRC32=y
> > CONFIG_LIBCRC32C=y
> > CONFIG_ZLIB_INFLATE=y
> > CONFIG_LZO_COMPRESS=y
> > CONFIG_LZO_DECOMPRESS=y
> > CONFIG_XZ_DEC=y
> > CONFIG_XZ_DEC_X86=y
> > CONFIG_XZ_DEC_POWERPC=y
> > CONFIG_XZ_DEC_IA64=y
> > CONFIG_XZ_DEC_ARM=y
> > CONFIG_XZ_DEC_ARMTHUMB=y
> > CONFIG_XZ_DEC_SPARC=y
> > CONFIG_XZ_DEC_BCJ=y
> > CONFIG_DECOMPRESS_GZIP=y
> > CONFIG_DECOMPRESS_BZIP2=y
> > CONFIG_DECOMPRESS_LZMA=y
> > CONFIG_DECOMPRESS_XZ=y
> > CONFIG_DECOMPRESS_LZO=y
> > CONFIG_HAS_IOMEM=y
> > CONFIG_HAS_IOPORT=y
> > CONFIG_HAS_DMA=y
> > CONFIG_CHECK_SIGNATURE=y
> > CONFIG_CPU_RMAP=y
> > CONFIG_NLATTR=y
> > ----------------
> >
> > ------ contents of /sys/devices/system/cpu/* after cpu 1 and cpu2 have been turned off -----------
> > $ grep -r . /sys/devices/system/cpu/
> > grep: /sys/devices/system/cpu/probe: Permission denied
> > grep: /sys/devices/system/cpu/release: Permission denied
> > /sys/devices/system/cpu/online:0,3
> > /sys/devices/system/cpu/possible:0-3
> > /sys/devices/system/cpu/present:0-3
> > /sys/devices/system/cpu/kernel_max:3
> > /sys/devices/system/cpu/offline:1-2
> > /sys/devices/system/cpu/cpuidle/current_driver:intel_idle
> > /sys/devices/system/cpu/cpuidle/current_governor_ro:menu
> > /sys/devices/system/cpu/cpu0/crash_notes:13fc14a10
> > /sys/devices/system/cpu/cpu0/cache/index0/type:Data
> > /sys/devices/system/cpu/cpu0/cache/index0/level:1
> > /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size:64
> > /sys/devices/system/cpu/cpu0/cache/index0/physical_line_partition:1
> > /sys/devices/system/cpu/cpu0/cache/index0/ways_of_associativity:6
> > /sys/devices/system/cpu/cpu0/cache/index0/number_of_sets:64
> > /sys/devices/system/cpu/cpu0/cache/index0/size:24K
> > /sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_map:9
> > /sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list:0,3
> > /sys/devices/system/cpu/cpu0/cache/index1/type:Instruction
> > /sys/devices/system/cpu/cpu0/cache/index1/level:1
> > /sys/devices/system/cpu/cpu0/cache/index1/coherency_line_size:64
> > /sys/devices/system/cpu/cpu0/cache/index1/physical_line_partition:1
> > /sys/devices/system/cpu/cpu0/cache/index1/ways_of_associativity:8
> > /sys/devices/system/cpu/cpu0/cache/index1/number_of_sets:64
> > /sys/devices/system/cpu/cpu0/cache/index1/size:32K
> > /sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_map:9
> > /sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_list:0,3
> > /sys/devices/system/cpu/cpu0/cache/index2/type:Unified
> > /sys/devices/system/cpu/cpu0/cache/index2/level:2
> > /sys/devices/system/cpu/cpu0/cache/index2/coherency_line_size:64
> > /sys/devices/system/cpu/cpu0/cache/index2/physical_line_partition:1
> > /sys/devices/system/cpu/cpu0/cache/index2/ways_of_associativity:8
> > /sys/devices/system/cpu/cpu0/cache/index2/number_of_sets:1024
> > /sys/devices/system/cpu/cpu0/cache/index2/size:512K
> > /sys/devices/system/cpu/cpu0/cache/index2/shared_cpu_map:9
> > /sys/devices/system/cpu/cpu0/cache/index2/shared_cpu_list:0,3
> > /sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count:0
> > grep: /sys/devices/system/cpu/cpu0/microcode/reload: Permission denied
> > /sys/devices/system/cpu/cpu0/microcode/version:0x107
> > /sys/devices/system/cpu/cpu0/microcode/processor_flags:0x8
> > /sys/devices/system/cpu/cpu0/cpuidle/state0/name:POLL
> > /sys/devices/system/cpu/cpu0/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
> > /sys/devices/system/cpu/cpu0/cpuidle/state0/latency:0
> > /sys/devices/system/cpu/cpu0/cpuidle/state0/power:4294967295
> > /sys/devices/system/cpu/cpu0/cpuidle/state0/usage:8
> > /sys/devices/system/cpu/cpu0/cpuidle/state0/time:1838938
> > /sys/devices/system/cpu/cpu0/cpuidle/state1/name:C1-ATM
> > /sys/devices/system/cpu/cpu0/cpuidle/state1/desc:MWAIT 0x00
> > /sys/devices/system/cpu/cpu0/cpuidle/state1/latency:1
> > /sys/devices/system/cpu/cpu0/cpuidle/state1/power:4294967294
> > /sys/devices/system/cpu/cpu0/cpuidle/state1/usage:15944
> > /sys/devices/system/cpu/cpu0/cpuidle/state1/time:167329609
> > /sys/devices/system/cpu/cpu0/topology/physical_package_id:0
> > /sys/devices/system/cpu/cpu0/topology/core_id:0
> > /sys/devices/system/cpu/cpu0/topology/thread_siblings:9
> > /sys/devices/system/cpu/cpu0/topology/thread_siblings_list:0,3
> > /sys/devices/system/cpu/cpu0/topology/core_siblings:9
> > /sys/devices/system/cpu/cpu0/topology/core_siblings_list:0,3
> > /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq:225000
> > /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq:1800000
> > /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency:10000001
> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq:225000
> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq:1800000
> > /sys/devices/system/cpu/cpu0/cpufreq/affected_cpus:0 3
> > /sys/devices/system/cpu/cpu0/cpufreq/related_cpus:0 3
> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor:userspace
> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver:p4-clockmod
> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors:ondemand userspace performance
> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed:1800000
> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies:225000 450000 675000 900000 1125000 1350000 1575000 1800000
> > /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq:1800000
> > /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq:1800000
> > /sys/devices/system/cpu/cpu1/online:0
> > /sys/devices/system/cpu/cpu1/crash_notes:13fc94a10
> > /sys/devices/system/cpu/cpu1/cpuidle/state0/name:POLL
> > /sys/devices/system/cpu/cpu1/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
> > /sys/devices/system/cpu/cpu1/cpuidle/state0/latency:0
> > /sys/devices/system/cpu/cpu1/cpuidle/state0/power:4294967295
> > /sys/devices/system/cpu/cpu1/cpuidle/state0/usage:10
> > /sys/devices/system/cpu/cpu1/cpuidle/state0/time:3742
> > /sys/devices/system/cpu/cpu1/cpuidle/state1/name:C1-ATM
> > /sys/devices/system/cpu/cpu1/cpuidle/state1/desc:MWAIT 0x00
> > /sys/devices/system/cpu/cpu1/cpuidle/state1/latency:1
> > /sys/devices/system/cpu/cpu1/cpuidle/state1/power:4294967294
> > /sys/devices/system/cpu/cpu1/cpuidle/state1/usage:3388
> > /sys/devices/system/cpu/cpu1/cpuidle/state1/time:24732806
> > /sys/devices/system/cpu/cpu2/online:0
> > /sys/devices/system/cpu/cpu2/crash_notes:13fd14a10
> > /sys/devices/system/cpu/cpu2/cpuidle/state0/name:POLL
> > /sys/devices/system/cpu/cpu2/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
> > /sys/devices/system/cpu/cpu2/cpuidle/state0/latency:0
> > /sys/devices/system/cpu/cpu2/cpuidle/state0/power:4294967295
> > /sys/devices/system/cpu/cpu2/cpuidle/state0/usage:12
> > /sys/devices/system/cpu/cpu2/cpuidle/state0/time:855620
> > /sys/devices/system/cpu/cpu2/cpuidle/state1/name:C1-ATM
> > /sys/devices/system/cpu/cpu2/cpuidle/state1/desc:MWAIT 0x00
> > /sys/devices/system/cpu/cpu2/cpuidle/state1/latency:1
> > /sys/devices/system/cpu/cpu2/cpuidle/state1/power:4294967294
> > /sys/devices/system/cpu/cpu2/cpuidle/state1/usage:4455
> > /sys/devices/system/cpu/cpu2/cpuidle/state1/time:27807198
> > /sys/devices/system/cpu/cpu3/online:1
> > /sys/devices/system/cpu/cpu3/crash_notes:13fd94a10
> > /sys/devices/system/cpu/cpu3/thermal_throttle/core_throttle_count:0
> > /sys/devices/system/cpu/cpu3/topology/physical_package_id:0
> > /sys/devices/system/cpu/cpu3/topology/core_id:0
> > /sys/devices/system/cpu/cpu3/topology/thread_siblings:9
> > /sys/devices/system/cpu/cpu3/topology/thread_siblings_list:0,3
> > /sys/devices/system/cpu/cpu3/topology/core_siblings:9
> > /sys/devices/system/cpu/cpu3/topology/core_siblings_list:0,3
> > /sys/devices/system/cpu/cpu3/cache/index0/type:Data
> > /sys/devices/system/cpu/cpu3/cache/index0/level:1
> > /sys/devices/system/cpu/cpu3/cache/index0/coherency_line_size:64
> > /sys/devices/system/cpu/cpu3/cache/index0/physical_line_partition:1
> > /sys/devices/system/cpu/cpu3/cache/index0/ways_of_associativity:6
> > /sys/devices/system/cpu/cpu3/cache/index0/number_of_sets:64
> > /sys/devices/system/cpu/cpu3/cache/index0/size:24K
> > /sys/devices/system/cpu/cpu3/cache/index0/shared_cpu_map:9
> > /sys/devices/system/cpu/cpu3/cache/index0/shared_cpu_list:0,3
> > /sys/devices/system/cpu/cpu3/cache/index1/type:Instruction
> > /sys/devices/system/cpu/cpu3/cache/index1/level:1
> > /sys/devices/system/cpu/cpu3/cache/index1/coherency_line_size:64
> > /sys/devices/system/cpu/cpu3/cache/index1/physical_line_partition:1
> > /sys/devices/system/cpu/cpu3/cache/index1/ways_of_associativity:8
> > /sys/devices/system/cpu/cpu3/cache/index1/number_of_sets:64
> > /sys/devices/system/cpu/cpu3/cache/index1/size:32K
> > /sys/devices/system/cpu/cpu3/cache/index1/shared_cpu_map:9
> > /sys/devices/system/cpu/cpu3/cache/index1/shared_cpu_list:0,3
> > /sys/devices/system/cpu/cpu3/cache/index2/type:Unified
> > /sys/devices/system/cpu/cpu3/cache/index2/level:2
> > /sys/devices/system/cpu/cpu3/cache/index2/coherency_line_size:64
> > /sys/devices/system/cpu/cpu3/cache/index2/physical_line_partition:1
> > /sys/devices/system/cpu/cpu3/cache/index2/ways_of_associativity:8
> > /sys/devices/system/cpu/cpu3/cache/index2/number_of_sets:1024
> > /sys/devices/system/cpu/cpu3/cache/index2/size:512K
> > /sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_map:9
> > /sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_list:0,3
> > grep: /sys/devices/system/cpu/cpu3/microcode/reload: Permission denied
> > /sys/devices/system/cpu/cpu3/microcode/version:0x107
> > /sys/devices/system/cpu/cpu3/microcode/processor_flags:0x8
> > /sys/devices/system/cpu/cpu3/cpuidle/state0/name:POLL
> > /sys/devices/system/cpu/cpu3/cpuidle/state0/desc:CPUIDLE CORE POLL IDLE
> > /sys/devices/system/cpu/cpu3/cpuidle/state0/latency:0
> > /sys/devices/system/cpu/cpu3/cpuidle/state0/power:4294967295
> > /sys/devices/system/cpu/cpu3/cpuidle/state0/usage:21
> > /sys/devices/system/cpu/cpu3/cpuidle/state0/time:2055565
> > /sys/devices/system/cpu/cpu3/cpuidle/state1/name:C1-ATM
> > /sys/devices/system/cpu/cpu3/cpuidle/state1/desc:MWAIT 0x00
> > /sys/devices/system/cpu/cpu3/cpuidle/state1/latency:1
> > /sys/devices/system/cpu/cpu3/cpuidle/state1/power:4294967294
> > /sys/devices/system/cpu/cpu3/cpuidle/state1/usage:13834
> > /sys/devices/system/cpu/cpu3/cpuidle/state1/time:166939905
> > ---------------------
> >
> > ------------------------------ contents of /sys/power/* -----------------
> > $ grep -r . /sys/power/
> > /sys/power/state:mem disk
> > /sys/power/pm_trace:0
> > /sys/power/pm_async:1
> > /sys/power/wakeup_count:0
> > /sys/power/pm_test:[none] core processors platform devices freezer
> > /sys/power/disk:[platform] test testproc shutdown reboot
> > /sys/power/resume:8:2
> > /sys/power/image_size:1628569600
> > /sys/power/reserved_size:1048576
> > --------------------------------------------------------------------
> >
> >
> > ______________________________________________________
> > PixiMail - The secret Freedom
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at http://www.tux.org/lkml/
> >
> >
>
^ permalink raw reply
* [RFC/PATCH v3 00/13] PM QoS: add a per-device latency constraints class
From: jean.pihet @ 2011-07-28 8:30 UTC (permalink / raw)
To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
Linux PM mailing list
Cc: Jean Pihet
From: Jean Pihet <j-pihet@ti.com>
This patch set is in an RFC state, for review and comments.
High level implementation:
1. Add a new PM QoS class for device wake-up constraints (PM_QOS_DEV_LATENCY).
. Define a pm_qos_constraints struct for the storage of the constraints list
and associated values (target_value, default_value, type ...).
. Update the pm_qos_object struct with the information related to a PM QoS
class: ptr to constraints list, notifer ptr, name ...
. Each PM QoS class statically declare objects for pm_qos_object and
pm_qos_constraints. The only exception is the devices constraints, cf. below.
. The device constraints class is statically declaring a pm_qos_object. The
pm_qos_constraints are per-device and so are embedded into the device struct.
The new class is available from kernel drivers and shall be made available
to user space through a per-device sysfs entry. User space API to come as a
subsequent patch.
2. Added a notification of device insertion/removal from the device PM framework
to PM QoS.
This allows to init/de-init the per-device constraints list upon device insertion
and removal.
RFC state for comments and review, lightly tested
3. Make the pm_qos_add_request API more generic by using a
struct pm_qos_parameters parameter. This allows easy extension in the future.
4. Upon a change of the aggregated constraint value in the PM_QOS_DEV_LATENCY class
a notification chain mechanism is used to take action on the system.
This is the proposed way to have PM QoS and the platform dependant code to
interact with each other, cf. 5 below.
The notification mechanism now passes the constraint request struct ptr in
order for the notifier callback to have access to the full set of constraint
data, e.g. the struct device ptr.
5. cpuidle interaction with the OMAP3 cpuidle handler
Since cpuidle is a CPU centric framework it decides the MPU next power state
based on the MPU exit_latency and target_residency figures.
The rest of the power domains get their next power state programmed from
the PM_QOS_DEV_LATENCY class of the PM QoS framework, via the device
wake-up latency constraints callback to the OMAP_PM_CONSTRAINTS framework.
Note: the exit_latency and target_residency figures of the MPU include the MPU
itself and the peripherals needed for the MPU to execute instructions (e.g.
main memory, caches, IRQ controller, MMU etc).
Some of those peripherals can belong to other power domains than the MPU
subsystem and so the corresponding latencies must be included in those figures.
6. Update the pm_qos_add_request callers to the generic API
7. Misc fixes to improve code readability:
. rename of the PM QoS implementation file from pm_qos_params.[ch] to pm_qos.[ch]
. rename of fields names (request, list, constraints, class),
. simplification of the in-kernel PM QoS API implementation. The main logic part
is now implemented in the update_target function.
Questions:
1. per-device user-space API: since sysfs does not provide open/close
callbacks it is not possible to support multiple and simultaneous users of
the per-device sysfs entry. A user-space constraints aggregation application is
needed in case of multiple constraints for a device. Is this the way to go?
On-going developments, patches in preparation:
1. add a user-space API for the devices constratins PM QoS, using a sysfs entry
per device
2. write Documentation for the new PM QoS class, once the RFC is agreed on
3. validate the constraints framework on OMAP4 HW (done on OMAP3)
4. refine the power domains wake-up latency and the cpuidle figures
Based on the master branch of the linux-omap git tree (3.0.0-rc7). Compile
tested using OMAP and x86 generic defconfigs.
Lightly tested on OMAP3 Beagleboard (ES2.x).
Changelog:
v3:
. Complete PM QoS re-design after the comments on MLs
. Patch set split up for improved readability and easier maintenance
v2:
. Rework after comments on the mailing lists
. Added a notification of device insertion/removal from the device PM framework
. Validated on OMAP3 HW
v1:
. Initial implementation
Jean Pihet (12):
PM: QoS: rename pm_qos_params files to pm_qos
PM: add a per-device wake-up latency constraints plist
PM: QoS: extend the in-kernel API with per-device latency constraints
PM: QoS: implement the per-device latency constraints
PM: QoS: support the dynamic insertion and removal of devices
OMAP PM: create a PM layer plugin for per-device constraints
OMAP PM: early init of the pwrdms states
OMAP2+: powerdomain: control power domains next state
OMAP3: powerdomain data: add wake-up latency figures
OMAP2+: omap_hwmod: manage the wake-up latency constraints
OMAP: PM CONSTRAINTS: implement the devices wake-up latency
constraints
OMAP2+: cpuidle only influences the MPU state
Vishwanath BS (1):
OMAP4: powerdomain data: add wake-up latency figures
arch/arm/mach-msm/clock.c | 2 +-
arch/arm/mach-omap2/cpuidle34xx.c | 42 +--
arch/arm/mach-omap2/omap_hwmod.c | 26 ++-
arch/arm/mach-omap2/pm.h | 17 +-
arch/arm/mach-omap2/pm34xx.c | 2 +-
arch/arm/mach-omap2/pm44xx.c | 2 +-
arch/arm/mach-omap2/powerdomain.c | 190 +++++++++
arch/arm/mach-omap2/powerdomain.h | 33 ++-
arch/arm/mach-omap2/powerdomains3xxx_data.c | 77 ++++
arch/arm/mach-omap2/powerdomains44xx_data.c | 84 ++++
arch/arm/plat-omap/Kconfig | 7 +
arch/arm/plat-omap/Makefile | 1 +
arch/arm/plat-omap/i2c.c | 20 -
arch/arm/plat-omap/include/plat/omap-pm.h | 128 ------
arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 +
arch/arm/plat-omap/omap-pm-constraints.c | 344 ++++++++++++++++
arch/arm/plat-omap/omap-pm-noop.c | 89 ----
drivers/acpi/processor_idle.c | 2 +-
drivers/base/power/main.c | 4 +
drivers/cpuidle/cpuidle.c | 2 +-
drivers/cpuidle/governors/ladder.c | 2 +-
drivers/cpuidle/governors/menu.c | 2 +-
drivers/i2c/busses/i2c-omap.c | 35 +-
drivers/media/video/via-camera.c | 9 +-
drivers/net/e1000e/netdev.c | 11 +-
drivers/net/wireless/ipw2x00/ipw2100.c | 10 +-
drivers/staging/msm/lcdc.c | 2 +-
drivers/staging/msm/tvenc.c | 2 +-
include/linux/netdevice.h | 4 +-
include/linux/pm.h | 4 +
include/linux/pm_qos.h | 68 ++++
include/linux/pm_qos_params.h | 38 --
include/sound/pcm.h | 4 +-
kernel/Makefile | 2 +-
kernel/pm_qos.c | 557 ++++++++++++++++++++++++++
kernel/pm_qos_params.c | 481 ----------------------
net/mac80211/main.c | 2 +-
net/mac80211/mlme.c | 2 +-
net/mac80211/scan.c | 2 +-
sound/core/pcm_native.c | 10 +-
40 files changed, 1487 insertions(+), 834 deletions(-)
create mode 100644 arch/arm/plat-omap/omap-pm-constraints.c
create mode 100644 include/linux/pm_qos.h
delete mode 100644 include/linux/pm_qos_params.h
create mode 100644 kernel/pm_qos.c
delete mode 100644 kernel/pm_qos_params.c
--
1.7.2.5
^ permalink raw reply
* [PATCH 01/13] PM: QoS: rename pm_qos_params files to pm_qos
From: jean.pihet @ 2011-07-28 8:30 UTC (permalink / raw)
To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
Linux PM mailing list
Cc: Jean Pihet
In-Reply-To: <1311841821-10252-1-git-send-email-j-pihet@ti.com>
From: Jean Pihet <j-pihet@ti.com>
The PM QoS implementation files are better named
kernel/pm_qos.c and include/linux/pm_qos.h.
Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
arch/arm/mach-msm/clock.c | 2 +-
drivers/acpi/processor_idle.c | 2 +-
drivers/cpuidle/cpuidle.c | 2 +-
drivers/cpuidle/governors/ladder.c | 2 +-
| 2 +-
drivers/media/video/via-camera.c | 2 +-
drivers/net/e1000e/netdev.c | 2 +-
drivers/net/wireless/ipw2x00/ipw2100.c | 2 +-
drivers/staging/msm/lcdc.c | 2 +-
drivers/staging/msm/tvenc.c | 2 +-
include/linux/netdevice.h | 2 +-
include/linux/pm_qos.h | 38 +++
include/linux/pm_qos_params.h | 38 ---
include/sound/pcm.h | 2 +-
kernel/Makefile | 2 +-
kernel/pm_qos.c | 481 ++++++++++++++++++++++++++++++++
kernel/pm_qos_params.c | 481 --------------------------------
net/mac80211/main.c | 2 +-
net/mac80211/mlme.c | 2 +-
net/mac80211/scan.c | 2 +-
sound/core/pcm_native.c | 2 +-
21 files changed, 536 insertions(+), 536 deletions(-)
create mode 100644 include/linux/pm_qos.h
delete mode 100644 include/linux/pm_qos_params.h
create mode 100644 kernel/pm_qos.c
delete mode 100644 kernel/pm_qos_params.c
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 22a5376..d9145df 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -18,7 +18,7 @@
#include <linux/list.h>
#include <linux/err.h>
#include <linux/spinlock.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/mutex.h>
#include <linux/clk.h>
#include <linux/string.h>
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 431ab11..2e69e09 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -37,7 +37,7 @@
#include <linux/dmi.h>
#include <linux/moduleparam.h>
#include <linux/sched.h> /* need_resched() */
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/clockchips.h>
#include <linux/cpuidle.h>
#include <linux/irqflags.h>
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index bf50924..eed4c47 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -12,7 +12,7 @@
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/notifier.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/cpu.h>
#include <linux/cpuidle.h>
#include <linux/ktime.h>
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index 12c9890..f62fde2 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -14,7 +14,7 @@
#include <linux/kernel.h>
#include <linux/cpuidle.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/moduleparam.h>
#include <linux/jiffies.h>
--git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index c47f3d0..3600f19 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -12,7 +12,7 @@
#include <linux/kernel.h>
#include <linux/cpuidle.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/time.h>
#include <linux/ktime.h>
#include <linux/hrtimer.h>
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 85d3048..b3ca389 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -21,7 +21,7 @@
#include <media/videobuf-dma-sg.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/via-core.h>
#include <linux/via-gpio.h>
#include <linux/via_i2c.h>
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 3310c3d..a8a18e1 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -46,7 +46,7 @@
#include <linux/if_vlan.h>
#include <linux/cpu.h>
#include <linux/smp.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/pm_runtime.h>
#include <linux/aer.h>
#include <linux/prefetch.h>
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 4430775..d9df575 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -161,7 +161,7 @@ that only one external action is invoked at a time.
#include <linux/firmware.h>
#include <linux/acpi.h>
#include <linux/ctype.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <net/lib80211.h>
diff --git a/drivers/staging/msm/lcdc.c b/drivers/staging/msm/lcdc.c
index 8183394..1d5183d 100644
--- a/drivers/staging/msm/lcdc.c
+++ b/drivers/staging/msm/lcdc.c
@@ -32,7 +32,7 @@
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include "msm_fb.h"
diff --git a/drivers/staging/msm/tvenc.c b/drivers/staging/msm/tvenc.c
index 4fbb77b..5a798b8 100644
--- a/drivers/staging/msm/tvenc.c
+++ b/drivers/staging/msm/tvenc.c
@@ -32,7 +32,7 @@
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#define TVENC_C
#include "tvenc.h"
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 54b8b4d..cc1eb9e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -31,7 +31,7 @@
#include <linux/if_link.h>
#ifdef __KERNEL__
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/mm.h>
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
new file mode 100644
index 0000000..9cc0224
--- /dev/null
+++ b/include/linux/pm_qos.h
@@ -0,0 +1,38 @@
+#ifndef _LINUX_PM_QOS_H
+#define _LINUX_PM_QOS_H
+/* interface for the pm_qos_power infrastructure of the linux kernel.
+ *
+ * Mark Gross <mgross@linux.intel.com>
+ */
+#include <linux/plist.h>
+#include <linux/notifier.h>
+#include <linux/miscdevice.h>
+
+#define PM_QOS_RESERVED 0
+#define PM_QOS_CPU_DMA_LATENCY 1
+#define PM_QOS_NETWORK_LATENCY 2
+#define PM_QOS_NETWORK_THROUGHPUT 3
+
+#define PM_QOS_NUM_CLASSES 4
+#define PM_QOS_DEFAULT_VALUE -1
+
+#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
+#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
+#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
+
+struct pm_qos_request_list {
+ struct plist_node list;
+ int pm_qos_class;
+};
+
+void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
+void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
+ s32 new_value);
+void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
+
+int pm_qos_request(int pm_qos_class);
+int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
+int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
+int pm_qos_request_active(struct pm_qos_request_list *req);
+
+#endif
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
deleted file mode 100644
index a7d87f9..0000000
--- a/include/linux/pm_qos_params.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _LINUX_PM_QOS_PARAMS_H
-#define _LINUX_PM_QOS_PARAMS_H
-/* interface for the pm_qos_power infrastructure of the linux kernel.
- *
- * Mark Gross <mgross@linux.intel.com>
- */
-#include <linux/plist.h>
-#include <linux/notifier.h>
-#include <linux/miscdevice.h>
-
-#define PM_QOS_RESERVED 0
-#define PM_QOS_CPU_DMA_LATENCY 1
-#define PM_QOS_NETWORK_LATENCY 2
-#define PM_QOS_NETWORK_THROUGHPUT 3
-
-#define PM_QOS_NUM_CLASSES 4
-#define PM_QOS_DEFAULT_VALUE -1
-
-#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
-#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
-#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
-
-struct pm_qos_request_list {
- struct plist_node list;
- int pm_qos_class;
-};
-
-void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
-void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
- s32 new_value);
-void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
-
-int pm_qos_request(int pm_qos_class);
-int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
-int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
-int pm_qos_request_active(struct pm_qos_request_list *req);
-
-#endif
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index e1bad11..1204f17 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -29,7 +29,7 @@
#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/bitops.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#define snd_pcm_substream_chip(substream) ((substream)->private_data)
#define snd_pcm_chip(pcm) ((pcm)->private_data)
diff --git a/kernel/Makefile b/kernel/Makefile
index 2d64cfc..3f6d0ed 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -9,7 +9,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
rcupdate.o extable.o params.o posix-timers.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
- notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \
+ notifier.o ksysfs.o pm_qos.o sched_clock.o cred.o \
async.o range.o jump_label.o
obj-y += groups.o
diff --git a/kernel/pm_qos.c b/kernel/pm_qos.c
new file mode 100644
index 0000000..3bf69f1
--- /dev/null
+++ b/kernel/pm_qos.c
@@ -0,0 +1,481 @@
+/*
+ * This module exposes the interface to kernel space for specifying
+ * QoS dependencies. It provides infrastructure for registration of:
+ *
+ * Dependents on a QoS value : register requests
+ * Watchers of QoS value : get notified when target QoS value changes
+ *
+ * This QoS design is best effort based. Dependents register their QoS needs.
+ * Watchers register to keep track of the current QoS needs of the system.
+ *
+ * There are 3 basic classes of QoS parameter: latency, timeout, throughput
+ * each have defined units:
+ * latency: usec
+ * timeout: usec <-- currently not used.
+ * throughput: kbs (kilo byte / sec)
+ *
+ * There are lists of pm_qos_objects each one wrapping requests, notifiers
+ *
+ * User mode requests on a QOS parameter register themselves to the
+ * subsystem by opening the device node /dev/... and writing there request to
+ * the node. As long as the process holds a file handle open to the node the
+ * client continues to be accounted for. Upon file release the usermode
+ * request is removed and a new qos target is computed. This way when the
+ * request that the application has is cleaned up when closes the file
+ * pointer or exits the pm_qos_object will get an opportunity to clean up.
+ *
+ * Mark Gross <mgross@linux.intel.com>
+ */
+
+/*#define DEBUG*/
+
+#include <linux/pm_qos.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <linux/uaccess.h>
+
+/*
+ * locking rule: all changes to requests or notifiers lists
+ * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock
+ * held, taken with _irqsave. One lock to rule them all
+ */
+enum pm_qos_type {
+ PM_QOS_MAX, /* return the largest value */
+ PM_QOS_MIN /* return the smallest value */
+};
+
+/*
+ * Note: The lockless read path depends on the CPU accessing
+ * target_value atomically. Atomic access is only guaranteed on all CPU
+ * types linux supports for 32 bit quantites
+ */
+struct pm_qos_object {
+ struct plist_head requests;
+ struct blocking_notifier_head *notifiers;
+ struct miscdevice pm_qos_power_miscdev;
+ char *name;
+ s32 target_value; /* Do not change to 64 bit */
+ s32 default_value;
+ enum pm_qos_type type;
+};
+
+static DEFINE_SPINLOCK(pm_qos_lock);
+
+static struct pm_qos_object null_pm_qos;
+static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
+static struct pm_qos_object cpu_dma_pm_qos = {
+ .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
+ .notifiers = &cpu_dma_lat_notifier,
+ .name = "cpu_dma_latency",
+ .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
+ .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
+ .type = PM_QOS_MIN,
+};
+
+static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
+static struct pm_qos_object network_lat_pm_qos = {
+ .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
+ .notifiers = &network_lat_notifier,
+ .name = "network_latency",
+ .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
+ .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
+ .type = PM_QOS_MIN
+};
+
+
+static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
+static struct pm_qos_object network_throughput_pm_qos = {
+ .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
+ .notifiers = &network_throughput_notifier,
+ .name = "network_throughput",
+ .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
+ .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
+ .type = PM_QOS_MAX,
+};
+
+
+static struct pm_qos_object *pm_qos_array[] = {
+ &null_pm_qos,
+ &cpu_dma_pm_qos,
+ &network_lat_pm_qos,
+ &network_throughput_pm_qos
+};
+
+static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos);
+static ssize_t pm_qos_power_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos);
+static int pm_qos_power_open(struct inode *inode, struct file *filp);
+static int pm_qos_power_release(struct inode *inode, struct file *filp);
+
+static const struct file_operations pm_qos_power_fops = {
+ .write = pm_qos_power_write,
+ .read = pm_qos_power_read,
+ .open = pm_qos_power_open,
+ .release = pm_qos_power_release,
+ .llseek = noop_llseek,
+};
+
+/* unlocked internal variant */
+static inline int pm_qos_get_value(struct pm_qos_object *o)
+{
+ if (plist_head_empty(&o->requests))
+ return o->default_value;
+
+ switch (o->type) {
+ case PM_QOS_MIN:
+ return plist_first(&o->requests)->prio;
+
+ case PM_QOS_MAX:
+ return plist_last(&o->requests)->prio;
+
+ default:
+ /* runtime check for not using enum */
+ BUG();
+ }
+}
+
+static inline s32 pm_qos_read_value(struct pm_qos_object *o)
+{
+ return o->target_value;
+}
+
+static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
+{
+ o->target_value = value;
+}
+
+static void update_target(struct pm_qos_object *o, struct plist_node *node,
+ int del, int value)
+{
+ unsigned long flags;
+ int prev_value, curr_value;
+
+ spin_lock_irqsave(&pm_qos_lock, flags);
+ prev_value = pm_qos_get_value(o);
+ /* PM_QOS_DEFAULT_VALUE is a signal that the value is unchanged */
+ if (value != PM_QOS_DEFAULT_VALUE) {
+ /*
+ * to change the list, we atomically remove, reinit
+ * with new value and add, then see if the extremal
+ * changed
+ */
+ plist_del(node, &o->requests);
+ plist_node_init(node, value);
+ plist_add(node, &o->requests);
+ } else if (del) {
+ plist_del(node, &o->requests);
+ } else {
+ plist_add(node, &o->requests);
+ }
+ curr_value = pm_qos_get_value(o);
+ pm_qos_set_value(o, curr_value);
+ spin_unlock_irqrestore(&pm_qos_lock, flags);
+
+ if (prev_value != curr_value)
+ blocking_notifier_call_chain(o->notifiers,
+ (unsigned long)curr_value,
+ NULL);
+}
+
+static int register_pm_qos_misc(struct pm_qos_object *qos)
+{
+ qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR;
+ qos->pm_qos_power_miscdev.name = qos->name;
+ qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops;
+
+ return misc_register(&qos->pm_qos_power_miscdev);
+}
+
+static int find_pm_qos_object_by_minor(int minor)
+{
+ int pm_qos_class;
+
+ for (pm_qos_class = 0;
+ pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) {
+ if (minor ==
+ pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor)
+ return pm_qos_class;
+ }
+ return -1;
+}
+
+/**
+ * pm_qos_request - returns current system wide qos expectation
+ * @pm_qos_class: identification of which qos value is requested
+ *
+ * This function returns the current target value.
+ */
+int pm_qos_request(int pm_qos_class)
+{
+ return pm_qos_read_value(pm_qos_array[pm_qos_class]);
+}
+EXPORT_SYMBOL_GPL(pm_qos_request);
+
+int pm_qos_request_active(struct pm_qos_request_list *req)
+{
+ return req->pm_qos_class != 0;
+}
+EXPORT_SYMBOL_GPL(pm_qos_request_active);
+
+/**
+ * pm_qos_add_request - inserts new qos request into the list
+ * @dep: pointer to a preallocated handle
+ * @pm_qos_class: identifies which list of qos request to use
+ * @value: defines the qos request
+ *
+ * This function inserts a new entry in the pm_qos_class list of requested qos
+ * performance characteristics. It recomputes the aggregate QoS expectations
+ * for the pm_qos_class of parameters and initializes the pm_qos_request_list
+ * handle. Caller needs to save this handle for later use in updates and
+ * removal.
+ */
+
+void pm_qos_add_request(struct pm_qos_request_list *dep,
+ int pm_qos_class, s32 value)
+{
+ struct pm_qos_object *o = pm_qos_array[pm_qos_class];
+ int new_value;
+
+ if (pm_qos_request_active(dep)) {
+ WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n");
+ return;
+ }
+ if (value == PM_QOS_DEFAULT_VALUE)
+ new_value = o->default_value;
+ else
+ new_value = value;
+ plist_node_init(&dep->list, new_value);
+ dep->pm_qos_class = pm_qos_class;
+ update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE);
+}
+EXPORT_SYMBOL_GPL(pm_qos_add_request);
+
+/**
+ * pm_qos_update_request - modifies an existing qos request
+ * @pm_qos_req : handle to list element holding a pm_qos request to use
+ * @value: defines the qos request
+ *
+ * Updates an existing qos request for the pm_qos_class of parameters along
+ * with updating the target pm_qos_class value.
+ *
+ * Attempts are made to make this code callable on hot code paths.
+ */
+void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
+ s32 new_value)
+{
+ s32 temp;
+ struct pm_qos_object *o;
+
+ if (!pm_qos_req) /*guard against callers passing in null */
+ return;
+
+ if (!pm_qos_request_active(pm_qos_req)) {
+ WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n");
+ return;
+ }
+
+ o = pm_qos_array[pm_qos_req->pm_qos_class];
+
+ if (new_value == PM_QOS_DEFAULT_VALUE)
+ temp = o->default_value;
+ else
+ temp = new_value;
+
+ if (temp != pm_qos_req->list.prio)
+ update_target(o, &pm_qos_req->list, 0, temp);
+}
+EXPORT_SYMBOL_GPL(pm_qos_update_request);
+
+/**
+ * pm_qos_remove_request - modifies an existing qos request
+ * @pm_qos_req: handle to request list element
+ *
+ * Will remove pm qos request from the list of requests and
+ * recompute the current target value for the pm_qos_class. Call this
+ * on slow code paths.
+ */
+void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
+{
+ struct pm_qos_object *o;
+
+ if (pm_qos_req == NULL)
+ return;
+ /* silent return to keep pcm code cleaner */
+
+ if (!pm_qos_request_active(pm_qos_req)) {
+ WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n");
+ return;
+ }
+
+ o = pm_qos_array[pm_qos_req->pm_qos_class];
+ update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE);
+ memset(pm_qos_req, 0, sizeof(*pm_qos_req));
+}
+EXPORT_SYMBOL_GPL(pm_qos_remove_request);
+
+/**
+ * pm_qos_add_notifier - sets notification entry for changes to target value
+ * @pm_qos_class: identifies which qos target changes should be notified.
+ * @notifier: notifier block managed by caller.
+ *
+ * will register the notifier into a notification chain that gets called
+ * upon changes to the pm_qos_class target value.
+ */
+int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
+{
+ int retval;
+
+ retval = blocking_notifier_chain_register(
+ pm_qos_array[pm_qos_class]->notifiers, notifier);
+
+ return retval;
+}
+EXPORT_SYMBOL_GPL(pm_qos_add_notifier);
+
+/**
+ * pm_qos_remove_notifier - deletes notification entry from chain.
+ * @pm_qos_class: identifies which qos target changes are notified.
+ * @notifier: notifier block to be removed.
+ *
+ * will remove the notifier from the notification chain that gets called
+ * upon changes to the pm_qos_class target value.
+ */
+int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier)
+{
+ int retval;
+
+ retval = blocking_notifier_chain_unregister(
+ pm_qos_array[pm_qos_class]->notifiers, notifier);
+
+ return retval;
+}
+EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
+
+static int pm_qos_power_open(struct inode *inode, struct file *filp)
+{
+ long pm_qos_class;
+
+ pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
+ if (pm_qos_class >= 0) {
+ struct pm_qos_request_list *req = kzalloc(sizeof(*req), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE);
+ filp->private_data = req;
+
+ if (filp->private_data)
+ return 0;
+ }
+ return -EPERM;
+}
+
+static int pm_qos_power_release(struct inode *inode, struct file *filp)
+{
+ struct pm_qos_request_list *req;
+
+ req = filp->private_data;
+ pm_qos_remove_request(req);
+ kfree(req);
+
+ return 0;
+}
+
+
+static ssize_t pm_qos_power_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ s32 value;
+ unsigned long flags;
+ struct pm_qos_object *o;
+ struct pm_qos_request_list *pm_qos_req = filp->private_data;
+
+ if (!pm_qos_req)
+ return -EINVAL;
+ if (!pm_qos_request_active(pm_qos_req))
+ return -EINVAL;
+
+ o = pm_qos_array[pm_qos_req->pm_qos_class];
+ spin_lock_irqsave(&pm_qos_lock, flags);
+ value = pm_qos_get_value(o);
+ spin_unlock_irqrestore(&pm_qos_lock, flags);
+
+ return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32));
+}
+
+static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ s32 value;
+ struct pm_qos_request_list *pm_qos_req;
+
+ if (count == sizeof(s32)) {
+ if (copy_from_user(&value, buf, sizeof(s32)))
+ return -EFAULT;
+ } else if (count <= 11) { /* ASCII perhaps? */
+ char ascii_value[11];
+ unsigned long int ulval;
+ int ret;
+
+ if (copy_from_user(ascii_value, buf, count))
+ return -EFAULT;
+
+ if (count > 10) {
+ if (ascii_value[10] == '\n')
+ ascii_value[10] = '\0';
+ else
+ return -EINVAL;
+ } else {
+ ascii_value[count] = '\0';
+ }
+ ret = strict_strtoul(ascii_value, 16, &ulval);
+ if (ret) {
+ pr_debug("%s, 0x%lx, 0x%x\n", ascii_value, ulval, ret);
+ return -EINVAL;
+ }
+ value = (s32)lower_32_bits(ulval);
+ } else {
+ return -EINVAL;
+ }
+
+ pm_qos_req = filp->private_data;
+ pm_qos_update_request(pm_qos_req, value);
+
+ return count;
+}
+
+
+static int __init pm_qos_power_init(void)
+{
+ int ret = 0;
+
+ ret = register_pm_qos_misc(&cpu_dma_pm_qos);
+ if (ret < 0) {
+ printk(KERN_ERR "pm_qos_param: cpu_dma_latency setup failed\n");
+ return ret;
+ }
+ ret = register_pm_qos_misc(&network_lat_pm_qos);
+ if (ret < 0) {
+ printk(KERN_ERR "pm_qos_param: network_latency setup failed\n");
+ return ret;
+ }
+ ret = register_pm_qos_misc(&network_throughput_pm_qos);
+ if (ret < 0)
+ printk(KERN_ERR
+ "pm_qos_param: network_throughput setup failed\n");
+
+ return ret;
+}
+
+late_initcall(pm_qos_power_init);
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
deleted file mode 100644
index 6824ca7..0000000
--- a/kernel/pm_qos_params.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * This module exposes the interface to kernel space for specifying
- * QoS dependencies. It provides infrastructure for registration of:
- *
- * Dependents on a QoS value : register requests
- * Watchers of QoS value : get notified when target QoS value changes
- *
- * This QoS design is best effort based. Dependents register their QoS needs.
- * Watchers register to keep track of the current QoS needs of the system.
- *
- * There are 3 basic classes of QoS parameter: latency, timeout, throughput
- * each have defined units:
- * latency: usec
- * timeout: usec <-- currently not used.
- * throughput: kbs (kilo byte / sec)
- *
- * There are lists of pm_qos_objects each one wrapping requests, notifiers
- *
- * User mode requests on a QOS parameter register themselves to the
- * subsystem by opening the device node /dev/... and writing there request to
- * the node. As long as the process holds a file handle open to the node the
- * client continues to be accounted for. Upon file release the usermode
- * request is removed and a new qos target is computed. This way when the
- * request that the application has is cleaned up when closes the file
- * pointer or exits the pm_qos_object will get an opportunity to clean up.
- *
- * Mark Gross <mgross@linux.intel.com>
- */
-
-/*#define DEBUG*/
-
-#include <linux/pm_qos_params.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/miscdevice.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <linux/uaccess.h>
-
-/*
- * locking rule: all changes to requests or notifiers lists
- * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock
- * held, taken with _irqsave. One lock to rule them all
- */
-enum pm_qos_type {
- PM_QOS_MAX, /* return the largest value */
- PM_QOS_MIN /* return the smallest value */
-};
-
-/*
- * Note: The lockless read path depends on the CPU accessing
- * target_value atomically. Atomic access is only guaranteed on all CPU
- * types linux supports for 32 bit quantites
- */
-struct pm_qos_object {
- struct plist_head requests;
- struct blocking_notifier_head *notifiers;
- struct miscdevice pm_qos_power_miscdev;
- char *name;
- s32 target_value; /* Do not change to 64 bit */
- s32 default_value;
- enum pm_qos_type type;
-};
-
-static DEFINE_SPINLOCK(pm_qos_lock);
-
-static struct pm_qos_object null_pm_qos;
-static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
-static struct pm_qos_object cpu_dma_pm_qos = {
- .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
- .notifiers = &cpu_dma_lat_notifier,
- .name = "cpu_dma_latency",
- .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
- .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
- .type = PM_QOS_MIN,
-};
-
-static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
-static struct pm_qos_object network_lat_pm_qos = {
- .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
- .notifiers = &network_lat_notifier,
- .name = "network_latency",
- .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
- .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
- .type = PM_QOS_MIN
-};
-
-
-static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
-static struct pm_qos_object network_throughput_pm_qos = {
- .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
- .notifiers = &network_throughput_notifier,
- .name = "network_throughput",
- .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
- .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
- .type = PM_QOS_MAX,
-};
-
-
-static struct pm_qos_object *pm_qos_array[] = {
- &null_pm_qos,
- &cpu_dma_pm_qos,
- &network_lat_pm_qos,
- &network_throughput_pm_qos
-};
-
-static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *f_pos);
-static ssize_t pm_qos_power_read(struct file *filp, char __user *buf,
- size_t count, loff_t *f_pos);
-static int pm_qos_power_open(struct inode *inode, struct file *filp);
-static int pm_qos_power_release(struct inode *inode, struct file *filp);
-
-static const struct file_operations pm_qos_power_fops = {
- .write = pm_qos_power_write,
- .read = pm_qos_power_read,
- .open = pm_qos_power_open,
- .release = pm_qos_power_release,
- .llseek = noop_llseek,
-};
-
-/* unlocked internal variant */
-static inline int pm_qos_get_value(struct pm_qos_object *o)
-{
- if (plist_head_empty(&o->requests))
- return o->default_value;
-
- switch (o->type) {
- case PM_QOS_MIN:
- return plist_first(&o->requests)->prio;
-
- case PM_QOS_MAX:
- return plist_last(&o->requests)->prio;
-
- default:
- /* runtime check for not using enum */
- BUG();
- }
-}
-
-static inline s32 pm_qos_read_value(struct pm_qos_object *o)
-{
- return o->target_value;
-}
-
-static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
-{
- o->target_value = value;
-}
-
-static void update_target(struct pm_qos_object *o, struct plist_node *node,
- int del, int value)
-{
- unsigned long flags;
- int prev_value, curr_value;
-
- spin_lock_irqsave(&pm_qos_lock, flags);
- prev_value = pm_qos_get_value(o);
- /* PM_QOS_DEFAULT_VALUE is a signal that the value is unchanged */
- if (value != PM_QOS_DEFAULT_VALUE) {
- /*
- * to change the list, we atomically remove, reinit
- * with new value and add, then see if the extremal
- * changed
- */
- plist_del(node, &o->requests);
- plist_node_init(node, value);
- plist_add(node, &o->requests);
- } else if (del) {
- plist_del(node, &o->requests);
- } else {
- plist_add(node, &o->requests);
- }
- curr_value = pm_qos_get_value(o);
- pm_qos_set_value(o, curr_value);
- spin_unlock_irqrestore(&pm_qos_lock, flags);
-
- if (prev_value != curr_value)
- blocking_notifier_call_chain(o->notifiers,
- (unsigned long)curr_value,
- NULL);
-}
-
-static int register_pm_qos_misc(struct pm_qos_object *qos)
-{
- qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR;
- qos->pm_qos_power_miscdev.name = qos->name;
- qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops;
-
- return misc_register(&qos->pm_qos_power_miscdev);
-}
-
-static int find_pm_qos_object_by_minor(int minor)
-{
- int pm_qos_class;
-
- for (pm_qos_class = 0;
- pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) {
- if (minor ==
- pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor)
- return pm_qos_class;
- }
- return -1;
-}
-
-/**
- * pm_qos_request - returns current system wide qos expectation
- * @pm_qos_class: identification of which qos value is requested
- *
- * This function returns the current target value.
- */
-int pm_qos_request(int pm_qos_class)
-{
- return pm_qos_read_value(pm_qos_array[pm_qos_class]);
-}
-EXPORT_SYMBOL_GPL(pm_qos_request);
-
-int pm_qos_request_active(struct pm_qos_request_list *req)
-{
- return req->pm_qos_class != 0;
-}
-EXPORT_SYMBOL_GPL(pm_qos_request_active);
-
-/**
- * pm_qos_add_request - inserts new qos request into the list
- * @dep: pointer to a preallocated handle
- * @pm_qos_class: identifies which list of qos request to use
- * @value: defines the qos request
- *
- * This function inserts a new entry in the pm_qos_class list of requested qos
- * performance characteristics. It recomputes the aggregate QoS expectations
- * for the pm_qos_class of parameters and initializes the pm_qos_request_list
- * handle. Caller needs to save this handle for later use in updates and
- * removal.
- */
-
-void pm_qos_add_request(struct pm_qos_request_list *dep,
- int pm_qos_class, s32 value)
-{
- struct pm_qos_object *o = pm_qos_array[pm_qos_class];
- int new_value;
-
- if (pm_qos_request_active(dep)) {
- WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n");
- return;
- }
- if (value == PM_QOS_DEFAULT_VALUE)
- new_value = o->default_value;
- else
- new_value = value;
- plist_node_init(&dep->list, new_value);
- dep->pm_qos_class = pm_qos_class;
- update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE);
-}
-EXPORT_SYMBOL_GPL(pm_qos_add_request);
-
-/**
- * pm_qos_update_request - modifies an existing qos request
- * @pm_qos_req : handle to list element holding a pm_qos request to use
- * @value: defines the qos request
- *
- * Updates an existing qos request for the pm_qos_class of parameters along
- * with updating the target pm_qos_class value.
- *
- * Attempts are made to make this code callable on hot code paths.
- */
-void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
- s32 new_value)
-{
- s32 temp;
- struct pm_qos_object *o;
-
- if (!pm_qos_req) /*guard against callers passing in null */
- return;
-
- if (!pm_qos_request_active(pm_qos_req)) {
- WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n");
- return;
- }
-
- o = pm_qos_array[pm_qos_req->pm_qos_class];
-
- if (new_value == PM_QOS_DEFAULT_VALUE)
- temp = o->default_value;
- else
- temp = new_value;
-
- if (temp != pm_qos_req->list.prio)
- update_target(o, &pm_qos_req->list, 0, temp);
-}
-EXPORT_SYMBOL_GPL(pm_qos_update_request);
-
-/**
- * pm_qos_remove_request - modifies an existing qos request
- * @pm_qos_req: handle to request list element
- *
- * Will remove pm qos request from the list of requests and
- * recompute the current target value for the pm_qos_class. Call this
- * on slow code paths.
- */
-void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
-{
- struct pm_qos_object *o;
-
- if (pm_qos_req == NULL)
- return;
- /* silent return to keep pcm code cleaner */
-
- if (!pm_qos_request_active(pm_qos_req)) {
- WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n");
- return;
- }
-
- o = pm_qos_array[pm_qos_req->pm_qos_class];
- update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE);
- memset(pm_qos_req, 0, sizeof(*pm_qos_req));
-}
-EXPORT_SYMBOL_GPL(pm_qos_remove_request);
-
-/**
- * pm_qos_add_notifier - sets notification entry for changes to target value
- * @pm_qos_class: identifies which qos target changes should be notified.
- * @notifier: notifier block managed by caller.
- *
- * will register the notifier into a notification chain that gets called
- * upon changes to the pm_qos_class target value.
- */
-int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
-{
- int retval;
-
- retval = blocking_notifier_chain_register(
- pm_qos_array[pm_qos_class]->notifiers, notifier);
-
- return retval;
-}
-EXPORT_SYMBOL_GPL(pm_qos_add_notifier);
-
-/**
- * pm_qos_remove_notifier - deletes notification entry from chain.
- * @pm_qos_class: identifies which qos target changes are notified.
- * @notifier: notifier block to be removed.
- *
- * will remove the notifier from the notification chain that gets called
- * upon changes to the pm_qos_class target value.
- */
-int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier)
-{
- int retval;
-
- retval = blocking_notifier_chain_unregister(
- pm_qos_array[pm_qos_class]->notifiers, notifier);
-
- return retval;
-}
-EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
-
-static int pm_qos_power_open(struct inode *inode, struct file *filp)
-{
- long pm_qos_class;
-
- pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
- if (pm_qos_class >= 0) {
- struct pm_qos_request_list *req = kzalloc(sizeof(*req), GFP_KERNEL);
- if (!req)
- return -ENOMEM;
-
- pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE);
- filp->private_data = req;
-
- if (filp->private_data)
- return 0;
- }
- return -EPERM;
-}
-
-static int pm_qos_power_release(struct inode *inode, struct file *filp)
-{
- struct pm_qos_request_list *req;
-
- req = filp->private_data;
- pm_qos_remove_request(req);
- kfree(req);
-
- return 0;
-}
-
-
-static ssize_t pm_qos_power_read(struct file *filp, char __user *buf,
- size_t count, loff_t *f_pos)
-{
- s32 value;
- unsigned long flags;
- struct pm_qos_object *o;
- struct pm_qos_request_list *pm_qos_req = filp->private_data;
-
- if (!pm_qos_req)
- return -EINVAL;
- if (!pm_qos_request_active(pm_qos_req))
- return -EINVAL;
-
- o = pm_qos_array[pm_qos_req->pm_qos_class];
- spin_lock_irqsave(&pm_qos_lock, flags);
- value = pm_qos_get_value(o);
- spin_unlock_irqrestore(&pm_qos_lock, flags);
-
- return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32));
-}
-
-static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *f_pos)
-{
- s32 value;
- struct pm_qos_request_list *pm_qos_req;
-
- if (count == sizeof(s32)) {
- if (copy_from_user(&value, buf, sizeof(s32)))
- return -EFAULT;
- } else if (count <= 11) { /* ASCII perhaps? */
- char ascii_value[11];
- unsigned long int ulval;
- int ret;
-
- if (copy_from_user(ascii_value, buf, count))
- return -EFAULT;
-
- if (count > 10) {
- if (ascii_value[10] == '\n')
- ascii_value[10] = '\0';
- else
- return -EINVAL;
- } else {
- ascii_value[count] = '\0';
- }
- ret = strict_strtoul(ascii_value, 16, &ulval);
- if (ret) {
- pr_debug("%s, 0x%lx, 0x%x\n", ascii_value, ulval, ret);
- return -EINVAL;
- }
- value = (s32)lower_32_bits(ulval);
- } else {
- return -EINVAL;
- }
-
- pm_qos_req = filp->private_data;
- pm_qos_update_request(pm_qos_req, value);
-
- return count;
-}
-
-
-static int __init pm_qos_power_init(void)
-{
- int ret = 0;
-
- ret = register_pm_qos_misc(&cpu_dma_pm_qos);
- if (ret < 0) {
- printk(KERN_ERR "pm_qos_param: cpu_dma_latency setup failed\n");
- return ret;
- }
- ret = register_pm_qos_misc(&network_lat_pm_qos);
- if (ret < 0) {
- printk(KERN_ERR "pm_qos_param: network_latency setup failed\n");
- return ret;
- }
- ret = register_pm_qos_misc(&network_throughput_pm_qos);
- if (ret < 0)
- printk(KERN_ERR
- "pm_qos_param: network_throughput setup failed\n");
-
- return ret;
-}
-
-late_initcall(pm_qos_power_init);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 866f269..bb771e9 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -19,7 +19,7 @@
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/bitmap.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/inetdevice.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d595265..f07705d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -17,7 +17,7 @@
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/crc32.h>
#include <linux/slab.h>
#include <net/mac80211.h>
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 58ffa7d..41393c4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -14,7 +14,7 @@
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <net/sch_generic.h>
#include <linux/slab.h>
#include <net/mac80211.h>
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 1c6be91..c74e228 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -23,7 +23,7 @@
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/time.h>
-#include <linux/pm_qos_params.h>
+#include <linux/pm_qos.h>
#include <linux/uio.h>
#include <linux/dma-mapping.h>
#include <sound/core.h>
--
1.7.2.5
^ permalink raw reply related
* [PATCH 02/13] PM: add a per-device wake-up latency constraints plist
From: jean.pihet @ 2011-07-28 8:30 UTC (permalink / raw)
To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
Linux PM mailing list
Cc: Jean Pihet
In-Reply-To: <1311841821-10252-1-git-send-email-j-pihet@ti.com>
From: Jean Pihet <j-pihet@ti.com>
Add the field latency_constraints in the struct dev_pm_info
and the initialization of the plist in device_pm_init.
This enables the implementation of per-device constraints in
PM QoS.
Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
drivers/base/power/main.c | 1 +
include/linux/pm.h | 2 ++
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 06f09bf..dad2eb9 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -97,6 +97,7 @@ void device_pm_add(struct device *dev)
dev_name(dev->parent));
list_add_tail(&dev->power.entry, &dpm_list);
mutex_unlock(&dpm_list_mtx);
+ plist_head_init(&dev->power.latency_constraints, &dev->power.lock);
}
/**
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 411e4f4..23c85f1 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -22,6 +22,7 @@
#define _LINUX_PM_H
#include <linux/list.h>
+#include <linux/plist.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
@@ -463,6 +464,7 @@ struct dev_pm_info {
unsigned long accounting_timestamp;
void *subsys_data; /* Owned by the subsystem. */
#endif
+ struct plist_head latency_constraints;
};
extern void update_pm_runtime_accounting(struct device *dev);
--
1.7.2.5
^ permalink raw reply related
* [PATCH 03/13] PM: QoS: extend the in-kernel API with per-device latency constraints
From: jean.pihet @ 2011-07-28 8:30 UTC (permalink / raw)
To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
Linux PM mailing list
Cc: Jean Pihet
In-Reply-To: <1311841821-10252-1-git-send-email-j-pihet@ti.com>
From: Jean Pihet <j-pihet@ti.com>
Extend the PM QoS kernel API:
- add a new PM QoS class PM_QOS_DEV_LATENCY for device wake-up latency
constraints
- make the pm_qos_add_request API more generic by using a parameter of
type struct pm_qos_parameters
- minor clean-ups and rename of struct fields:
. rename pm_qos_class to class and pm_qos_req to req in internal code
. consistenly use req and params as the API parameters
. rename struct pm_qos_request_list to struct pm_qos_request
- update the in-kernel API callers to the new API
Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
arch/arm/plat-omap/i2c.c | 20 -----
drivers/i2c/busses/i2c-omap.c | 35 ++++++---
drivers/media/video/via-camera.c | 7 +-
drivers/net/e1000e/netdev.c | 9 ++-
drivers/net/wireless/ipw2x00/ipw2100.c | 8 +-
include/linux/netdevice.h | 2 +-
include/linux/pm_qos.h | 39 ++++++----
include/sound/pcm.h | 2 +-
kernel/pm_qos.c | 130 +++++++++++++++++--------------
sound/core/pcm_native.c | 8 ++-
10 files changed, 141 insertions(+), 119 deletions(-)
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 2388b8e..98f7ea5 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -34,7 +34,6 @@
#include <mach/irqs.h>
#include <plat/mux.h>
#include <plat/i2c.h>
-#include <plat/omap-pm.h>
#include <plat/omap_device.h>
#define OMAP_I2C_SIZE 0x3f
@@ -129,16 +128,6 @@ static inline int omap1_i2c_add_bus(int bus_id)
#ifdef CONFIG_ARCH_OMAP2PLUS
-/*
- * XXX This function is a temporary compatibility wrapper - only
- * needed until the I2C driver can be converted to call
- * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
- */
-static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
-{
- omap_pm_set_max_mpu_wakeup_lat(dev, t);
-}
-
static struct omap_device_pm_latency omap_i2c_latency[] = {
[0] = {
.deactivate_func = omap_device_idle_hwmods,
@@ -178,15 +167,6 @@ static inline int omap2_i2c_add_bus(int bus_id)
dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
pdata->flags = dev_attr->flags;
- /*
- * When waiting for completion of a i2c transfer, we need to
- * set a wake up latency constraint for the MPU. This is to
- * ensure quick enough wakeup from idle, when transfer
- * completes.
- * Only omap3 has support for constraints
- */
- if (cpu_is_omap34xx())
- pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
od = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d53cd61..b7d3f0d 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -40,6 +40,7 @@
#include <linux/slab.h>
#include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
/* I2C controller revisions */
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -180,8 +181,7 @@ struct omap_i2c_dev {
struct completion cmd_complete;
struct resource *ioarea;
u32 latency; /* maximum mpu wkup latency */
- void (*set_mpu_wkup_lat)(struct device *dev,
- long latency);
+ struct pm_qos_request pm_qos_request;
u32 speed; /* Speed of bus in Khz */
u16 cmd_err;
u8 *buf;
@@ -648,6 +648,7 @@ static int
omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
+ struct pm_qos_parameters pm_qos_params;
int i;
int r;
@@ -657,8 +658,19 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
if (r < 0)
goto out;
- if (dev->set_mpu_wkup_lat != NULL)
- dev->set_mpu_wkup_lat(dev->dev, dev->latency);
+ /*
+ * When waiting for completion of a i2c transfer, we need to
+ * set a wake up latency constraint for the MPU. This is to
+ * ensure quick enough wakeup from idle, when transfer
+ * completes.
+ * Used on OMAP3 Only
+ */
+ if (cpu_is_omap34xx()) {
+ pm_qos_params.dev = dev->dev;
+ pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+ pm_qos_params.value = dev->latency;
+ pm_qos_add_request(&dev->pm_qos_request, &pm_qos_params);
+ }
for (i = 0; i < num; i++) {
r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
@@ -666,8 +678,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
break;
}
- if (dev->set_mpu_wkup_lat != NULL)
- dev->set_mpu_wkup_lat(dev->dev, -1);
+ if (cpu_is_omap34xx())
+ pm_qos_remove_request(&dev->pm_qos_request);
if (r == 0)
r = num;
@@ -1021,13 +1033,10 @@ omap_i2c_probe(struct platform_device *pdev)
goto err_release_region;
}
- if (pdata != NULL) {
+ if (pdata != NULL)
speed = pdata->clkrate;
- dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
- } else {
+ else
speed = 100; /* Default speed */
- dev->set_mpu_wkup_lat = NULL;
- }
dev->speed = speed;
dev->idle = 1;
@@ -1075,8 +1084,8 @@ omap_i2c_probe(struct platform_device *pdev)
dev->fifo_size = (dev->fifo_size / 2);
dev->b_hw = 1; /* Enable hardware fixes */
}
- /* calculate wakeup latency constraint for MPU */
- if (dev->set_mpu_wkup_lat != NULL)
+ /* calculate wakeup latency constraint */
+ if (cpu_is_omap34xx())
dev->latency = (1000000 * dev->fifo_size) /
(1000 * speed / 8);
}
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index b3ca389..037c02c 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -69,7 +69,7 @@ struct via_camera {
struct mutex lock;
enum viacam_opstate opstate;
unsigned long flags;
- struct pm_qos_request_list qos_request;
+ struct pm_qos_request qos_request;
/*
* GPIO info for power/reset management
*/
@@ -1086,6 +1086,7 @@ static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
{
struct via_camera *cam = priv;
int ret = 0;
+ struct pm_qos_parameters pm_qos_params;
if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -1120,7 +1121,9 @@ static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
* requirement which will keep the CPU out of the deeper sleep
* states.
*/
- pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50);
+ pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+ pm_qos_params.value = 50;
+ pm_qos_add_request(&cam->qos_request, &pm_qos_params);
/*
* Fire things up.
*/
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index a8a18e1..33f55f3 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3604,6 +3604,7 @@ static int e1000_open(struct net_device *netdev)
struct e1000_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
int err;
+ struct pm_qos_parameters pm_qos_params;
/* disallow open during test */
if (test_bit(__E1000_TESTING, &adapter->state))
@@ -3641,10 +3642,12 @@ static int e1000_open(struct net_device *netdev)
/* DMA latency requirement to workaround early-receive/jumbo issue */
if ((adapter->flags & FLAG_HAS_ERT) ||
- (adapter->hw.mac.type == e1000_pch2lan))
+ (adapter->hw.mac.type == e1000_pch2lan)) {
+ pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+ pm_qos_params.value = PM_QOS_DEFAULT_VALUE;
pm_qos_add_request(&adapter->netdev->pm_qos_req,
- PM_QOS_CPU_DMA_LATENCY,
- PM_QOS_DEFAULT_VALUE);
+ &pm_qos_params);
+ }
/*
* before we allocate an interrupt, we must be ready to handle it.
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index d9df575..6a41efc 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -174,7 +174,7 @@ that only one external action is invoked at a time.
#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
-static struct pm_qos_request_list ipw2100_pm_qos_req;
+static struct pm_qos_request ipw2100_pm_qos_req;
/* Debugging stuff */
#ifdef CONFIG_IPW2100_DEBUG
@@ -6643,12 +6643,14 @@ static struct pci_driver ipw2100_pci_driver = {
static int __init ipw2100_init(void)
{
int ret;
+ struct pm_qos_parameters pm_qos_params;
printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
- pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
- PM_QOS_DEFAULT_VALUE);
+ pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+ pm_qos_params.value = PM_QOS_DEFAULT_VALUE;
+ pm_qos_add_request(&ipw2100_pm_qos_req, &pm_qos_params);
ret = pci_register_driver(&ipw2100_pci_driver);
if (ret)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index cc1eb9e..82f01d9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -999,7 +999,7 @@ struct net_device {
*/
char name[IFNAMSIZ];
- struct pm_qos_request_list pm_qos_req;
+ struct pm_qos_request pm_qos_req;
/* device name hash chain */
struct hlist_node name_hlist;
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 9cc0224..a2e4409 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -8,31 +8,40 @@
#include <linux/notifier.h>
#include <linux/miscdevice.h>
-#define PM_QOS_RESERVED 0
-#define PM_QOS_CPU_DMA_LATENCY 1
-#define PM_QOS_NETWORK_LATENCY 2
-#define PM_QOS_NETWORK_THROUGHPUT 3
+#define PM_QOS_RESERVED 0
+#define PM_QOS_CPU_DMA_LATENCY 1
+#define PM_QOS_DEV_LATENCY 2
+#define PM_QOS_NETWORK_LATENCY 3
+#define PM_QOS_NETWORK_THROUGHPUT 4
-#define PM_QOS_NUM_CLASSES 4
+#define PM_QOS_NUM_CLASSES 5
#define PM_QOS_DEFAULT_VALUE -1
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
+#define PM_QOS_DEV_LAT_DEFAULT_VALUE 0
#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
-struct pm_qos_request_list {
+struct pm_qos_request {
struct plist_node list;
- int pm_qos_class;
+ int class;
+ struct device *dev;
};
-void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
-void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
- s32 new_value);
-void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
+struct pm_qos_parameters {
+ int class;
+ struct device *dev;
+ s32 value;
+};
+
+void pm_qos_add_request(struct pm_qos_request *req,
+ struct pm_qos_parameters *params);
+void pm_qos_update_request(struct pm_qos_request *req, s32 new_value);
+void pm_qos_remove_request(struct pm_qos_request *req);
-int pm_qos_request(int pm_qos_class);
-int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
-int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
-int pm_qos_request_active(struct pm_qos_request_list *req);
+int pm_qos_request(int class);
+int pm_qos_add_notifier(int class, struct notifier_block *notifier);
+int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
+int pm_qos_request_active(struct pm_qos_request *req);
#endif
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 1204f17..d3b068f 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -373,7 +373,7 @@ struct snd_pcm_substream {
int number;
char name[32]; /* substream name */
int stream; /* stream (direction) */
- struct pm_qos_request_list latency_pm_qos_req; /* pm_qos request */
+ struct pm_qos_request latency_pm_qos_req; /* pm_qos request */
size_t buffer_bytes_max; /* limit ring buffer size */
struct snd_dma_buffer dma_buffer;
unsigned int dma_buf_id;
diff --git a/kernel/pm_qos.c b/kernel/pm_qos.c
index 3bf69f1..4ede3cd 100644
--- a/kernel/pm_qos.c
+++ b/kernel/pm_qos.c
@@ -82,6 +82,16 @@ static struct pm_qos_object cpu_dma_pm_qos = {
.type = PM_QOS_MIN,
};
+static BLOCKING_NOTIFIER_HEAD(dev_lat_notifier);
+static struct pm_qos_object dev_pm_qos = {
+ .requests = PLIST_HEAD_INIT(dev_pm_qos.requests, pm_qos_lock),
+ .notifiers = &dev_lat_notifier,
+ .name = "dev_latency",
+ .target_value = PM_QOS_DEV_LAT_DEFAULT_VALUE,
+ .default_value = PM_QOS_DEV_LAT_DEFAULT_VALUE,
+ .type = PM_QOS_MIN,
+};
+
static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
static struct pm_qos_object network_lat_pm_qos = {
.requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
@@ -107,6 +117,7 @@ static struct pm_qos_object network_throughput_pm_qos = {
static struct pm_qos_object *pm_qos_array[] = {
&null_pm_qos,
&cpu_dma_pm_qos,
+ &dev_pm_qos,
&network_lat_pm_qos,
&network_throughput_pm_qos
};
@@ -212,132 +223,132 @@ static int find_pm_qos_object_by_minor(int minor)
/**
* pm_qos_request - returns current system wide qos expectation
- * @pm_qos_class: identification of which qos value is requested
+ * @class: identification of which qos value is requested
*
* This function returns the current target value.
*/
-int pm_qos_request(int pm_qos_class)
+int pm_qos_request(int class)
{
- return pm_qos_read_value(pm_qos_array[pm_qos_class]);
+ return pm_qos_read_value(pm_qos_array[class]);
}
EXPORT_SYMBOL_GPL(pm_qos_request);
-int pm_qos_request_active(struct pm_qos_request_list *req)
+int pm_qos_request_active(struct pm_qos_request *req)
{
- return req->pm_qos_class != 0;
+ return req->class != 0;
}
EXPORT_SYMBOL_GPL(pm_qos_request_active);
/**
* pm_qos_add_request - inserts new qos request into the list
- * @dep: pointer to a preallocated handle
- * @pm_qos_class: identifies which list of qos request to use
- * @value: defines the qos request
+ * @req: pointer to a preallocated handle
+ * @params: request parameters
*
- * This function inserts a new entry in the pm_qos_class list of requested qos
+ * This function inserts a new entry in the class list of requested qos
* performance characteristics. It recomputes the aggregate QoS expectations
- * for the pm_qos_class of parameters and initializes the pm_qos_request_list
+ * for the class of parameters and initializes the pm_qos_request
* handle. Caller needs to save this handle for later use in updates and
* removal.
*/
-void pm_qos_add_request(struct pm_qos_request_list *dep,
- int pm_qos_class, s32 value)
+void pm_qos_add_request(struct pm_qos_request *req,
+ struct pm_qos_parameters *params)
{
- struct pm_qos_object *o = pm_qos_array[pm_qos_class];
+ struct pm_qos_object *o = pm_qos_array[params->class];
int new_value;
- if (pm_qos_request_active(dep)) {
- WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n");
+ if (pm_qos_request_active(req)) {
+ WARN(1, KERN_ERR "pm_qos_add_request() called for already "
+ "added request\n");
return;
}
- if (value == PM_QOS_DEFAULT_VALUE)
+ if (params->value == PM_QOS_DEFAULT_VALUE)
new_value = o->default_value;
else
- new_value = value;
- plist_node_init(&dep->list, new_value);
- dep->pm_qos_class = pm_qos_class;
- update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE);
+ new_value = params->value;
+ plist_node_init(&req->list, new_value);
+ req->class = params->class;
+ req->dev = params->dev;
+ update_target(o, &req->list, 0, PM_QOS_DEFAULT_VALUE);
}
EXPORT_SYMBOL_GPL(pm_qos_add_request);
/**
* pm_qos_update_request - modifies an existing qos request
- * @pm_qos_req : handle to list element holding a pm_qos request to use
+ * @req : handle to list element holding a pm_qos request to use
* @value: defines the qos request
*
- * Updates an existing qos request for the pm_qos_class of parameters along
- * with updating the target pm_qos_class value.
+ * Updates an existing qos request for the class of parameters along
+ * with updating the target class value.
*
* Attempts are made to make this code callable on hot code paths.
*/
-void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
- s32 new_value)
+void pm_qos_update_request(struct pm_qos_request *req, s32 new_value)
{
s32 temp;
struct pm_qos_object *o;
- if (!pm_qos_req) /*guard against callers passing in null */
+ if (!req) /*guard against callers passing in null */
return;
- if (!pm_qos_request_active(pm_qos_req)) {
+ if (!pm_qos_request_active(req)) {
WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n");
return;
}
- o = pm_qos_array[pm_qos_req->pm_qos_class];
+ o = pm_qos_array[req->class];
if (new_value == PM_QOS_DEFAULT_VALUE)
temp = o->default_value;
else
temp = new_value;
- if (temp != pm_qos_req->list.prio)
- update_target(o, &pm_qos_req->list, 0, temp);
+ if (temp != req->list.prio)
+ update_target(o, &req->list, 0, temp);
}
EXPORT_SYMBOL_GPL(pm_qos_update_request);
/**
* pm_qos_remove_request - modifies an existing qos request
- * @pm_qos_req: handle to request list element
+ * @req: handle to request list element
*
* Will remove pm qos request from the list of requests and
- * recompute the current target value for the pm_qos_class. Call this
+ * recompute the current target value for the class. Call this
* on slow code paths.
*/
-void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
+void pm_qos_remove_request(struct pm_qos_request *req)
{
struct pm_qos_object *o;
- if (pm_qos_req == NULL)
+ if (req == NULL)
return;
/* silent return to keep pcm code cleaner */
- if (!pm_qos_request_active(pm_qos_req)) {
+ if (!pm_qos_request_active(req)) {
WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n");
return;
}
- o = pm_qos_array[pm_qos_req->pm_qos_class];
- update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE);
- memset(pm_qos_req, 0, sizeof(*pm_qos_req));
+ o = pm_qos_array[req->class];
+ update_target(o, &req->list, 1, PM_QOS_DEFAULT_VALUE);
+ memset(req, 0, sizeof(*req));
}
EXPORT_SYMBOL_GPL(pm_qos_remove_request);
/**
* pm_qos_add_notifier - sets notification entry for changes to target value
- * @pm_qos_class: identifies which qos target changes should be notified.
+ * @class: identifies which qos target changes should be notified.
* @notifier: notifier block managed by caller.
*
* will register the notifier into a notification chain that gets called
- * upon changes to the pm_qos_class target value.
+ * upon changes to the class target value.
*/
-int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
+int pm_qos_add_notifier(int class, struct notifier_block *notifier)
{
int retval;
retval = blocking_notifier_chain_register(
- pm_qos_array[pm_qos_class]->notifiers, notifier);
+ pm_qos_array[class]->notifiers, notifier);
return retval;
}
@@ -345,18 +356,18 @@ EXPORT_SYMBOL_GPL(pm_qos_add_notifier);
/**
* pm_qos_remove_notifier - deletes notification entry from chain.
- * @pm_qos_class: identifies which qos target changes are notified.
+ * @class: identifies which qos target changes are notified.
* @notifier: notifier block to be removed.
*
* will remove the notifier from the notification chain that gets called
- * upon changes to the pm_qos_class target value.
+ * upon changes to the class target value.
*/
-int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier)
+int pm_qos_remove_notifier(int class, struct notifier_block *notifier)
{
int retval;
retval = blocking_notifier_chain_unregister(
- pm_qos_array[pm_qos_class]->notifiers, notifier);
+ pm_qos_array[class]->notifiers, notifier);
return retval;
}
@@ -364,15 +375,16 @@ EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
static int pm_qos_power_open(struct inode *inode, struct file *filp)
{
- long pm_qos_class;
+ struct pm_qos_parameters pm_qos_params;
- pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
- if (pm_qos_class >= 0) {
- struct pm_qos_request_list *req = kzalloc(sizeof(*req), GFP_KERNEL);
+ pm_qos_params.class = find_pm_qos_object_by_minor(iminor(inode));
+ if (pm_qos_params.class >= 0) {
+ struct pm_qos_request *req = kzalloc(sizeof(*req), GFP_KERNEL);
if (!req)
return -ENOMEM;
- pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE);
+ pm_qos_params.value = PM_QOS_DEFAULT_VALUE;
+ pm_qos_add_request(req, &pm_qos_params);
filp->private_data = req;
if (filp->private_data)
@@ -383,7 +395,7 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp)
static int pm_qos_power_release(struct inode *inode, struct file *filp)
{
- struct pm_qos_request_list *req;
+ struct pm_qos_request *req;
req = filp->private_data;
pm_qos_remove_request(req);
@@ -399,14 +411,14 @@ static ssize_t pm_qos_power_read(struct file *filp, char __user *buf,
s32 value;
unsigned long flags;
struct pm_qos_object *o;
- struct pm_qos_request_list *pm_qos_req = filp->private_data;
+ struct pm_qos_request *req = filp->private_data;
- if (!pm_qos_req)
+ if (!req)
return -EINVAL;
- if (!pm_qos_request_active(pm_qos_req))
+ if (!pm_qos_request_active(req))
return -EINVAL;
- o = pm_qos_array[pm_qos_req->pm_qos_class];
+ o = pm_qos_array[req->class];
spin_lock_irqsave(&pm_qos_lock, flags);
value = pm_qos_get_value(o);
spin_unlock_irqrestore(&pm_qos_lock, flags);
@@ -418,7 +430,7 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
size_t count, loff_t *f_pos)
{
s32 value;
- struct pm_qos_request_list *pm_qos_req;
+ struct pm_qos_request *req;
if (count == sizeof(s32)) {
if (copy_from_user(&value, buf, sizeof(s32)))
@@ -449,8 +461,8 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
return -EINVAL;
}
- pm_qos_req = filp->private_data;
- pm_qos_update_request(pm_qos_req, value);
+ req = filp->private_data;
+ pm_qos_update_request(req, value);
return count;
}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index c74e228..fb05f37 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -375,6 +375,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
int err, usecs;
unsigned int bits;
snd_pcm_uframes_t frames;
+ struct pm_qos_parameters pm_qos_params;
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
@@ -455,9 +456,12 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
if (pm_qos_request_active(&substream->latency_pm_qos_req))
pm_qos_remove_request(&substream->latency_pm_qos_req);
- if ((usecs = period_to_usecs(runtime)) >= 0)
+ if ((usecs = period_to_usecs(runtime)) >= 0) {
+ pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+ pm_qos_params.value = usecs;
pm_qos_add_request(&substream->latency_pm_qos_req,
- PM_QOS_CPU_DMA_LATENCY, usecs);
+ &pm_qos_params);
+ }
return 0;
_error:
/* hardware might be unusable from this time,
--
1.7.2.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox