public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* 2.6.25-rc9 -- INFO: possible circular locking dependency detected
@ 2008-04-14  3:04 Miles Lane
  2008-04-14  3:29 ` Miles Lane
  2008-04-14  6:54 ` Peter Zijlstra
  0 siblings, 2 replies; 23+ messages in thread
From: Miles Lane @ 2008-04-14  3:04 UTC (permalink / raw)
  To: LKML

[ 3217.586003] [ INFO: possible circular locking dependency detected ]
[ 3217.586006] 2.6.25-rc9 #1
[ 3217.586008] -------------------------------------------------------
[ 3217.586011] pm-suspend/7421 is trying to acquire lock:
[ 3217.586013]  (&per_cpu(cpu_policy_rwsem, cpu)){----}, at:
[<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
[ 3217.586023]
[ 3217.586024] but task is already holding lock:
[ 3217.586026]  (&cpu_hotplug.lock){--..}, at: [<c0142cec>]
cpu_hotplug_begin+0x2f/0x89
[ 3217.586033]
[ 3217.586033] which lock already depends on the new lock.
[ 3217.586035]
[ 3217.586036]
[ 3217.586037] the existing dependency chain (in reverse order) is:
[ 3217.586039]
[ 3217.586040] -> #3 (&cpu_hotplug.lock){--..}:
[ 3217.586044]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
[ 3217.586052]        [<c013f5c2>] lock_acquire+0x76/0x9d
[ 3217.586058]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
[ 3217.586066]        [<c0143038>] get_online_cpus+0x2c/0x3e
[ 3217.586072]        [<c011eb03>] sched_getaffinity+0xe/0x4d
[ 3217.586079]        [<c0159784>] __synchronize_sched+0x11/0x5f
[ 3217.586087]        [<c0137380>] synchronize_srcu+0x22/0x5b
[ 3217.586093]        [<c01376a3>] srcu_notifier_chain_unregister+0x45/0x4c
[ 3217.586100]        [<c0277204>] cpufreq_unregister_notifier+0x1f/0x2f
[ 3217.586107]        [<f8cfd68c>] cpufreq_governor_dbs+0x1e9/0x242
[cpufreq_conservative]
[ 3217.586117]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
[ 3217.586124]        [<c0277703>] __cpufreq_set_policy+0x13f/0x1c3
[ 3217.586130]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
[ 3217.586137]        [<c0278708>] store+0x42/0x5b
[ 3217.586143]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
[ 3217.586151]        [<c017dbc7>] vfs_write+0x8c/0x108
[ 3217.586158]        [<c017e122>] sys_write+0x3b/0x60
[ 3217.586165]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
[ 3217.586172]        [<ffffffff>] 0xffffffff
[ 3217.586184]
[ 3217.586185] -> #2 (&sp->mutex){--..}:
[ 3217.586188]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
[ 3217.586195]        [<c013f5c2>] lock_acquire+0x76/0x9d
[ 3217.586201]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
[ 3217.586208]        [<c0137374>] synchronize_srcu+0x16/0x5b
[ 3217.586214]        [<c01376a3>] srcu_notifier_chain_unregister+0x45/0x4c
[ 3217.586220]        [<c0277204>] cpufreq_unregister_notifier+0x1f/0x2f
[ 3217.586227]        [<f8cfd68c>] cpufreq_governor_dbs+0x1e9/0x242
[cpufreq_conservative]
[ 3217.586235]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
[ 3217.586242]        [<c0277703>] __cpufreq_set_policy+0x13f/0x1c3
[ 3217.586248]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
[ 3217.586255]        [<c0278708>] store+0x42/0x5b
[ 3217.586261]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
[ 3217.586268]        [<c017dbc7>] vfs_write+0x8c/0x108
[ 3217.586274]        [<c017e122>] sys_write+0x3b/0x60
[ 3217.586280]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
[ 3217.586287]        [<ffffffff>] 0xffffffff
[ 3217.586297]
[ 3217.586298] -> #1 (dbs_mutex#2){--..}:
[ 3217.586302]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
[ 3217.586309]        [<c013f5c2>] lock_acquire+0x76/0x9d
[ 3217.586315]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
[ 3217.586322]        [<f8cfd511>] cpufreq_governor_dbs+0x6e/0x242
[cpufreq_conservative]
[ 3217.586330]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
[ 3217.586336]        [<c0277719>] __cpufreq_set_policy+0x155/0x1c3
[ 3217.586343]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
[ 3217.586349]        [<c0278708>] store+0x42/0x5b
[ 3217.586355]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
[ 3217.586362]        [<c017dbc7>] vfs_write+0x8c/0x108
[ 3217.586369]        [<c017e122>] sys_write+0x3b/0x60
[ 3217.586375]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
[ 3217.586381]        [<ffffffff>] 0xffffffff
[ 3217.586451]
[ 3217.586452] -> #0 (&per_cpu(cpu_policy_rwsem, cpu)){----}:
[ 3217.586456]        [<c013f2c6>] __lock_acquire+0x929/0xbaf
[ 3217.586463]        [<c013f5c2>] lock_acquire+0x76/0x9d
[ 3217.586469]        [<c030a219>] down_write+0x28/0x44
[ 3217.586475]        [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
[ 3217.586482]        [<c0308abd>] cpufreq_cpu_callback+0x43/0x66
[ 3217.586489]        [<c013753e>] notifier_call_chain+0x2b/0x4a
[ 3217.586495]        [<c013757f>] __raw_notifier_call_chain+0xe/0x10
[ 3217.586501]        [<c0142dde>] _cpu_down+0x71/0x1f8
[ 3217.586507]        [<c0143094>] disable_nonboot_cpus+0x4a/0xc6
[ 3217.586513]        [<c0146ce5>] suspend_devices_and_enter+0x6c/0x101
[ 3217.586521]        [<c0146e8b>] enter_state+0xc4/0x119
[ 3217.586527]        [<c0146f76>] state_store+0x96/0xac
[ 3217.586533]        [<c01e7479>] kobj_attr_store+0x1a/0x22
[ 3217.586541]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
[ 3217.586547]        [<c017dbc7>] vfs_write+0x8c/0x108
[ 3217.586554]        [<c017e122>] sys_write+0x3b/0x60
[ 3217.586560]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
[ 3217.586567]        [<ffffffff>] 0xffffffff
[ 3217.586578]
[ 3217.586578] other info that might help us debug this:
[ 3217.586580]
[ 3217.586582] 5 locks held by pm-suspend/7421:
[ 3217.586584]  #0:  (&buffer->mutex){--..}, at: [<c01b1a36>]
sysfs_write_file+0x25/0xe3
[ 3217.586590]  #1:  (pm_mutex){--..}, at: [<c0146eca>] enter_state+0x103/0x119
[ 3217.586596]  #2:  (pm_sleep_rwsem){--..}, at: [<c0261789>]
device_suspend+0x25/0x1ad
[ 3217.586604]  #3:  (cpu_add_remove_lock){--..}, at: [<c0142c93>]
cpu_maps_update_begin+0xf/0x11
[ 3217.586610]  #4:  (&cpu_hotplug.lock){--..}, at: [<c0142cec>]
cpu_hotplug_begin+0x2f/0x89
[ 3217.586616]
[ 3217.586617] stack backtrace:
[ 3217.586620] Pid: 7421, comm: pm-suspend Not tainted 2.6.25-rc9 #1
[ 3217.586627]  [<c013d914>] print_circular_bug_tail+0x5b/0x66
[ 3217.586634]  [<c013d25e>] ? print_circular_bug_entry+0x39/0x43
[ 3217.586643]  [<c013f2c6>] __lock_acquire+0x929/0xbaf
[ 3217.586656]  [<c013f5c2>] lock_acquire+0x76/0x9d
[ 3217.586661]  [<c0277fe1>] ? lock_policy_rwsem_write+0x33/0x5a
[ 3217.586668]  [<c030a219>] down_write+0x28/0x44
[ 3217.586673]  [<c0277fe1>] ? lock_policy_rwsem_write+0x33/0x5a
[ 3217.586678]  [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
[ 3217.586684]  [<c0308abd>] cpufreq_cpu_callback+0x43/0x66
[ 3217.586689]  [<c013753e>] notifier_call_chain+0x2b/0x4a
[ 3217.586696]  [<c013757f>] __raw_notifier_call_chain+0xe/0x10
[ 3217.586701]  [<c0142dde>] _cpu_down+0x71/0x1f8
[ 3217.586710]  [<c0143094>] disable_nonboot_cpus+0x4a/0xc6
[ 3217.586716]  [<c0146ce5>] suspend_devices_and_enter+0x6c/0x101
[ 3217.586721]  [<c0146e8b>] enter_state+0xc4/0x119
[ 3217.586726]  [<c0146f76>] state_store+0x96/0xac
[ 3217.586731]  [<c0146ee0>] ? state_store+0x0/0xac
[ 3217.586736]  [<c01e7479>] kobj_attr_store+0x1a/0x22
[ 3217.586742]  [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
[ 3217.586750]  [<c01b1a11>] ? sysfs_write_file+0x0/0xe3
[ 3217.586755]  [<c017dbc7>] vfs_write+0x8c/0x108
[ 3217.586762]  [<c017e122>] sys_write+0x3b/0x60
[ 3217.586769]  [<c0104470>] sysenter_past_esp+0x6d/0xc5
[ 3217.586780]  =======================
[ 3217.588064] Breaking affinity for irq 16

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14  3:04 2.6.25-rc9 -- INFO: possible circular locking dependency detected Miles Lane
@ 2008-04-14  3:29 ` Miles Lane
  2008-04-14  6:54 ` Peter Zijlstra
  1 sibling, 0 replies; 23+ messages in thread
From: Miles Lane @ 2008-04-14  3:29 UTC (permalink / raw)
  To: LKML

Ah.  You may need my .config file.  Here it is.

#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.25-rc9
# Sun Apr 13 17:23:26 2008
#
# CONFIG_64BIT is not set
CONFIG_X86_32=y
# CONFIG_X86_64 is not set
CONFIG_X86=y
# CONFIG_GENERIC_LOCKBREAK is not set
CONFIG_GENERIC_TIME=y
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_SEMAPHORE_SLEEPERS=y
CONFIG_FAST_CMPXCHG_LOCAL=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_HWEIGHT=y
# CONFIG_GENERIC_GPIO is not set
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMI=y
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
# CONFIG_GENERIC_TIME_VSYSCALL is not set
CONFIG_ARCH_HAS_CPU_RELAX=y
# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ZONE_DMA32 is not set
CONFIG_ARCH_POPULATES_NODE_MAP=y
# CONFIG_AUDIT_ARCH is not set
CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_X86_SMP=y
CONFIG_X86_32_SMP=y
CONFIG_X86_HT=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_TRAMPOLINE=y
CONFIG_KTIME_SCALAR=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_TASKSTATS is not set
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_AUDIT_TREE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_NS=y
CONFIG_CPUSETS=y
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
# CONFIG_USER_SCHED is not set
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_CGROUP_MEM_RES_CTLR=y
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_PROC_PID_CPUSET is not set
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
# CONFIG_COMPAT_BRK is not set
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
CONFIG_BLK_DEV_BSG=y

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_PREEMPT_NOTIFIERS=y
# CONFIG_CLASSIC_RCU is not set

#
# Processor type and features
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_SMP=y
CONFIG_X86_PC=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_ES7000 is not set
# CONFIG_X86_RDC321X is not set
# CONFIG_X86_VSMP is not set
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_PARAVIRT_GUEST=y
# CONFIG_XEN is not set
CONFIG_VMI=y
CONFIG_LGUEST_GUEST=y
CONFIG_PARAVIRT=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MPSC is not set
CONFIG_MCORE2=y
# CONFIG_GENERIC_CPU is not set
# CONFIG_X86_GENERIC is not set
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_XADD=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_P6_NOP=y
CONFIG_X86_TSC=y
CONFIG_X86_MINIMUM_CPU_FAMILY=6
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
# CONFIG_IOMMU_HELPER is not set
CONFIG_NR_CPUS=5
CONFIG_SCHED_SMT=y
CONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_RCU=y
CONFIG_RCU_TRACE=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_MCE=y
CONFIG_X86_MCE_NONFATAL=m
CONFIG_X86_MCE_P4THERMAL=y
CONFIG_VM86=y
# CONFIG_TOSHIBA is not set
# CONFIG_I8K is not set
# CONFIG_X86_REBOOTFIXUPS is not set
CONFIG_MICROCODE=m
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
# CONFIG_NOHIGHMEM is not set
CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_HIGHMEM=y
CONFIG_NEED_NODE_MEMMAP_SIZE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_STATIC=y
# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set

#
# Memory hotplug is currently incompatible with Software Suspend
#
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HIGHPTE=y
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
CONFIG_EFI=y
CONFIG_IRQBALANCE=y
CONFIG_SECCOMP=y
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
CONFIG_HZ_300=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=300
CONFIG_SCHED_HRTICK=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x100000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x100000
CONFIG_HOTPLUG_CPU=y
CONFIG_COMPAT_VDSO=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y

#
# Power management options
#
CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP_SMP=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""
CONFIG_ACPI=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_PROCFS_POWER=y
CONFIG_ACPI_SYSFS_POWER=y
CONFIG_ACPI_PROC_EVENT=y
CONFIG_ACPI_AC=m
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_DOCK=y
# CONFIG_ACPI_BAY is not set
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=m
CONFIG_ACPI_WMI=m
# CONFIG_ACPI_ASUS is not set
# CONFIG_ACPI_TOSHIBA is not set
# CONFIG_ACPI_CUSTOM_DSDT is not set
CONFIG_ACPI_BLACKLIST_YEAR=2001
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_DEBUG_FUNC_TRACE=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
CONFIG_X86_PM_TIMER=y
CONFIG_ACPI_CONTAINER=y
# CONFIG_ACPI_SBS is not set
CONFIG_X86_APM_BOOT=y
CONFIG_APM=m
# CONFIG_APM_IGNORE_USER_SUSPEND is not set
# CONFIG_APM_DO_ENABLE is not set
# CONFIG_APM_CPU_IDLE is not set
# CONFIG_APM_DISPLAY_BLANK is not set
# CONFIG_APM_ALLOW_INTS is not set
# CONFIG_APM_REAL_MODE_POWER_OFF is not set

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_DEBUG=y
CONFIG_CPU_FREQ_STAT=m
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m

#
# CPUFreq processor drivers
#
CONFIG_X86_ACPI_CPUFREQ=m
# CONFIG_X86_POWERNOW_K6 is not set
# CONFIG_X86_POWERNOW_K7 is not set
# CONFIG_X86_POWERNOW_K8 is not set
# CONFIG_X86_GX_SUSPMOD is not set
# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
# CONFIG_X86_SPEEDSTEP_ICH is not set
# CONFIG_X86_SPEEDSTEP_SMI is not set
# CONFIG_X86_P4_CLOCKMOD is not set
# CONFIG_X86_CPUFREQ_NFORCE2 is not set
# CONFIG_X86_LONGRUN is not set
# CONFIG_X86_LONGHAUL is not set
# CONFIG_X86_E_POWERSAVER is not set

#
# shared options
#
CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y
# CONFIG_X86_SPEEDSTEP_LIB is not set
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y

#
# Bus options (PCI etc.)
#
CONFIG_PCI=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCIEPORTBUS=y
CONFIG_HOTPLUG_PCI_PCIE=m
CONFIG_PCIEAER=y
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
CONFIG_HT_IRQ=y
CONFIG_ISA_DMA_API=y
CONFIG_ISA=y
CONFIG_EISA=y
# CONFIG_EISA_VLB_PRIMING is not set
CONFIG_EISA_PCI_EISA=y
CONFIG_EISA_VIRTUAL_ROOT=y
CONFIG_EISA_NAMES=y
# CONFIG_MCA is not set
# CONFIG_SCx200 is not set
CONFIG_PCCARD=m
CONFIG_PCMCIA_DEBUG=y
CONFIG_PCMCIA=m
CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y

#
# PC-card bridges
#
CONFIG_YENTA=m
CONFIG_YENTA_O2=y
CONFIG_YENTA_RICOH=y
CONFIG_YENTA_TI=y
CONFIG_YENTA_ENE_TUNE=y
CONFIG_YENTA_TOSHIBA=y
CONFIG_PD6729=m
CONFIG_I82092=m
CONFIG_I82365=m
CONFIG_TCIC=m
CONFIG_PCMCIA_PROBE=y
CONFIG_PCCARD_NONSTATIC=m
CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI_FAKE=m
CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_HOTPLUG_PCI_ACPI_IBM=m
CONFIG_HOTPLUG_PCI_CPCI=y
CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m
CONFIG_HOTPLUG_PCI_SHPC=m

#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_AOUT=m
CONFIG_BINFMT_MISC=m

#
# Networking
#
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_XFRM_STATISTICS is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_RARP is not set
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE=m
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
CONFIG_INET_LRO=m
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
# CONFIG_IPV6_OPTIMISTIC_DAD is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
# CONFIG_INET6_XFRM_MODE_BEET is not set
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=y
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
CONFIG_NETWORK_SECMARK=y
# CONFIG_NETFILTER is not set
CONFIG_IP_DCCP=m
CONFIG_INET_DCCP_DIAG=m
CONFIG_IP_DCCP_ACKVEC=y

#
# DCCP CCIDs Configuration (EXPERIMENTAL)
#
CONFIG_IP_DCCP_CCID2=m
# CONFIG_IP_DCCP_CCID2_DEBUG is not set
CONFIG_IP_DCCP_CCID3=m
# CONFIG_IP_DCCP_CCID3_DEBUG is not set
CONFIG_IP_DCCP_CCID3_RTO=100
CONFIG_IP_DCCP_TFRC_LIB=m

#
# DCCP Kernel Hacking
#
# CONFIG_IP_DCCP_DEBUG is not set
CONFIG_IP_SCTP=m
# CONFIG_SCTP_DBG_MSG is not set
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
CONFIG_TIPC=m
# CONFIG_TIPC_ADVANCED is not set
# CONFIG_TIPC_DEBUG is not set
CONFIG_ATM=m
CONFIG_ATM_CLIP=m
# CONFIG_ATM_CLIP_NO_ICMP is not set
CONFIG_ATM_LANE=m
CONFIG_ATM_MPOA=m
CONFIG_ATM_BR2684=m
# CONFIG_ATM_BR2684_IPFILTER is not set
CONFIG_BRIDGE=m
CONFIG_VLAN_8021Q=m
CONFIG_DECNET=m
# CONFIG_DECNET_ROUTER is not set
CONFIG_LLC=y
CONFIG_LLC2=m
CONFIG_IPX=m
# CONFIG_IPX_INTERN is not set
CONFIG_ATALK=m
CONFIG_DEV_APPLETALK=m
# CONFIG_LTPC is not set
# CONFIG_COPS is not set
CONFIG_IPDDP=m
CONFIG_IPDDP_ENCAP=y
CONFIG_IPDDP_DECAP=y
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_SCHED is not set
CONFIG_NET_SCH_FIFO=y

#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
CONFIG_IRDA=m

#
# IrDA protocols
#
CONFIG_IRLAN=m
CONFIG_IRNET=m
CONFIG_IRCOMM=m
CONFIG_IRDA_ULTRA=y

#
# IrDA options
#
CONFIG_IRDA_CACHE_LAST_LSAP=y
CONFIG_IRDA_FAST_RR=y
CONFIG_IRDA_DEBUG=y

#
# Infrared-port device drivers
#

#
# SIR device drivers
#
CONFIG_IRTTY_SIR=m

#
# Dongle support
#
CONFIG_DONGLE=y
CONFIG_ESI_DONGLE=m
CONFIG_ACTISYS_DONGLE=m
CONFIG_TEKRAM_DONGLE=m
CONFIG_TOIM3232_DONGLE=m
CONFIG_LITELINK_DONGLE=m
CONFIG_MA600_DONGLE=m
CONFIG_GIRBIL_DONGLE=m
CONFIG_MCP2120_DONGLE=m
CONFIG_OLD_BELKIN_DONGLE=m
CONFIG_ACT200L_DONGLE=m
CONFIG_KINGSUN_DONGLE=m
CONFIG_KSDAZZLE_DONGLE=m
CONFIG_KS959_DONGLE=m

#
# FIR device drivers
#
CONFIG_USB_IRDA=m
CONFIG_SIGMATEL_FIR=m
CONFIG_NSC_FIR=m
CONFIG_WINBOND_FIR=m
CONFIG_TOSHIBA_FIR=m
CONFIG_SMC_IRCC_FIR=m
CONFIG_ALI_FIR=m
CONFIG_VLSI_FIR=m
CONFIG_VIA_FIR=m
CONFIG_MCS_FIR=m
CONFIG_BT=m
CONFIG_BT_L2CAP=m
CONFIG_BT_SCO=m
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=m

#
# Bluetooth device drivers
#
CONFIG_BT_HCIUSB=m
CONFIG_BT_HCIUSB_SCO=y
CONFIG_BT_HCIBTSDIO=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
CONFIG_BT_HCIDTL1=m
CONFIG_BT_HCIBT3C=m
CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIBTUART=m
CONFIG_BT_HCIVHCI=m
# CONFIG_AF_RXRPC is not set

#
# Wireless
#
CONFIG_CFG80211=m
CONFIG_NL80211=y
CONFIG_WIRELESS_EXT=y
CONFIG_MAC80211=m

#
# Rate control algorithm selection
#
CONFIG_MAC80211_RC_DEFAULT_PID=y
# CONFIG_MAC80211_RC_DEFAULT_SIMPLE is not set
# CONFIG_MAC80211_RC_DEFAULT_NONE is not set

#
# Selecting 'y' for an algorithm will
#

#
# build the algorithm into mac80211.
#
CONFIG_MAC80211_RC_DEFAULT="pid"
CONFIG_MAC80211_RC_PID=y
# CONFIG_MAC80211_RC_SIMPLE is not set
CONFIG_MAC80211_LEDS=y
CONFIG_MAC80211_DEBUGFS=y
CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT=y
# CONFIG_MAC80211_DEBUG is not set
CONFIG_IEEE80211=m
CONFIG_IEEE80211_DEBUG=y
CONFIG_IEEE80211_CRYPT_WEP=m
CONFIG_IEEE80211_CRYPT_CCMP=m
CONFIG_IEEE80211_CRYPT_TKIP=m
# CONFIG_IEEE80211_SOFTMAC is not set
CONFIG_RFKILL=m
# CONFIG_RFKILL_INPUT is not set
CONFIG_RFKILL_LEDS=y
# CONFIG_NET_9P is not set

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
CONFIG_CONNECTOR=m
CONFIG_MTD=m
CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=0
CONFIG_MTD_CONCAT=m
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_REDBOOT_PARTS=m
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
CONFIG_MTD_REDBOOT_PARTS_READONLY=y

#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=m
CONFIG_MTD_BLKDEVS=m
CONFIG_MTD_BLOCK=m
CONFIG_MTD_BLOCK_RO=m
CONFIG_FTL=m
CONFIG_NFTL=m
CONFIG_NFTL_RW=y
CONFIG_INFTL=m
CONFIG_RFD_FTL=m
CONFIG_SSFDC=m
CONFIG_MTD_OOPS=m

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=m
CONFIG_MTD_JEDECPROBE=m
CONFIG_MTD_GEN_PROBE=m
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_NOSWAP=y
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_OTP is not set
CONFIG_MTD_CFI_INTELEXT=m
CONFIG_MTD_CFI_AMDSTD=m
CONFIG_MTD_CFI_STAA=m
CONFIG_MTD_CFI_UTIL=m
CONFIG_MTD_RAM=m
CONFIG_MTD_ROM=m
CONFIG_MTD_ABSENT=m

#
# Mapping drivers for chip access
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=m
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
CONFIG_MTD_SC520CDP=m
CONFIG_MTD_NETSC520=m
CONFIG_MTD_TS5500=m
CONFIG_MTD_SBC_GXX=m
CONFIG_MTD_AMD76XROM=m
CONFIG_MTD_ICHXROM=m
CONFIG_MTD_ESB2ROM=m
CONFIG_MTD_CK804XROM=m
CONFIG_MTD_SCB2_FLASH=m
CONFIG_MTD_NETtel=m
CONFIG_MTD_DILNETPC=m
CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000
CONFIG_MTD_L440GX=m
CONFIG_MTD_PCI=m
CONFIG_MTD_INTEL_VR_NOR=m
CONFIG_MTD_PLATRAM=m

#
# Self-contained MTD device drivers
#
CONFIG_MTD_PMC551=m
CONFIG_MTD_PMC551_BUGFIX=y
CONFIG_MTD_PMC551_DEBUG=y
CONFIG_MTD_DATAFLASH=m
CONFIG_MTD_M25P80=m
CONFIG_MTD_SLRAM=m
CONFIG_MTD_PHRAM=m
CONFIG_MTD_MTDRAM=m
CONFIG_MTDRAM_TOTAL_SIZE=4096
CONFIG_MTDRAM_ERASE_SIZE=128
CONFIG_MTD_BLOCK2MTD=m

#
# Disk-On-Chip Device Drivers
#
CONFIG_MTD_DOC2000=m
CONFIG_MTD_DOC2001=m
CONFIG_MTD_DOC2001PLUS=m
CONFIG_MTD_DOCPROBE=m
CONFIG_MTD_DOCECC=m
CONFIG_MTD_DOCPROBE_ADVANCED=y
CONFIG_MTD_DOCPROBE_ADDRESS=0x0000
CONFIG_MTD_DOCPROBE_HIGH=y
CONFIG_MTD_DOCPROBE_55AA=y
CONFIG_MTD_NAND=m
CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_ECC_SMC=y
CONFIG_MTD_NAND_MUSEUM_IDS=y
CONFIG_MTD_NAND_IDS=m
CONFIG_MTD_NAND_DISKONCHIP=m
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
CONFIG_MTD_NAND_CAFE=m
CONFIG_MTD_NAND_CS553X=m
CONFIG_MTD_NAND_NANDSIM=m
CONFIG_MTD_NAND_PLATFORM=m
CONFIG_MTD_ALAUDA=m
CONFIG_MTD_ONENAND=m
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
CONFIG_MTD_ONENAND_OTP=y
CONFIG_MTD_ONENAND_2X_PROGRAM=y
CONFIG_MTD_ONENAND_SIM=m

#
# UBI - Unsorted block images
#
CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_RESERVE=1
CONFIG_MTD_UBI_GLUEBI=y

#
# UBI debugging options
#
CONFIG_MTD_UBI_DEBUG=y
CONFIG_MTD_UBI_DEBUG_MSG=y
CONFIG_MTD_UBI_DEBUG_PARANOID=y
CONFIG_MTD_UBI_DEBUG_DISABLE_BGT=y
CONFIG_MTD_UBI_DEBUG_USERSPACE_IO=y
CONFIG_MTD_UBI_DEBUG_EMULATE_BITFLIPS=y
CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES=y
CONFIG_MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES=y

#
# Additional UBI debugging messages
#
CONFIG_MTD_UBI_DEBUG_MSG_BLD=y
CONFIG_MTD_UBI_DEBUG_MSG_EBA=y
CONFIG_MTD_UBI_DEBUG_MSG_WL=y
CONFIG_MTD_UBI_DEBUG_MSG_IO=y
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_PARPORT_SERIAL=m
CONFIG_PARPORT_PC_FIFO=y
CONFIG_PARPORT_PC_SUPERIO=y
CONFIG_PARPORT_PC_PCMCIA=m
# CONFIG_PARPORT_GSC is not set
CONFIG_PARPORT_AX88796=m
CONFIG_PARPORT_1284=y
CONFIG_PARPORT_NOT_PC=y
CONFIG_PNP=y
# CONFIG_PNP_DEBUG is not set

#
# Protocols
#
# CONFIG_ISAPNP is not set
# CONFIG_PNPBIOS is not set
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_FD=m
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_VIRTIO_BLK is not set
CONFIG_MISC_DEVICES=y
# CONFIG_IBM_ASM is not set
# CONFIG_PHANTOM is not set
CONFIG_EEPROM_93CX6=m
# CONFIG_SGI_IOC4 is not set
CONFIG_TIFM_CORE=m
CONFIG_TIFM_7XX1=m
# CONFIG_TC1100_WMI is not set
# CONFIG_SONY_LAPTOP is not set
# CONFIG_THINKPAD_ACPI is not set
CONFIG_INTEL_MENLOW=m
# CONFIG_ENCLOSURE_SERVICES is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set

#
# SCSI device support
#
CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_SCSI_TGT=m
CONFIG_SCSI_NETLINK=y
# CONFIG_SCSI_PROC_FS is not set

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=m
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
# CONFIG_CHR_DEV_SCH is not set

#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
CONFIG_SCSI_WAIT_SCAN=m

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=m
CONFIG_SCSI_FC_ATTRS=m
# CONFIG_SCSI_FC_TGT_ATTRS is not set
CONFIG_SCSI_ISCSI_ATTRS=m
CONFIG_SCSI_SAS_ATTRS=y
CONFIG_SCSI_SAS_LIBSAS=m
# CONFIG_SCSI_SAS_ATA is not set
CONFIG_SCSI_SAS_HOST_SMP=y
CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
CONFIG_SCSI_SRP_ATTRS=m
# CONFIG_SCSI_SRP_TGT_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_ULTRASTOR is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
CONFIG_SCSI_LOWLEVEL_PCMCIA=y
CONFIG_PCMCIA_AHA152X=m
CONFIG_PCMCIA_FDOMAIN=m
CONFIG_PCMCIA_NINJA_SCSI=m
CONFIG_PCMCIA_QLOGIC=m
CONFIG_PCMCIA_SYM53C500=m
CONFIG_ATA=m
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_ACPI=y
CONFIG_SATA_AHCI=m
# CONFIG_SATA_SVW is not set
CONFIG_ATA_PIIX=m
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_SX4 is not set
# CONFIG_SATA_SIL is not set
# CONFIG_SATA_SIL24 is not set
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
# CONFIG_SATA_INIC162X is not set
CONFIG_PATA_ACPI=m
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CS5535 is not set
# CONFIG_PATA_CS5536 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_LEGACY is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
CONFIG_PATA_MPIIX=m
CONFIG_PATA_OLDPIIX=m
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_OPTIDMA is not set
CONFIG_PATA_PCMCIA=m
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_QDI is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_SIL680 is not set
CONFIG_PATA_SIS=m
CONFIG_PATA_VIA=m
# CONFIG_PATA_WINBOND is not set
# CONFIG_PATA_WINBOND_VLB is not set
CONFIG_MD=y
# CONFIG_BLK_DEV_MD is not set
CONFIG_BLK_DEV_DM=m
# CONFIG_DM_DEBUG is not set
# CONFIG_DM_CRYPT is not set
# CONFIG_DM_SNAPSHOT is not set
# CONFIG_DM_MIRROR is not set
# CONFIG_DM_ZERO is not set
# CONFIG_DM_MULTIPATH is not set
# CONFIG_DM_DELAY is not set
# CONFIG_DM_UEVENT is not set
# CONFIG_FUSION is not set

#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
CONFIG_IEEE1394=m

#
# Subsystem Options
#
# CONFIG_IEEE1394_VERBOSEDEBUG is not set

#
# Controllers
#
CONFIG_IEEE1394_PCILYNX=m
CONFIG_IEEE1394_OHCI1394=m

#
# Protocols
#
CONFIG_IEEE1394_VIDEO1394=m
CONFIG_IEEE1394_SBP2=m
# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y
CONFIG_IEEE1394_ETH1394=m
CONFIG_IEEE1394_DV1394=m
CONFIG_IEEE1394_RAWIO=m
CONFIG_I2O=m
CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
CONFIG_I2O_EXT_ADAPTEC=y
CONFIG_I2O_CONFIG=m
CONFIG_I2O_CONFIG_OLD_IOCTL=y
CONFIG_I2O_BUS=m
CONFIG_I2O_BLOCK=m
CONFIG_I2O_SCSI=m
CONFIG_I2O_PROC=m
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
CONFIG_NETDEVICES_MULTIQUEUE=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
# CONFIG_NET_SB1000 is not set
# CONFIG_ARCNET is not set
CONFIG_PHYLIB=m

#
# MII PHY device drivers
#
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
CONFIG_LXT_PHY=m
# CONFIG_CICADA_PHY is not set
# CONFIG_VITESSE_PHY is not set
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_HAPPYMEAL=m
CONFIG_SUNGEM=m
CONFIG_CASSINI=m
CONFIG_NET_VENDOR_3COM=y
CONFIG_EL1=m
CONFIG_EL2=m
CONFIG_ELPLUS=m
CONFIG_EL16=m
CONFIG_EL3=m
CONFIG_3C515=m
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
CONFIG_LANCE=m
CONFIG_NET_VENDOR_SMC=y
CONFIG_WD80x3=m
CONFIG_ULTRA=m
CONFIG_ULTRA32=m
CONFIG_SMC9194=m
CONFIG_ENC28J60=m
CONFIG_ENC28J60_WRITEVERIFY=y
CONFIG_NET_VENDOR_RACAL=y
CONFIG_NI52=m
CONFIG_NI65=m
CONFIG_NET_TULIP=y
CONFIG_DE2104X=m
CONFIG_TULIP=m
CONFIG_TULIP_MWI=y
CONFIG_TULIP_MMIO=y
CONFIG_TULIP_NAPI=y
CONFIG_TULIP_NAPI_HW_MITIGATION=y
CONFIG_DE4X5=m
CONFIG_WINBOND_840=m
CONFIG_DM9102=m
CONFIG_ULI526X=m
CONFIG_PCMCIA_XIRCOM=m
CONFIG_AT1700=m
CONFIG_DEPCA=m
CONFIG_HP100=m
CONFIG_NET_ISA=y
CONFIG_E2100=m
CONFIG_EWRK3=m
CONFIG_EEXPRESS=m
CONFIG_EEXPRESS_PRO=m
CONFIG_HPLAN_PLUS=m
CONFIG_HPLAN=m
CONFIG_LP486E=m
CONFIG_ETH16I=m
CONFIG_NE2000=m
CONFIG_ZNET=m
CONFIG_SEEQ8005=m
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
CONFIG_NET_PCI=y
CONFIG_PCNET32=m
CONFIG_PCNET32_NAPI=y
CONFIG_AMD8111_ETH=m
CONFIG_AMD8111E_NAPI=y
CONFIG_ADAPTEC_STARFIRE=m
CONFIG_ADAPTEC_STARFIRE_NAPI=y
CONFIG_AC3200=m
CONFIG_APRICOT=m
CONFIG_B44=m
CONFIG_B44_PCI_AUTOSELECT=y
CONFIG_B44_PCICORE_AUTOSELECT=y
CONFIG_B44_PCI=y
CONFIG_FORCEDETH=m
CONFIG_FORCEDETH_NAPI=y
CONFIG_CS89x0=m
CONFIG_EEPRO100=m
CONFIG_E100=m
CONFIG_LNE390=m
CONFIG_FEALNX=m
CONFIG_NATSEMI=m
CONFIG_NE2K_PCI=m
CONFIG_NE3210=m
CONFIG_ES3210=m
CONFIG_8139CP=m
CONFIG_8139TOO=m
CONFIG_8139TOO_PIO=y
CONFIG_8139TOO_TUNE_TWISTER=y
CONFIG_8139TOO_8129=y
CONFIG_8139_OLD_RX_RESET=y
CONFIG_R6040=m
CONFIG_SIS900=m
CONFIG_EPIC100=m
CONFIG_SUNDANCE=m
CONFIG_SUNDANCE_MMIO=y
CONFIG_TLAN=m
CONFIG_VIA_RHINE=m
CONFIG_VIA_RHINE_MMIO=y
CONFIG_VIA_RHINE_NAPI=y
CONFIG_SC92031=m
CONFIG_NET_POCKET=y
CONFIG_ATP=m
CONFIG_DE600=m
CONFIG_DE620=m
CONFIG_NETDEV_1000=y
CONFIG_ACENIC=m
CONFIG_ACENIC_OMIT_TIGON_I=y
CONFIG_DL2K=m
CONFIG_E1000=m
CONFIG_E1000_NAPI=y
CONFIG_E1000_DISABLE_PACKET_SPLIT=y
CONFIG_E1000E=m
CONFIG_E1000E_ENABLED=y
CONFIG_IP1000=m
CONFIG_IGB=m
CONFIG_NS83820=m
CONFIG_HAMACHI=m
CONFIG_YELLOWFIN=m
CONFIG_R8169=m
CONFIG_R8169_NAPI=y
CONFIG_R8169_VLAN=y
CONFIG_SIS190=m
CONFIG_SKGE=m
CONFIG_SKGE_DEBUG=y
CONFIG_SKY2=m
CONFIG_SKY2_DEBUG=y
# CONFIG_SK98LIN is not set
CONFIG_VIA_VELOCITY=m
CONFIG_TIGON3=m
CONFIG_BNX2=m
CONFIG_QLA3XXX=m
CONFIG_ATL1=m
CONFIG_NETDEV_10000=y
CONFIG_CHELSIO_T1=m
CONFIG_CHELSIO_T1_1G=y
CONFIG_CHELSIO_T1_NAPI=y
CONFIG_CHELSIO_T3=m
CONFIG_IXGBE=m
CONFIG_IXGB=m
CONFIG_IXGB_NAPI=y
CONFIG_S2IO=m
CONFIG_S2IO_NAPI=y
CONFIG_MYRI10GE=m
CONFIG_NETXEN_NIC=m
CONFIG_NIU=m
# CONFIG_MLX4_CORE is not set
CONFIG_TEHUTI=m
CONFIG_BNX2X=m
CONFIG_TR=y
CONFIG_IBMTR=m
CONFIG_IBMOL=m
CONFIG_IBMLS=m
CONFIG_3C359=m
CONFIG_TMS380TR=m
CONFIG_TMSPCI=m
CONFIG_SKISA=m
CONFIG_PROTEON=m
CONFIG_ABYSS=m
CONFIG_SMCTR=m

#
# Wireless LAN
#
CONFIG_WLAN_PRE80211=y
CONFIG_STRIP=m
CONFIG_ARLAN=m
CONFIG_WAVELAN=m
CONFIG_PCMCIA_WAVELAN=m
CONFIG_PCMCIA_NETWAVE=m
CONFIG_WLAN_80211=y
CONFIG_PCMCIA_RAYCS=m
CONFIG_IPW2100=m
# CONFIG_IPW2100_MONITOR is not set
# CONFIG_IPW2100_DEBUG is not set
CONFIG_IPW2200=m
CONFIG_IPW2200_MONITOR=y
CONFIG_IPW2200_RADIOTAP=y
CONFIG_IPW2200_PROMISCUOUS=y
CONFIG_IPW2200_QOS=y
# CONFIG_IPW2200_DEBUG is not set
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
CONFIG_LIBERTAS_CS=m
CONFIG_LIBERTAS_SDIO=m
CONFIG_LIBERTAS_DEBUG=y
CONFIG_AIRO=m
CONFIG_HERMES=m
CONFIG_PLX_HERMES=m
CONFIG_TMD_HERMES=m
CONFIG_NORTEL_HERMES=m
CONFIG_PCI_HERMES=m
CONFIG_PCMCIA_HERMES=m
CONFIG_PCMCIA_SPECTRUM=m
CONFIG_ATMEL=m
CONFIG_PCI_ATMEL=m
CONFIG_PCMCIA_ATMEL=m
CONFIG_AIRO_CS=m
CONFIG_PCMCIA_WL3501=m
CONFIG_PRISM54=m
CONFIG_USB_ZD1201=m
CONFIG_USB_NET_RNDIS_WLAN=m
CONFIG_RTL8180=m
CONFIG_RTL8187=m
CONFIG_ADM8211=m
CONFIG_P54_COMMON=m
CONFIG_P54_USB=m
CONFIG_P54_PCI=m
CONFIG_ATH5K=m
CONFIG_IWL4965=m
# CONFIG_IWL4965_QOS is not set
CONFIG_IWL4965_SPECTRUM_MEASUREMENT=y
CONFIG_IWL4965_SENSITIVITY=y
# CONFIG_IWL4965_DEBUG is not set
CONFIG_IWL3945=m
# CONFIG_IWL3945_QOS is not set
CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y
CONFIG_IWL3945_DEBUG=y
CONFIG_HOSTAP=m
CONFIG_HOSTAP_FIRMWARE=y
CONFIG_HOSTAP_FIRMWARE_NVRAM=y
CONFIG_HOSTAP_PLX=m
CONFIG_HOSTAP_PCI=m
CONFIG_HOSTAP_CS=m
CONFIG_B43=m
CONFIG_B43_PCI_AUTOSELECT=y
CONFIG_B43_PCICORE_AUTOSELECT=y
CONFIG_B43_PCMCIA=y
CONFIG_B43_LEDS=y
CONFIG_B43_DEBUG=y
CONFIG_B43LEGACY=m
CONFIG_B43LEGACY_PCI_AUTOSELECT=y
CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
CONFIG_B43LEGACY_LEDS=y
CONFIG_B43LEGACY_DEBUG=y
CONFIG_B43LEGACY_DMA=y
CONFIG_B43LEGACY_PIO=y
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_B43LEGACY_DMA_MODE is not set
# CONFIG_B43LEGACY_PIO_MODE is not set
CONFIG_ZD1211RW=m
CONFIG_ZD1211RW_DEBUG=y
CONFIG_RT2X00=m
CONFIG_RT2X00_LIB=m
CONFIG_RT2X00_LIB_PCI=m
CONFIG_RT2X00_LIB_USB=m
CONFIG_RT2X00_LIB_FIRMWARE=y
CONFIG_RT2X00_LIB_RFKILL=y
CONFIG_RT2400PCI=m
CONFIG_RT2400PCI_RFKILL=y
CONFIG_RT2500PCI=m
CONFIG_RT2500PCI_RFKILL=y
CONFIG_RT61PCI=m
CONFIG_RT61PCI_RFKILL=y
CONFIG_RT2500USB=m
CONFIG_RT73USB=m
CONFIG_RT2X00_LIB_DEBUGFS=y
CONFIG_RT2X00_DEBUG=y

#
# USB Network Adapters
#
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_CDCETHER=m
CONFIG_USB_NET_DM9601=m
CONFIG_USB_NET_GL620A=m
CONFIG_USB_NET_NET1080=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
CONFIG_USB_NET_RNDIS_HOST=m
CONFIG_USB_NET_CDC_SUBSET=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_BELKIN=y
CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=m
CONFIG_NET_PCMCIA=y
CONFIG_PCMCIA_3C589=m
CONFIG_PCMCIA_3C574=m
CONFIG_PCMCIA_FMVJ18X=m
CONFIG_PCMCIA_PCNET=m
CONFIG_PCMCIA_NMCLAN=m
CONFIG_PCMCIA_SMC91C92=m
CONFIG_PCMCIA_XIRC2PS=m
CONFIG_PCMCIA_AXNET=m
# CONFIG_PCMCIA_IBMTR is not set
CONFIG_WAN=y
CONFIG_HOSTESS_SV11=m
CONFIG_COSA=m
CONFIG_LANMEDIA=m
CONFIG_SEALEVEL_4021=m
CONFIG_HDLC=m
CONFIG_HDLC_RAW=m
CONFIG_HDLC_RAW_ETH=m
CONFIG_HDLC_CISCO=m
CONFIG_HDLC_FR=m
CONFIG_HDLC_PPP=m

#
# X.25/LAPB support is disabled
#
CONFIG_PCI200SYN=m
CONFIG_WANXL=m
CONFIG_PC300=m
CONFIG_PC300_MLPPP=y

#
# Cyclades-PC300 MLPPP support is disabled.
#

#
# Refer to the file README.mlppp, provided by PC300 package.
#
CONFIG_PC300TOO=m
CONFIG_N2=m
CONFIG_C101=m
CONFIG_FARSYNC=m
CONFIG_DSCC4=m
CONFIG_DSCC4_PCISYNC=y
CONFIG_DSCC4_PCI_RST=y
CONFIG_DLCI=m
CONFIG_DLCI_MAX=8
CONFIG_SDLA=m
CONFIG_SBNI=m
CONFIG_SBNI_MULTILINE=y
CONFIG_ATM_DRIVERS=y
# CONFIG_ATM_DUMMY is not set
# CONFIG_ATM_TCP is not set
# CONFIG_ATM_LANAI is not set
# CONFIG_ATM_ENI is not set
# CONFIG_ATM_FIRESTREAM is not set
# CONFIG_ATM_ZATM is not set
# CONFIG_ATM_NICSTAR is not set
# CONFIG_ATM_IDT77252 is not set
# CONFIG_ATM_AMBASSADOR is not set
# CONFIG_ATM_HORIZON is not set
# CONFIG_ATM_IA is not set
# CONFIG_ATM_FORE200E_MAYBE is not set
# CONFIG_ATM_HE is not set
CONFIG_FDDI=y
CONFIG_DEFXX=m
CONFIG_DEFXX_MMIO=y
CONFIG_SKFP=m
CONFIG_HIPPI=y
CONFIG_ROADRUNNER=m
CONFIG_ROADRUNNER_LARGE_RINGS=y
CONFIG_PLIP=m
CONFIG_PPP=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPP_FILTER=y
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_MPPE=m
CONFIG_PPPOE=m
# CONFIG_PPPOATM is not set
CONFIG_PPPOL2TP=m
# CONFIG_SLIP is not set
CONFIG_SLHC=m
# CONFIG_NET_FC is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_VIRTIO_NET is not set
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
CONFIG_INPUT_POLLDEV=m

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=800
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
CONFIG_KEYBOARD_SUNKBD=m
CONFIG_KEYBOARD_LKKBD=m
CONFIG_KEYBOARD_XTKBD=m
CONFIG_KEYBOARD_NEWTON=m
CONFIG_KEYBOARD_STOWAWAY=m
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=m
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_MOUSE_PS2_TOUCHKIT=y
CONFIG_MOUSE_SERIAL=m
CONFIG_MOUSE_APPLETOUCH=m
# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_LOGIBM is not set
# CONFIG_MOUSE_PC110PAD is not set
CONFIG_MOUSE_VSXXXAA=m
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=m
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set

#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NOZOMI is not set

#
# Serial drivers
#
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_CS=m
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
# CONFIG_SERIAL_8250_FOURPORT is not set
# CONFIG_SERIAL_8250_ACCENT is not set
# CONFIG_SERIAL_8250_BOCA is not set
# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
# CONFIG_SERIAL_8250_HUB6 is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
CONFIG_SERIAL_8250_RSA=y

#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_PRINTER is not set
# CONFIG_PPDEV is not set
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_IPMI_HANDLER=m
# CONFIG_IPMI_PANIC_EVENT is not set
CONFIG_IPMI_DEVICE_INTERFACE=m
CONFIG_IPMI_SI=m
CONFIG_IPMI_WATCHDOG=m
CONFIG_IPMI_POWEROFF=m
CONFIG_HW_RANDOM=m
CONFIG_HW_RANDOM_INTEL=m
# CONFIG_HW_RANDOM_AMD is not set
# CONFIG_HW_RANDOM_GEODE is not set
# CONFIG_HW_RANDOM_VIA is not set
CONFIG_NVRAM=m
CONFIG_RTC=m
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_SONYPI is not set

#
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not set
# CONFIG_CARDMAN_4000 is not set
# CONFIG_CARDMAN_4040 is not set
# CONFIG_IPWIRELESS is not set
# CONFIG_MWAVE is not set
# CONFIG_PC8736x_GPIO is not set
# CONFIG_NSC_GPIO is not set
# CONFIG_CS5535_GPIO is not set
# CONFIG_RAW_DRIVER is not set
CONFIG_HPET=y
# CONFIG_HPET_RTC_IRQ is not set
CONFIG_HPET_MMAP=y
# CONFIG_HANGCHECK_TIMER is not set
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=m

#
# I2C Algorithms
#
CONFIG_I2C_ALGOBIT=m
# CONFIG_I2C_ALGOPCF is not set
CONFIG_I2C_ALGOPCA=m

#
# I2C Hardware Bus support
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
CONFIG_I2C_I801=m
CONFIG_I2C_I810=m
CONFIG_I2C_PIIX4=m
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_I2C_SIMTEC is not set
# CONFIG_SCx200_ACB is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_TINY_USB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
# CONFIG_I2C_PCA_ISA is not set

#
# Miscellaneous I2C Chip support
#
CONFIG_DS1682=m
CONFIG_SENSORS_EEPROM=m
CONFIG_SENSORS_PCF8574=m
CONFIG_PCF8575=m
CONFIG_SENSORS_PCF8591=m
CONFIG_TPS65010=m
CONFIG_SENSORS_MAX6875=m
CONFIG_SENSORS_TSL2550=m
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set

#
# SPI support
#
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y

#
# SPI Master Controller Drivers
#
CONFIG_SPI_BITBANG=m
# CONFIG_SPI_BUTTERFLY is not set
# CONFIG_SPI_LM70_LLP is not set

#
# SPI Protocol Masters
#
CONFIG_SPI_AT25=m
CONFIG_SPI_SPIDEV=m
CONFIG_SPI_TLE62X0=m
# CONFIG_W1 is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
# CONFIG_PDA_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
CONFIG_HWMON=m
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_ABITUGURU3 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_K8TEMP is not set
# CONFIG_SENSORS_ASB100 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
# CONFIG_SENSORS_FSCHER is not set
# CONFIG_SENSORS_FSCPOS is not set
# CONFIG_SENSORS_FSCHMD is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
CONFIG_SENSORS_CORETEMP=m
# CONFIG_SENSORS_IBMPEX is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM70 is not set
# CONFIG_SENSORS_LM75 is not set
# CONFIG_SENSORS_LM77 is not set
# CONFIG_SENSORS_LM78 is not set
# CONFIG_SENSORS_LM80 is not set
# CONFIG_SENSORS_LM83 is not set
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_SENSORS_HDAPS is not set
# CONFIG_SENSORS_APPLESMC is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
CONFIG_THERMAL=y
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set

#
# Watchdog Device Drivers
#
CONFIG_SOFT_WATCHDOG=m
# CONFIG_ACQUIRE_WDT is not set
# CONFIG_ADVANTECH_WDT is not set
# CONFIG_ALIM1535_WDT is not set
# CONFIG_ALIM7101_WDT is not set
# CONFIG_SC520_WDT is not set
# CONFIG_EUROTECH_WDT is not set
# CONFIG_IB700_WDT is not set
# CONFIG_IBMASR is not set
# CONFIG_WAFER_WDT is not set
CONFIG_I6300ESB_WDT=m
CONFIG_ITCO_WDT=m
# CONFIG_ITCO_VENDOR_SUPPORT is not set
# CONFIG_IT8712F_WDT is not set
# CONFIG_HP_WATCHDOG is not set
# CONFIG_SC1200_WDT is not set
# CONFIG_PC87413_WDT is not set
# CONFIG_60XX_WDT is not set
# CONFIG_SBC8360_WDT is not set
# CONFIG_SBC7240_WDT is not set
# CONFIG_CPU5_WDT is not set
# CONFIG_SMSC37B787_WDT is not set
# CONFIG_W83627HF_WDT is not set
# CONFIG_W83697HF_WDT is not set
# CONFIG_W83877F_WDT is not set
# CONFIG_W83977F_WDT is not set
# CONFIG_MACHZ_WDT is not set
# CONFIG_SBC_EPX_C3_WATCHDOG is not set

#
# ISA-based Watchdog Cards
#
# CONFIG_PCWATCHDOG is not set
# CONFIG_MIXCOMWD is not set
# CONFIG_WDT is not set

#
# PCI-based Watchdog Cards
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set

#
# USB-based Watchdog Cards
#
# CONFIG_USBPCWATCHDOG is not set

#
# Sonics Silicon Backplane
#
CONFIG_SSB_POSSIBLE=y
CONFIG_SSB=m
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_B43_PCI_BRIDGE=y
CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
CONFIG_SSB_PCMCIAHOST=y
# CONFIG_SSB_DEBUG is not set
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_DRIVER_PCICORE=y

#
# Multifunction device drivers
#
# CONFIG_MFD_SM501 is not set

#
# Multimedia devices
#
CONFIG_VIDEO_DEV=m
CONFIG_VIDEO_V4L2_COMMON=m
# CONFIG_VIDEO_V4L1 is not set
CONFIG_VIDEO_V4L1_COMPAT=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_ADV_DEBUG is not set
CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
CONFIG_VIDEO_TVAUDIO=m
CONFIG_VIDEO_TDA7432=m
CONFIG_VIDEO_TDA9875=m
CONFIG_VIDEO_MSP3400=m
CONFIG_VIDEO_WM8775=m
CONFIG_VIDEO_OV7670=m
CONFIG_VIDEO_SAA711X=m
CONFIG_VIDEO_TVP5150=m
CONFIG_VIDEO_CX25840=m
CONFIG_VIDEO_CX2341X=m
# CONFIG_VIDEO_VIVI is not set
CONFIG_VIDEO_BT848=m
CONFIG_VIDEO_SAA6588=m
CONFIG_VIDEO_SAA5246A=m
CONFIG_VIDEO_SAA5249=m
CONFIG_VIDEO_SAA7134=m
CONFIG_VIDEO_SAA7134_ALSA=m
CONFIG_VIDEO_HEXIUM_ORION=m
CONFIG_VIDEO_HEXIUM_GEMINI=m
CONFIG_VIDEO_CX88=m
CONFIG_VIDEO_CX88_ALSA=m
CONFIG_VIDEO_CX88_BLACKBIRD=m
CONFIG_VIDEO_CAFE_CCIC=m
CONFIG_V4L_USB_DRIVERS=y
CONFIG_VIDEO_PVRUSB2=m
# CONFIG_VIDEO_PVRUSB2_ONAIR_CREATOR is not set
# CONFIG_VIDEO_PVRUSB2_ONAIR_USB2 is not set
CONFIG_VIDEO_PVRUSB2_SYSFS=y
# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
CONFIG_VIDEO_EM28XX=m
# CONFIG_VIDEO_EM28XX_ALSA is not set
CONFIG_VIDEO_USBVISION=m
CONFIG_USB_ET61X251=m
CONFIG_USB_SN9C102=m
CONFIG_USB_ZC0301=m
CONFIG_USB_ZR364XX=m
CONFIG_USB_STKWEBCAM=m
# CONFIG_RADIO_ADAPTERS is not set
# CONFIG_DVB_CORE is not set
CONFIG_VIDEO_SAA7146=m
CONFIG_VIDEO_SAA7146_VV=m
CONFIG_VIDEO_TUNER=m
# CONFIG_VIDEO_TUNER_CUSTOMIZE is not set
CONFIG_TUNER_XC2028=m
CONFIG_TUNER_MT20XX=m
CONFIG_TUNER_TDA8290=m
CONFIG_TUNER_TEA5761=m
CONFIG_TUNER_TEA5767=m
CONFIG_TUNER_SIMPLE=m
CONFIG_TUNER_TDA9887=m
CONFIG_VIDEOBUF_GEN=m
CONFIG_VIDEOBUF_DMA_SG=m
CONFIG_VIDEO_BTCX=m
CONFIG_VIDEO_IR_I2C=m
CONFIG_VIDEO_IR=m
CONFIG_VIDEO_TVEEPROM=m
# CONFIG_DAB is not set

#
# Graphics support
#
CONFIG_AGP=y
# CONFIG_AGP_ALI is not set
# CONFIG_AGP_ATI is not set
# CONFIG_AGP_AMD is not set
# CONFIG_AGP_AMD64 is not set
CONFIG_AGP_INTEL=m
# CONFIG_AGP_NVIDIA is not set
# CONFIG_AGP_SIS is not set
# CONFIG_AGP_SWORKS is not set
# CONFIG_AGP_VIA is not set
# CONFIG_AGP_EFFICEON is not set
CONFIG_DRM=m
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
# CONFIG_DRM_RADEON is not set
# CONFIG_DRM_I810 is not set
# CONFIG_DRM_I830 is not set
CONFIG_DRM_I915=m
# CONFIG_DRM_MGA is not set
# CONFIG_DRM_SIS is not set
# CONFIG_DRM_VIA is not set
# CONFIG_DRM_SAVAGE is not set
CONFIG_VGASTATE=m
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_DDC=m
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
# CONFIG_FB_SYS_FOPS is not set
CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y

#
# Frame buffer hardware drivers
#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ARC is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
# CONFIG_FB_VGA16 is not set
CONFIG_FB_UVESA=m
CONFIG_FB_VESA=y
CONFIG_FB_EFI=y
# CONFIG_FB_IMAC is not set
# CONFIG_FB_HECUBA is not set
# CONFIG_FB_HGA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
CONFIG_FB_I810=m
CONFIG_FB_I810_GTF=y
CONFIG_FB_I810_I2C=y
# CONFIG_FB_LE80578 is not set
CONFIG_FB_INTEL=m
CONFIG_FB_INTEL_DEBUG=y
CONFIG_FB_INTEL_I2C=y
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VT8623 is not set
# CONFIG_FB_CYBLA is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_GEODE is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set

#
# Display device support
#
CONFIG_DISPLAY_SUPPORT=m

#
# Display hardware drivers
#

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128
CONFIG_VIDEO_SELECT=y
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y

#
# Sound
#
CONFIG_SOUND=m

#
# Advanced Linux Sound Architecture
#
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
CONFIG_SND_HWDEP=m
CONFIG_SND_SEQUENCER=m
# CONFIG_SND_SEQ_DUMMY is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_RTCTIMER=m
CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
# CONFIG_SND_DYNAMIC_MINORS is not set
# CONFIG_SND_SUPPORT_OLD_API is not set
CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_DETECT=y
CONFIG_SND_PCM_XRUN_DEBUG=y

#
# Generic devices
#
CONFIG_SND_AC97_CODEC=m
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_MTS64 is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
# CONFIG_SND_PORTMAN2X4 is not set

#
# ISA devices
#
# CONFIG_SND_ADLIB is not set
# CONFIG_SND_AD1816A is not set
# CONFIG_SND_AD1848 is not set
# CONFIG_SND_ALS100 is not set
# CONFIG_SND_AZT2320 is not set
# CONFIG_SND_CMI8330 is not set
# CONFIG_SND_CS4231 is not set
# CONFIG_SND_CS4232 is not set
# CONFIG_SND_CS4236 is not set
# CONFIG_SND_DT019X is not set
# CONFIG_SND_ES968 is not set
# CONFIG_SND_ES1688 is not set
# CONFIG_SND_ES18XX is not set
# CONFIG_SND_SC6000 is not set
# CONFIG_SND_GUSCLASSIC is not set
# CONFIG_SND_GUSEXTREME is not set
# CONFIG_SND_GUSMAX is not set
# CONFIG_SND_INTERWAVE is not set
# CONFIG_SND_INTERWAVE_STB is not set
# CONFIG_SND_OPL3SA2 is not set
# CONFIG_SND_OPTI92X_AD1848 is not set
# CONFIG_SND_OPTI92X_CS4231 is not set
# CONFIG_SND_OPTI93X is not set
# CONFIG_SND_MIRO is not set
# CONFIG_SND_SB8 is not set
# CONFIG_SND_SB16 is not set
# CONFIG_SND_SBAWE is not set
# CONFIG_SND_SGALAXY is not set
# CONFIG_SND_SSCAPE is not set
# CONFIG_SND_WAVEFRONT is not set

#
# PCI devices
#
# CONFIG_SND_AD1889 is not set
# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALS4000 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
# CONFIG_SND_AU8810 is not set
# CONFIG_SND_AU8820 is not set
# CONFIG_SND_AU8830 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_BT87X is not set
# CONFIG_SND_CA0106 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_OXYGEN is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS5530 is not set
# CONFIG_SND_CS5535AUDIO is not set
# CONFIG_SND_DARLA20 is not set
# CONFIG_SND_GINA20 is not set
# CONFIG_SND_LAYLA20 is not set
# CONFIG_SND_DARLA24 is not set
# CONFIG_SND_GINA24 is not set
# CONFIG_SND_LAYLA24 is not set
# CONFIG_SND_MONA is not set
# CONFIG_SND_MIA is not set
# CONFIG_SND_ECHO3G is not set
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
# CONFIG_SND_FM801 is not set
CONFIG_SND_HDA_INTEL=m
CONFIG_SND_HDA_HWDEP=y
CONFIG_SND_HDA_CODEC_REALTEK=y
CONFIG_SND_HDA_CODEC_ANALOG=y
CONFIG_SND_HDA_CODEC_SIGMATEL=y
CONFIG_SND_HDA_CODEC_VIA=y
CONFIG_SND_HDA_CODEC_ATIHDMI=y
CONFIG_SND_HDA_CODEC_CONEXANT=y
CONFIG_SND_HDA_CODEC_CMEDIA=y
CONFIG_SND_HDA_CODEC_SI3054=y
CONFIG_SND_HDA_GENERIC=y
# CONFIG_SND_HDA_POWER_SAVE is not set
# CONFIG_SND_HDSP is not set
# CONFIG_SND_HDSPM is not set
# CONFIG_SND_HIFIER is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
CONFIG_SND_INTEL8X0=m
CONFIG_SND_INTEL8X0M=m
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_SIS7019 is not set
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VIRTUOSO is not set
# CONFIG_SND_VX222 is not set
# CONFIG_SND_YMFPCI is not set
CONFIG_SND_AC97_POWER_SAVE=y
CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0

#
# SPI devices
#

#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
# CONFIG_SND_USB_USX2Y is not set
# CONFIG_SND_USB_CAIAQ is not set

#
# PCMCIA devices
#
# CONFIG_SND_VXPOCKET is not set
# CONFIG_SND_PDAUDIOCF is not set

#
# System on Chip audio support
#
# CONFIG_SND_SOC is not set

#
# SoC Audio support for SuperH
#

#
# ALSA SoC audio for Freescale SOCs
#

#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
CONFIG_AC97_BUS=m
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set

#
# USB Input Devices
#
CONFIG_USB_HID=m
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set

#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=m
CONFIG_USB_DEBUG=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y

#
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_PERSIST is not set
# CONFIG_USB_OTG is not set

#
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
CONFIG_USB_ISP116X_HCD=m
CONFIG_USB_OHCI_HCD=m
# CONFIG_USB_OHCI_HCD_SSB is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=m
CONFIG_USB_SL811_HCD=m
CONFIG_USB_SL811_CS=m
CONFIG_USB_R8A66597_HCD=m

#
# USB Device Class drivers
#
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m

#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#

#
# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_DPCM=y
CONFIG_USB_STORAGE_USBAT=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
CONFIG_USB_STORAGE_ALAUDA=y
CONFIG_USB_STORAGE_KARMA=y
CONFIG_USB_LIBUSUAL=y

#
# USB Imaging devices
#
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m
# CONFIG_USB_MON is not set

#
# USB port drivers
#
# CONFIG_USB_USS720 is not set
CONFIG_USB_SERIAL=m
CONFIG_USB_EZUSB=y
CONFIG_USB_SERIAL_GENERIC=y
# CONFIG_USB_SERIAL_AIRCABLE is not set
# CONFIG_USB_SERIAL_AIRPRIME is not set
# CONFIG_USB_SERIAL_ARK3116 is not set
# CONFIG_USB_SERIAL_BELKIN is not set
# CONFIG_USB_SERIAL_CH341 is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
# CONFIG_USB_SERIAL_CP2101 is not set
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
# CONFIG_USB_SERIAL_EMPEG is not set
# CONFIG_USB_SERIAL_FTDI_SIO is not set
# CONFIG_USB_SERIAL_FUNSOFT is not set
# CONFIG_USB_SERIAL_VISOR is not set
# CONFIG_USB_SERIAL_IPAQ is not set
# CONFIG_USB_SERIAL_IR is not set
# CONFIG_USB_SERIAL_EDGEPORT is not set
# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
# CONFIG_USB_SERIAL_GARMIN is not set
# CONFIG_USB_SERIAL_IPW is not set
# CONFIG_USB_SERIAL_IUU is not set
# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
# CONFIG_USB_SERIAL_KEYSPAN is not set
# CONFIG_USB_SERIAL_KLSI is not set
# CONFIG_USB_SERIAL_KOBIL_SCT is not set
# CONFIG_USB_SERIAL_MCT_U232 is not set
# CONFIG_USB_SERIAL_MOS7720 is not set
# CONFIG_USB_SERIAL_MOS7840 is not set
# CONFIG_USB_SERIAL_NAVMAN is not set
# CONFIG_USB_SERIAL_PL2303 is not set
# CONFIG_USB_SERIAL_OTI6858 is not set
# CONFIG_USB_SERIAL_HP4X is not set
# CONFIG_USB_SERIAL_SAFE is not set
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
# CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_SERIAL_OPTION is not set
# CONFIG_USB_SERIAL_OMNINET is not set
# CONFIG_USB_SERIAL_DEBUG is not set

#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ATM is not set
# CONFIG_USB_GADGET is not set
CONFIG_MMC=m
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set

#
# MMC/SD Card Drivers
#
CONFIG_MMC_BLOCK=m
CONFIG_MMC_BLOCK_BOUNCE=y
CONFIG_SDIO_UART=m

#
# MMC/SD Host Controller Drivers
#
CONFIG_MMC_SDHCI=m
CONFIG_MMC_RICOH_MMC=m
CONFIG_MMC_WBSD=m
CONFIG_MMC_TIFM_SD=m
CONFIG_MEMSTICK=m
CONFIG_MEMSTICK_DEBUG=y

#
# MemoryStick drivers
#
# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
CONFIG_MSPRO_BLOCK=m

#
# MemoryStick Host Controller Drivers
#
CONFIG_MEMSTICK_TIFM_MS=m
CONFIG_MEMSTICK_JMICRON_38X=m
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=m

#
# LED drivers
#
CONFIG_LEDS_CLEVO_MAIL=m

#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
# CONFIG_RTC_CLASS is not set
CONFIG_DMADEVICES=y

#
# DMA Devices
#
CONFIG_INTEL_IOATDMA=m
CONFIG_DMA_ENGINE=y

#
# DMA Clients
#
# CONFIG_NET_DMA is not set
CONFIG_DCA=m
# CONFIG_AUXDISPLAY is not set

#
# Userspace I/O
#
CONFIG_UIO=m
CONFIG_UIO_CIF=m

#
# Firmware Drivers
#
CONFIG_EDD=m
CONFIG_EFI_VARS=m
CONFIG_DELL_RBU=m
# CONFIG_DCDBAS is not set
CONFIG_DMIID=y

#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# CONFIG_EXT2_FS_SECURITY is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m
CONFIG_GENERIC_ACL=y

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y

#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
# CONFIG_JFFS2_SUMMARY is not set
# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
# CONFIG_SMB_FS is not set
CONFIG_CIFS=m
CONFIG_CIFS_STATS=y
# CONFIG_CIFS_STATS2 is not set
CONFIG_CIFS_WEAK_PW_HASH=y
# CONFIG_CIFS_XATTR is not set
CONFIG_CIFS_DEBUG2=y
# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
CONFIG_LDM_PARTITION=y
CONFIG_LDM_DEBUG=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
CONFIG_EFI_PARTITION=y
# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
CONFIG_NLS_ISO8859_15=y
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=y
CONFIG_DLM=m
CONFIG_DLM_DEBUG=y

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_PRINTK_TIME=y
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
CONFIG_SLUB_DEBUG_ON=y
# CONFIG_SLUB_STATS is not set
CONFIG_DEBUG_PREEMPT=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCKDEP=y
# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_LOCKDEP=y
CONFIG_TRACE_IRQFLAGS=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_HIGHMEM=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_SG=y
CONFIG_FRAME_POINTER=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_BACKTRACE_SELF_TEST=m
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
# CONFIG_SAMPLES is not set
CONFIG_EARLY_PRINTK=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_DEBUG_RODATA=y
CONFIG_DEBUG_RODATA_TEST=y
# CONFIG_DEBUG_NX_TEST is not set
CONFIG_4KSTACKS=y
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
CONFIG_DOUBLEFAULT=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_IO_DELAY_0XED is not set
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEFAULT_IO_DELAY_TYPE=0
CONFIG_DEBUG_BOOT_PARAMS=y
CONFIG_CPA_DEBUG=y

#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=m
CONFIG_CRYPTO_BLKCIPHER=m
# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_HASH=m
CONFIG_CRYPTO_MANAGER=m
CONFIG_CRYPTO_HMAC=m
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=m
CONFIG_CRYPTO_SHA1=m
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=m
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_XTS is not set
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_TWOFISH_586 is not set
# CONFIG_CRYPTO_SERPENT is not set
CONFIG_CRYPTO_AES=m
# CONFIG_CRYPTO_AES_586 is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
# CONFIG_CRYPTO_TEA is not set
CONFIG_CRYPTO_ARC4=m
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SALSA20_586 is not set
# CONFIG_CRYPTO_DEFLATE is not set
CONFIG_CRYPTO_MICHAEL_MIC=m
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_PADLOCK is not set
# CONFIG_CRYPTO_DEV_GEODE is not set
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
CONFIG_HAVE_KVM=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
CONFIG_KVM_INTEL=m
CONFIG_KVM_AMD=m
CONFIG_LGUEST=m
CONFIG_VIRTIO=y
CONFIG_VIRTIO_RING=y
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_BALLOON=m

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=m
CONFIG_AUDIT_GENERIC=y
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
CONFIG_REED_SOLOMON=m
CONFIG_REED_SOLOMON_DEC16=y
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14  3:04 2.6.25-rc9 -- INFO: possible circular locking dependency detected Miles Lane
  2008-04-14  3:29 ` Miles Lane
@ 2008-04-14  6:54 ` Peter Zijlstra
  2008-04-14  7:02   ` Heiko Carstens
  2008-04-14 12:06   ` Peter Zijlstra
  1 sibling, 2 replies; 23+ messages in thread
From: Peter Zijlstra @ 2008-04-14  6:54 UTC (permalink / raw)
  To: Miles Lane; +Cc: LKML, Gautham Shenoy, Rafael J. Wysocki, Ingo Molnar

Fun,

I will need to sort out this code before I can say anything about that,
perhaps Gautham and or Rafael have ideas before I can come up with
something.. ?

On Sun, 2008-04-13 at 23:04 -0400, Miles Lane wrote:
> [ 3217.586003] [ INFO: possible circular locking dependency detected ]
> [ 3217.586006] 2.6.25-rc9 #1
> [ 3217.586008] -------------------------------------------------------
> [ 3217.586011] pm-suspend/7421 is trying to acquire lock:
> [ 3217.586013]  (&per_cpu(cpu_policy_rwsem, cpu)){----}, at:
> [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
> [ 3217.586023]
> [ 3217.586024] but task is already holding lock:
> [ 3217.586026]  (&cpu_hotplug.lock){--..}, at: [<c0142cec>]
> cpu_hotplug_begin+0x2f/0x89
> [ 3217.586033]
> [ 3217.586033] which lock already depends on the new lock.
> [ 3217.586035]
> [ 3217.586036]
> [ 3217.586037] the existing dependency chain (in reverse order) is:
> [ 3217.586039]
> [ 3217.586040] -> #3 (&cpu_hotplug.lock){--..}:
> [ 3217.586044]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
> [ 3217.586052]        [<c013f5c2>] lock_acquire+0x76/0x9d
> [ 3217.586058]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
> [ 3217.586066]        [<c0143038>] get_online_cpus+0x2c/0x3e
> [ 3217.586072]        [<c011eb03>] sched_getaffinity+0xe/0x4d
> [ 3217.586079]        [<c0159784>] __synchronize_sched+0x11/0x5f
> [ 3217.586087]        [<c0137380>] synchronize_srcu+0x22/0x5b
> [ 3217.586093]        [<c01376a3>] srcu_notifier_chain_unregister+0x45/0x4c
> [ 3217.586100]        [<c0277204>] cpufreq_unregister_notifier+0x1f/0x2f
> [ 3217.586107]        [<f8cfd68c>] cpufreq_governor_dbs+0x1e9/0x242
> [cpufreq_conservative]
> [ 3217.586117]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
> [ 3217.586124]        [<c0277703>] __cpufreq_set_policy+0x13f/0x1c3
> [ 3217.586130]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
> [ 3217.586137]        [<c0278708>] store+0x42/0x5b
> [ 3217.586143]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> [ 3217.586151]        [<c017dbc7>] vfs_write+0x8c/0x108
> [ 3217.586158]        [<c017e122>] sys_write+0x3b/0x60
> [ 3217.586165]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> [ 3217.586172]        [<ffffffff>] 0xffffffff
> [ 3217.586184]
> [ 3217.586185] -> #2 (&sp->mutex){--..}:
> [ 3217.586188]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
> [ 3217.586195]        [<c013f5c2>] lock_acquire+0x76/0x9d
> [ 3217.586201]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
> [ 3217.586208]        [<c0137374>] synchronize_srcu+0x16/0x5b
> [ 3217.586214]        [<c01376a3>] srcu_notifier_chain_unregister+0x45/0x4c
> [ 3217.586220]        [<c0277204>] cpufreq_unregister_notifier+0x1f/0x2f
> [ 3217.586227]        [<f8cfd68c>] cpufreq_governor_dbs+0x1e9/0x242
> [cpufreq_conservative]
> [ 3217.586235]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
> [ 3217.586242]        [<c0277703>] __cpufreq_set_policy+0x13f/0x1c3
> [ 3217.586248]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
> [ 3217.586255]        [<c0278708>] store+0x42/0x5b
> [ 3217.586261]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> [ 3217.586268]        [<c017dbc7>] vfs_write+0x8c/0x108
> [ 3217.586274]        [<c017e122>] sys_write+0x3b/0x60
> [ 3217.586280]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> [ 3217.586287]        [<ffffffff>] 0xffffffff
> [ 3217.586297]
> [ 3217.586298] -> #1 (dbs_mutex#2){--..}:
> [ 3217.586302]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
> [ 3217.586309]        [<c013f5c2>] lock_acquire+0x76/0x9d
> [ 3217.586315]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
> [ 3217.586322]        [<f8cfd511>] cpufreq_governor_dbs+0x6e/0x242
> [cpufreq_conservative]
> [ 3217.586330]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
> [ 3217.586336]        [<c0277719>] __cpufreq_set_policy+0x155/0x1c3
> [ 3217.586343]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
> [ 3217.586349]        [<c0278708>] store+0x42/0x5b
> [ 3217.586355]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> [ 3217.586362]        [<c017dbc7>] vfs_write+0x8c/0x108
> [ 3217.586369]        [<c017e122>] sys_write+0x3b/0x60
> [ 3217.586375]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> [ 3217.586381]        [<ffffffff>] 0xffffffff
> [ 3217.586451]
> [ 3217.586452] -> #0 (&per_cpu(cpu_policy_rwsem, cpu)){----}:
> [ 3217.586456]        [<c013f2c6>] __lock_acquire+0x929/0xbaf
> [ 3217.586463]        [<c013f5c2>] lock_acquire+0x76/0x9d
> [ 3217.586469]        [<c030a219>] down_write+0x28/0x44
> [ 3217.586475]        [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
> [ 3217.586482]        [<c0308abd>] cpufreq_cpu_callback+0x43/0x66
> [ 3217.586489]        [<c013753e>] notifier_call_chain+0x2b/0x4a
> [ 3217.586495]        [<c013757f>] __raw_notifier_call_chain+0xe/0x10
> [ 3217.586501]        [<c0142dde>] _cpu_down+0x71/0x1f8
> [ 3217.586507]        [<c0143094>] disable_nonboot_cpus+0x4a/0xc6
> [ 3217.586513]        [<c0146ce5>] suspend_devices_and_enter+0x6c/0x101
> [ 3217.586521]        [<c0146e8b>] enter_state+0xc4/0x119
> [ 3217.586527]        [<c0146f76>] state_store+0x96/0xac
> [ 3217.586533]        [<c01e7479>] kobj_attr_store+0x1a/0x22
> [ 3217.586541]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> [ 3217.586547]        [<c017dbc7>] vfs_write+0x8c/0x108
> [ 3217.586554]        [<c017e122>] sys_write+0x3b/0x60
> [ 3217.586560]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> [ 3217.586567]        [<ffffffff>] 0xffffffff
> [ 3217.586578]
> [ 3217.586578] other info that might help us debug this:
> [ 3217.586580]
> [ 3217.586582] 5 locks held by pm-suspend/7421:
> [ 3217.586584]  #0:  (&buffer->mutex){--..}, at: [<c01b1a36>]
> sysfs_write_file+0x25/0xe3
> [ 3217.586590]  #1:  (pm_mutex){--..}, at: [<c0146eca>] enter_state+0x103/0x119
> [ 3217.586596]  #2:  (pm_sleep_rwsem){--..}, at: [<c0261789>]
> device_suspend+0x25/0x1ad
> [ 3217.586604]  #3:  (cpu_add_remove_lock){--..}, at: [<c0142c93>]
> cpu_maps_update_begin+0xf/0x11
> [ 3217.586610]  #4:  (&cpu_hotplug.lock){--..}, at: [<c0142cec>]
> cpu_hotplug_begin+0x2f/0x89
> [ 3217.586616]
> [ 3217.586617] stack backtrace:
> [ 3217.586620] Pid: 7421, comm: pm-suspend Not tainted 2.6.25-rc9 #1
> [ 3217.586627]  [<c013d914>] print_circular_bug_tail+0x5b/0x66
> [ 3217.586634]  [<c013d25e>] ? print_circular_bug_entry+0x39/0x43
> [ 3217.586643]  [<c013f2c6>] __lock_acquire+0x929/0xbaf
> [ 3217.586656]  [<c013f5c2>] lock_acquire+0x76/0x9d
> [ 3217.586661]  [<c0277fe1>] ? lock_policy_rwsem_write+0x33/0x5a
> [ 3217.586668]  [<c030a219>] down_write+0x28/0x44
> [ 3217.586673]  [<c0277fe1>] ? lock_policy_rwsem_write+0x33/0x5a
> [ 3217.586678]  [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
> [ 3217.586684]  [<c0308abd>] cpufreq_cpu_callback+0x43/0x66
> [ 3217.586689]  [<c013753e>] notifier_call_chain+0x2b/0x4a
> [ 3217.586696]  [<c013757f>] __raw_notifier_call_chain+0xe/0x10
> [ 3217.586701]  [<c0142dde>] _cpu_down+0x71/0x1f8
> [ 3217.586710]  [<c0143094>] disable_nonboot_cpus+0x4a/0xc6
> [ 3217.586716]  [<c0146ce5>] suspend_devices_and_enter+0x6c/0x101
> [ 3217.586721]  [<c0146e8b>] enter_state+0xc4/0x119
> [ 3217.586726]  [<c0146f76>] state_store+0x96/0xac
> [ 3217.586731]  [<c0146ee0>] ? state_store+0x0/0xac
> [ 3217.586736]  [<c01e7479>] kobj_attr_store+0x1a/0x22
> [ 3217.586742]  [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> [ 3217.586750]  [<c01b1a11>] ? sysfs_write_file+0x0/0xe3
> [ 3217.586755]  [<c017dbc7>] vfs_write+0x8c/0x108
> [ 3217.586762]  [<c017e122>] sys_write+0x3b/0x60
> [ 3217.586769]  [<c0104470>] sysenter_past_esp+0x6d/0xc5
> [ 3217.586780]  =======================
> [ 3217.588064] Breaking affinity for irq 16
> --
> 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	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14  6:54 ` Peter Zijlstra
@ 2008-04-14  7:02   ` Heiko Carstens
  2008-04-14  7:18     ` Ingo Molnar
  2008-04-14 12:06   ` Peter Zijlstra
  1 sibling, 1 reply; 23+ messages in thread
From: Heiko Carstens @ 2008-04-14  7:02 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Miles Lane, LKML, Gautham Shenoy, Rafael J. Wysocki, Ingo Molnar

On Mon, Apr 14, 2008 at 08:54:05AM +0200, Peter Zijlstra wrote:
> Fun,
> 
> I will need to sort out this code before I can say anything about that,
> perhaps Gautham and or Rafael have ideas before I can come up with
> something.. ?

Why not simply removing the get/put_online_cpus() pair in sched_getaffinity?
It's superfluous since we have already a read_lock/read_unlock pair there
which does disable/enable cpu hotplug anyway.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
 kernel/sched.c |    3 ---
 1 file changed, 3 deletions(-)

Index: linux-2.6/kernel/sched.c
===================================================================
--- linux-2.6.orig/kernel/sched.c
+++ linux-2.6/kernel/sched.c
@@ -4873,7 +4873,6 @@ long sched_getaffinity(pid_t pid, cpumas
 	struct task_struct *p;
 	int retval;
 
-	get_online_cpus();
 	read_lock(&tasklist_lock);
 
 	retval = -ESRCH;
@@ -4889,8 +4888,6 @@ long sched_getaffinity(pid_t pid, cpumas
 
 out_unlock:
 	read_unlock(&tasklist_lock);
-	put_online_cpus();
-
 	return retval;
 }
 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14  7:02   ` Heiko Carstens
@ 2008-04-14  7:18     ` Ingo Molnar
  0 siblings, 0 replies; 23+ messages in thread
From: Ingo Molnar @ 2008-04-14  7:18 UTC (permalink / raw)
  To: Heiko Carstens
  Cc: Peter Zijlstra, Miles Lane, LKML, Gautham Shenoy,
	Rafael J. Wysocki, Steven Rostedt


* Heiko Carstens <heiko.carstens@de.ibm.com> wrote:

> On Mon, Apr 14, 2008 at 08:54:05AM +0200, Peter Zijlstra wrote:
> > Fun,
> > 
> > I will need to sort out this code before I can say anything about that,
> > perhaps Gautham and or Rafael have ideas before I can come up with
> > something.. ?
> 
> Why not simply removing the get/put_online_cpus() pair in 
> sched_getaffinity? It's superfluous since we have already a 
> read_lock/read_unlock pair there which does disable/enable cpu hotplug 
> anyway.

we dont want to insert such silent "preempt off == hotplug disable" 
assumptions - which assumption breaks when the tasklist_lock becomes 
preemptible (such as in -rt).

	Ingo

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14  6:54 ` Peter Zijlstra
  2008-04-14  7:02   ` Heiko Carstens
@ 2008-04-14 12:06   ` Peter Zijlstra
  2008-04-14 12:27     ` Gautham R Shenoy
  1 sibling, 1 reply; 23+ messages in thread
From: Peter Zijlstra @ 2008-04-14 12:06 UTC (permalink / raw)
  To: Miles Lane; +Cc: LKML, Gautham Shenoy, Rafael J. Wysocki, Ingo Molnar

On Mon, 2008-04-14 at 08:54 +0200, Peter Zijlstra wrote:
> Fun,
> 
> I will need to sort out this code before I can say anything about that,
> perhaps Gautham and or Rafael have ideas before I can come up with
> something.. ?
> 
> On Sun, 2008-04-13 at 23:04 -0400, Miles Lane wrote:
> > [ 3217.586003] [ INFO: possible circular locking dependency detected ]
> > [ 3217.586006] 2.6.25-rc9 #1
> > [ 3217.586008] -------------------------------------------------------
> > [ 3217.586011] pm-suspend/7421 is trying to acquire lock:
> > [ 3217.586013]  (&per_cpu(cpu_policy_rwsem, cpu)){----}, at:
> > [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
> > [ 3217.586023]
> > [ 3217.586024] but task is already holding lock:
> > [ 3217.586026]  (&cpu_hotplug.lock){--..}, at: [<c0142cec>]
> > cpu_hotplug_begin+0x2f/0x89
> > [ 3217.586033]
> > [ 3217.586033] which lock already depends on the new lock.
> > [ 3217.586035]
> > [ 3217.586036]
> > [ 3217.586037] the existing dependency chain (in reverse order) is:
> > [ 3217.586039]
> > [ 3217.586040] -> #3 (&cpu_hotplug.lock){--..}:
> > [ 3217.586044]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
> > [ 3217.586052]        [<c013f5c2>] lock_acquire+0x76/0x9d
> > [ 3217.586058]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
> > [ 3217.586066]        [<c0143038>] get_online_cpus+0x2c/0x3e
> > [ 3217.586072]        [<c011eb03>] sched_getaffinity+0xe/0x4d
> > [ 3217.586079]        [<c0159784>] __synchronize_sched+0x11/0x5f
> > [ 3217.586087]        [<c0137380>] synchronize_srcu+0x22/0x5b
> > [ 3217.586093]        [<c01376a3>] srcu_notifier_chain_unregister+0x45/0x4c
> > [ 3217.586100]        [<c0277204>] cpufreq_unregister_notifier+0x1f/0x2f
> > [ 3217.586107]        [<f8cfd68c>] cpufreq_governor_dbs+0x1e9/0x242
> > [cpufreq_conservative]
> > [ 3217.586117]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
> > [ 3217.586124]        [<c0277703>] __cpufreq_set_policy+0x13f/0x1c3
> > [ 3217.586130]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
> > [ 3217.586137]        [<c0278708>] store+0x42/0x5b
> > [ 3217.586143]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > [ 3217.586151]        [<c017dbc7>] vfs_write+0x8c/0x108
> > [ 3217.586158]        [<c017e122>] sys_write+0x3b/0x60
> > [ 3217.586165]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > [ 3217.586172]        [<ffffffff>] 0xffffffff
> > [ 3217.586184]
> > [ 3217.586185] -> #2 (&sp->mutex){--..}:
> > [ 3217.586188]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
> > [ 3217.586195]        [<c013f5c2>] lock_acquire+0x76/0x9d
> > [ 3217.586201]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
> > [ 3217.586208]        [<c0137374>] synchronize_srcu+0x16/0x5b
> > [ 3217.586214]        [<c01376a3>] srcu_notifier_chain_unregister+0x45/0x4c
> > [ 3217.586220]        [<c0277204>] cpufreq_unregister_notifier+0x1f/0x2f
> > [ 3217.586227]        [<f8cfd68c>] cpufreq_governor_dbs+0x1e9/0x242
> > [cpufreq_conservative]
> > [ 3217.586235]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
> > [ 3217.586242]        [<c0277703>] __cpufreq_set_policy+0x13f/0x1c3
> > [ 3217.586248]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
> > [ 3217.586255]        [<c0278708>] store+0x42/0x5b
> > [ 3217.586261]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > [ 3217.586268]        [<c017dbc7>] vfs_write+0x8c/0x108
> > [ 3217.586274]        [<c017e122>] sys_write+0x3b/0x60
> > [ 3217.586280]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > [ 3217.586287]        [<ffffffff>] 0xffffffff
> > [ 3217.586297]
> > [ 3217.586298] -> #1 (dbs_mutex#2){--..}:
> > [ 3217.586302]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
> > [ 3217.586309]        [<c013f5c2>] lock_acquire+0x76/0x9d
> > [ 3217.586315]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
> > [ 3217.586322]        [<f8cfd511>] cpufreq_governor_dbs+0x6e/0x242
> > [cpufreq_conservative]
> > [ 3217.586330]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
> > [ 3217.586336]        [<c0277719>] __cpufreq_set_policy+0x155/0x1c3
> > [ 3217.586343]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
> > [ 3217.586349]        [<c0278708>] store+0x42/0x5b
> > [ 3217.586355]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > [ 3217.586362]        [<c017dbc7>] vfs_write+0x8c/0x108
> > [ 3217.586369]        [<c017e122>] sys_write+0x3b/0x60
> > [ 3217.586375]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > [ 3217.586381]        [<ffffffff>] 0xffffffff
> > [ 3217.586451]
> > [ 3217.586452] -> #0 (&per_cpu(cpu_policy_rwsem, cpu)){----}:
> > [ 3217.586456]        [<c013f2c6>] __lock_acquire+0x929/0xbaf
> > [ 3217.586463]        [<c013f5c2>] lock_acquire+0x76/0x9d
> > [ 3217.586469]        [<c030a219>] down_write+0x28/0x44
> > [ 3217.586475]        [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
> > [ 3217.586482]        [<c0308abd>] cpufreq_cpu_callback+0x43/0x66
> > [ 3217.586489]        [<c013753e>] notifier_call_chain+0x2b/0x4a
> > [ 3217.586495]        [<c013757f>] __raw_notifier_call_chain+0xe/0x10
> > [ 3217.586501]        [<c0142dde>] _cpu_down+0x71/0x1f8
> > [ 3217.586507]        [<c0143094>] disable_nonboot_cpus+0x4a/0xc6
> > [ 3217.586513]        [<c0146ce5>] suspend_devices_and_enter+0x6c/0x101
> > [ 3217.586521]        [<c0146e8b>] enter_state+0xc4/0x119
> > [ 3217.586527]        [<c0146f76>] state_store+0x96/0xac
> > [ 3217.586533]        [<c01e7479>] kobj_attr_store+0x1a/0x22
> > [ 3217.586541]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > [ 3217.586547]        [<c017dbc7>] vfs_write+0x8c/0x108
> > [ 3217.586554]        [<c017e122>] sys_write+0x3b/0x60
> > [ 3217.586560]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > [ 3217.586567]        [<ffffffff>] 0xffffffff
> > [ 3217.586578]
> > [ 3217.586578] other info that might help us debug this:
> > [ 3217.586580]
> > [ 3217.586582] 5 locks held by pm-suspend/7421:
> > [ 3217.586584]  #0:  (&buffer->mutex){--..}, at: [<c01b1a36>]
> > sysfs_write_file+0x25/0xe3
> > [ 3217.586590]  #1:  (pm_mutex){--..}, at: [<c0146eca>] enter_state+0x103/0x119
> > [ 3217.586596]  #2:  (pm_sleep_rwsem){--..}, at: [<c0261789>]
> > device_suspend+0x25/0x1ad
> > [ 3217.586604]  #3:  (cpu_add_remove_lock){--..}, at: [<c0142c93>]
> > cpu_maps_update_begin+0xf/0x11
> > [ 3217.586610]  #4:  (&cpu_hotplug.lock){--..}, at: [<c0142cec>]
> > cpu_hotplug_begin+0x2f/0x89
> > [ 3217.586616]
> > [ 3217.586617] stack backtrace:
> > [ 3217.586620] Pid: 7421, comm: pm-suspend Not tainted 2.6.25-rc9 #1
> > [ 3217.586627]  [<c013d914>] print_circular_bug_tail+0x5b/0x66
> > [ 3217.586634]  [<c013d25e>] ? print_circular_bug_entry+0x39/0x43
> > [ 3217.586643]  [<c013f2c6>] __lock_acquire+0x929/0xbaf
> > [ 3217.586656]  [<c013f5c2>] lock_acquire+0x76/0x9d
> > [ 3217.586661]  [<c0277fe1>] ? lock_policy_rwsem_write+0x33/0x5a
> > [ 3217.586668]  [<c030a219>] down_write+0x28/0x44
> > [ 3217.586673]  [<c0277fe1>] ? lock_policy_rwsem_write+0x33/0x5a
> > [ 3217.586678]  [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
> > [ 3217.586684]  [<c0308abd>] cpufreq_cpu_callback+0x43/0x66
> > [ 3217.586689]  [<c013753e>] notifier_call_chain+0x2b/0x4a
> > [ 3217.586696]  [<c013757f>] __raw_notifier_call_chain+0xe/0x10
> > [ 3217.586701]  [<c0142dde>] _cpu_down+0x71/0x1f8
> > [ 3217.586710]  [<c0143094>] disable_nonboot_cpus+0x4a/0xc6
> > [ 3217.586716]  [<c0146ce5>] suspend_devices_and_enter+0x6c/0x101
> > [ 3217.586721]  [<c0146e8b>] enter_state+0xc4/0x119
> > [ 3217.586726]  [<c0146f76>] state_store+0x96/0xac
> > [ 3217.586731]  [<c0146ee0>] ? state_store+0x0/0xac
> > [ 3217.586736]  [<c01e7479>] kobj_attr_store+0x1a/0x22
> > [ 3217.586742]  [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > [ 3217.586750]  [<c01b1a11>] ? sysfs_write_file+0x0/0xe3
> > [ 3217.586755]  [<c017dbc7>] vfs_write+0x8c/0x108
> > [ 3217.586762]  [<c017e122>] sys_write+0x3b/0x60
> > [ 3217.586769]  [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > [ 3217.586780]  =======================
> > [ 3217.588064] Breaking affinity for irq 16


Ok, so cpu_hotplug has a few issues imho:

 - access to active_writer isn't serialized and thus racey
 - holding the lock over the 'write' section generates the stuff above

So basically we want a reader/writer lock, where get/put_online_cpu is
the read side and cpu_hotplug_begin/done the write side.

We want:
 - readers to recurse in readers (code excluding cpu-hotplug can
   call code needing the same).

 - readers to recurse in the writer (the code changing the state can
   call code needing a stable state)

rwlock_t isn't quite suitable because it doesn't allow reader in writer
recursion and doesn't allow sleeping.

No lockdep annotation _yet_, because current lockdep recursive reader
support is:
 - broken (have a patch for that)
 - doesn't support reader in writer recursion (will have to do something
   about that)

Ok, so aside from the obviuos disclaimers, I've only compiled this and
might have made things way too complicated - but a slightly feverish
brain does that at times. What do people think?

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 2011ad8..119d837 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -27,12 +27,13 @@ static int cpu_hotplug_disabled;
 
 static struct {
 	struct task_struct *active_writer;
-	struct mutex lock; /* Synchronizes accesses to refcount, */
+	spinlock_t lock; /* Synchronizes accesses to refcount, */
 	/*
 	 * Also blocks the new readers during
 	 * an ongoing cpu hotplug operation.
 	 */
 	int refcount;
+	wait_queue_head_t reader_queue;
 	wait_queue_head_t writer_queue;
 } cpu_hotplug;
 
@@ -41,8 +42,9 @@ static struct {
 void __init cpu_hotplug_init(void)
 {
 	cpu_hotplug.active_writer = NULL;
-	mutex_init(&cpu_hotplug.lock);
+	spin_lock_init(&cpu_hotplug.lock);
 	cpu_hotplug.refcount = 0;
+	init_waitqueue_head(&cpu_hotplug.reader_queue);
 	init_waitqueue_head(&cpu_hotplug.writer_queue);
 }
 
@@ -51,27 +53,42 @@ void __init cpu_hotplug_init(void)
 void get_online_cpus(void)
 {
 	might_sleep();
+
+	spin_lock(&cpu_hotplug.lock);
 	if (cpu_hotplug.active_writer == current)
-		return;
-	mutex_lock(&cpu_hotplug.lock);
+		goto unlock;
+
+	if (cpu_hotplug.active_writer) {
+		DEFINE_WAIT(wait);
+
+		for (;;) {
+			prepare_to_wait(&cpu_hotplug.reader_queue, &wait,
+					TASK_UNINTERRUPTIBLE);
+			if (!cpu_hotplug.active_writer)
+				break;
+			spin_unlock(&cpu_hotplug.lock);
+			schedule();
+			spin_lock(&cpu_hotplug.lock);
+		}
+		finish_wait(&cpu_hotplug.reader_queue, &wait);
+	}
 	cpu_hotplug.refcount++;
-	mutex_unlock(&cpu_hotplug.lock);
-
+ unlock:
+	spin_unlock(&cpu_hotplug.lock);
 }
 EXPORT_SYMBOL_GPL(get_online_cpus);
 
 void put_online_cpus(void)
 {
+	spin_lock(&cpu_hotplug.lock);
 	if (cpu_hotplug.active_writer == current)
-		return;
-	mutex_lock(&cpu_hotplug.lock);
-	cpu_hotplug.refcount--;
+		goto unlock;
 
-	if (unlikely(writer_exists()) && !cpu_hotplug.refcount)
+	cpu_hotplug.refcount--;
+	if (!cpu_hotplug.refcount)
 		wake_up(&cpu_hotplug.writer_queue);
-
-	mutex_unlock(&cpu_hotplug.lock);
-
+ unlock:
+	spin_unlock(&cpu_hotplug.lock);
 }
 EXPORT_SYMBOL_GPL(put_online_cpus);
 
@@ -95,45 +112,41 @@ void cpu_maps_update_done(void)
  * This ensures that the hotplug operation can begin only when the
  * refcount goes to zero.
  *
- * Note that during a cpu-hotplug operation, the new readers, if any,
- * will be blocked by the cpu_hotplug.lock
- *
- * Since cpu_maps_update_begin is always called after invoking
- * cpu_maps_update_begin, we can be sure that only one writer is active.
- *
- * Note that theoretically, there is a possibility of a livelock:
- * - Refcount goes to zero, last reader wakes up the sleeping
- *   writer.
- * - Last reader unlocks the cpu_hotplug.lock.
- * - A new reader arrives at this moment, bumps up the refcount.
- * - The writer acquires the cpu_hotplug.lock finds the refcount
- *   non zero and goes to sleep again.
- *
- * However, this is very difficult to achieve in practice since
- * get_online_cpus() not an api which is called all that often.
- *
+ * cpu_hotplug is basically an unfair recursive reader/writer lock that
+ * allows reader in writer recursion.
  */
 static void cpu_hotplug_begin(void)
 {
-	DECLARE_WAITQUEUE(wait, current);
-
-	mutex_lock(&cpu_hotplug.lock);
+	might_sleep();
 
-	cpu_hotplug.active_writer = current;
-	add_wait_queue_exclusive(&cpu_hotplug.writer_queue, &wait);
-	while (cpu_hotplug.refcount) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		mutex_unlock(&cpu_hotplug.lock);
-		schedule();
-		mutex_lock(&cpu_hotplug.lock);
+	spin_lock(&cpu_hotplug.lock);
+	if (cpu_hotplug.refcount || cpu_hotplug.active_writer) {
+		DEFINE_WAIT(wait);
+
+		for (;;) {
+			prepare_to_wait(&cpu_hotplug.writer_queue, &wait,
+					TASK_UNINTERRUPTIBLE);
+			if (!cpu_hotplug.refcount && !cpu_hotplug.active_writer)
+				break;
+			spin_unlock(&cpu_hotplug.lock);
+			schedule();
+			spin_lock(&cpu_hotplug.lock);
+		}
+		finish_wait(&cpu_hotplug.writer_queue, &wait);
 	}
-	remove_wait_queue_locked(&cpu_hotplug.writer_queue, &wait);
+	cpu_hotplug.active_writer = current;
+	spin_unlock(&cpu_hotplug.lock);
 }
 
 static void cpu_hotplug_done(void)
 {
+	spin_lock(&cpu_hotplug.lock);
 	cpu_hotplug.active_writer = NULL;
-	mutex_unlock(&cpu_hotplug.lock);
+	if (!list_empty(&cpu_hotplug.writer_queue.task_list))
+		wake_up(&cpu_hotplug.writer_queue);
+	else
+		wake_up_all(&cpu_hotplug.reader_queue);
+	spin_unlock(&cpu_hotplug.lock);
 }
 /* Need to know about CPUs going up/down? */
 int __cpuinit register_cpu_notifier(struct notifier_block *nb)



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14 12:06   ` Peter Zijlstra
@ 2008-04-14 12:27     ` Gautham R Shenoy
  2008-04-14 12:42       ` Peter Zijlstra
  0 siblings, 1 reply; 23+ messages in thread
From: Gautham R Shenoy @ 2008-04-14 12:27 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Miles Lane, LKML, Rafael J. Wysocki, Ingo Molnar

On Mon, Apr 14, 2008 at 02:06:07PM +0200, Peter Zijlstra wrote:
> On Mon, 2008-04-14 at 08:54 +0200, Peter Zijlstra wrote:
> > Fun,
> > 
> > I will need to sort out this code before I can say anything about that,
> > perhaps Gautham and or Rafael have ideas before I can come up with
> > something.. ?
> > 
> > On Sun, 2008-04-13 at 23:04 -0400, Miles Lane wrote:
> > > [ 3217.586003] [ INFO: possible circular locking dependency detected ]
> > > [ 3217.586006] 2.6.25-rc9 #1
> > > [ 3217.586008] -------------------------------------------------------
> > > [ 3217.586011] pm-suspend/7421 is trying to acquire lock:
> > > [ 3217.586013]  (&per_cpu(cpu_policy_rwsem, cpu)){----}, at:
> > > [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
> > > [ 3217.586023]
> > > [ 3217.586024] but task is already holding lock:
> > > [ 3217.586026]  (&cpu_hotplug.lock){--..}, at: [<c0142cec>]
> > > cpu_hotplug_begin+0x2f/0x89
> > > [ 3217.586033]
> > > [ 3217.586033] which lock already depends on the new lock.
> > > [ 3217.586035]
> > > [ 3217.586036]
> > > [ 3217.586037] the existing dependency chain (in reverse order) is:
> > > [ 3217.586039]
> > > [ 3217.586040] -> #3 (&cpu_hotplug.lock){--..}:
> > > [ 3217.586044]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
> > > [ 3217.586052]        [<c013f5c2>] lock_acquire+0x76/0x9d
> > > [ 3217.586058]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
> > > [ 3217.586066]        [<c0143038>] get_online_cpus+0x2c/0x3e
> > > [ 3217.586072]        [<c011eb03>] sched_getaffinity+0xe/0x4d
> > > [ 3217.586079]        [<c0159784>] __synchronize_sched+0x11/0x5f
> > > [ 3217.586087]        [<c0137380>] synchronize_srcu+0x22/0x5b
> > > [ 3217.586093]        [<c01376a3>] srcu_notifier_chain_unregister+0x45/0x4c
> > > [ 3217.586100]        [<c0277204>] cpufreq_unregister_notifier+0x1f/0x2f
> > > [ 3217.586107]        [<f8cfd68c>] cpufreq_governor_dbs+0x1e9/0x242
> > > [cpufreq_conservative]
> > > [ 3217.586117]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
> > > [ 3217.586124]        [<c0277703>] __cpufreq_set_policy+0x13f/0x1c3
> > > [ 3217.586130]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
> > > [ 3217.586137]        [<c0278708>] store+0x42/0x5b
> > > [ 3217.586143]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > > [ 3217.586151]        [<c017dbc7>] vfs_write+0x8c/0x108
> > > [ 3217.586158]        [<c017e122>] sys_write+0x3b/0x60
> > > [ 3217.586165]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > > [ 3217.586172]        [<ffffffff>] 0xffffffff
> > > [ 3217.586184]
> > > [ 3217.586185] -> #2 (&sp->mutex){--..}:
> > > [ 3217.586188]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
> > > [ 3217.586195]        [<c013f5c2>] lock_acquire+0x76/0x9d
> > > [ 3217.586201]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
> > > [ 3217.586208]        [<c0137374>] synchronize_srcu+0x16/0x5b
> > > [ 3217.586214]        [<c01376a3>] srcu_notifier_chain_unregister+0x45/0x4c
> > > [ 3217.586220]        [<c0277204>] cpufreq_unregister_notifier+0x1f/0x2f
> > > [ 3217.586227]        [<f8cfd68c>] cpufreq_governor_dbs+0x1e9/0x242
> > > [cpufreq_conservative]
> > > [ 3217.586235]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
> > > [ 3217.586242]        [<c0277703>] __cpufreq_set_policy+0x13f/0x1c3
> > > [ 3217.586248]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
> > > [ 3217.586255]        [<c0278708>] store+0x42/0x5b
> > > [ 3217.586261]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > > [ 3217.586268]        [<c017dbc7>] vfs_write+0x8c/0x108
> > > [ 3217.586274]        [<c017e122>] sys_write+0x3b/0x60
> > > [ 3217.586280]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > > [ 3217.586287]        [<ffffffff>] 0xffffffff
> > > [ 3217.586297]
> > > [ 3217.586298] -> #1 (dbs_mutex#2){--..}:
> > > [ 3217.586302]        [<c013f39f>] __lock_acquire+0xa02/0xbaf
> > > [ 3217.586309]        [<c013f5c2>] lock_acquire+0x76/0x9d
> > > [ 3217.586315]        [<c0309c17>] mutex_lock_nested+0xd5/0x274
> > > [ 3217.586322]        [<f8cfd511>] cpufreq_governor_dbs+0x6e/0x242
> > > [cpufreq_conservative]
> > > [ 3217.586330]        [<c027758d>] __cpufreq_governor+0xb2/0xe9
> > > [ 3217.586336]        [<c0277719>] __cpufreq_set_policy+0x155/0x1c3
> > > [ 3217.586343]        [<c0277bf3>] store_scaling_governor+0x150/0x17f
> > > [ 3217.586349]        [<c0278708>] store+0x42/0x5b
> > > [ 3217.586355]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > > [ 3217.586362]        [<c017dbc7>] vfs_write+0x8c/0x108
> > > [ 3217.586369]        [<c017e122>] sys_write+0x3b/0x60
> > > [ 3217.586375]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > > [ 3217.586381]        [<ffffffff>] 0xffffffff
> > > [ 3217.586451]
> > > [ 3217.586452] -> #0 (&per_cpu(cpu_policy_rwsem, cpu)){----}:
> > > [ 3217.586456]        [<c013f2c6>] __lock_acquire+0x929/0xbaf
> > > [ 3217.586463]        [<c013f5c2>] lock_acquire+0x76/0x9d
> > > [ 3217.586469]        [<c030a219>] down_write+0x28/0x44
> > > [ 3217.586475]        [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
> > > [ 3217.586482]        [<c0308abd>] cpufreq_cpu_callback+0x43/0x66
> > > [ 3217.586489]        [<c013753e>] notifier_call_chain+0x2b/0x4a
> > > [ 3217.586495]        [<c013757f>] __raw_notifier_call_chain+0xe/0x10
> > > [ 3217.586501]        [<c0142dde>] _cpu_down+0x71/0x1f8
> > > [ 3217.586507]        [<c0143094>] disable_nonboot_cpus+0x4a/0xc6
> > > [ 3217.586513]        [<c0146ce5>] suspend_devices_and_enter+0x6c/0x101
> > > [ 3217.586521]        [<c0146e8b>] enter_state+0xc4/0x119
> > > [ 3217.586527]        [<c0146f76>] state_store+0x96/0xac
> > > [ 3217.586533]        [<c01e7479>] kobj_attr_store+0x1a/0x22
> > > [ 3217.586541]        [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > > [ 3217.586547]        [<c017dbc7>] vfs_write+0x8c/0x108
> > > [ 3217.586554]        [<c017e122>] sys_write+0x3b/0x60
> > > [ 3217.586560]        [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > > [ 3217.586567]        [<ffffffff>] 0xffffffff
> > > [ 3217.586578]
> > > [ 3217.586578] other info that might help us debug this:
> > > [ 3217.586580]
> > > [ 3217.586582] 5 locks held by pm-suspend/7421:
> > > [ 3217.586584]  #0:  (&buffer->mutex){--..}, at: [<c01b1a36>]
> > > sysfs_write_file+0x25/0xe3
> > > [ 3217.586590]  #1:  (pm_mutex){--..}, at: [<c0146eca>] enter_state+0x103/0x119
> > > [ 3217.586596]  #2:  (pm_sleep_rwsem){--..}, at: [<c0261789>]
> > > device_suspend+0x25/0x1ad
> > > [ 3217.586604]  #3:  (cpu_add_remove_lock){--..}, at: [<c0142c93>]
> > > cpu_maps_update_begin+0xf/0x11
> > > [ 3217.586610]  #4:  (&cpu_hotplug.lock){--..}, at: [<c0142cec>]
> > > cpu_hotplug_begin+0x2f/0x89
> > > [ 3217.586616]
> > > [ 3217.586617] stack backtrace:
> > > [ 3217.586620] Pid: 7421, comm: pm-suspend Not tainted 2.6.25-rc9 #1
> > > [ 3217.586627]  [<c013d914>] print_circular_bug_tail+0x5b/0x66
> > > [ 3217.586634]  [<c013d25e>] ? print_circular_bug_entry+0x39/0x43
> > > [ 3217.586643]  [<c013f2c6>] __lock_acquire+0x929/0xbaf
> > > [ 3217.586656]  [<c013f5c2>] lock_acquire+0x76/0x9d
> > > [ 3217.586661]  [<c0277fe1>] ? lock_policy_rwsem_write+0x33/0x5a
> > > [ 3217.586668]  [<c030a219>] down_write+0x28/0x44
> > > [ 3217.586673]  [<c0277fe1>] ? lock_policy_rwsem_write+0x33/0x5a
> > > [ 3217.586678]  [<c0277fe1>] lock_policy_rwsem_write+0x33/0x5a
> > > [ 3217.586684]  [<c0308abd>] cpufreq_cpu_callback+0x43/0x66
> > > [ 3217.586689]  [<c013753e>] notifier_call_chain+0x2b/0x4a
> > > [ 3217.586696]  [<c013757f>] __raw_notifier_call_chain+0xe/0x10
> > > [ 3217.586701]  [<c0142dde>] _cpu_down+0x71/0x1f8
> > > [ 3217.586710]  [<c0143094>] disable_nonboot_cpus+0x4a/0xc6
> > > [ 3217.586716]  [<c0146ce5>] suspend_devices_and_enter+0x6c/0x101
> > > [ 3217.586721]  [<c0146e8b>] enter_state+0xc4/0x119
> > > [ 3217.586726]  [<c0146f76>] state_store+0x96/0xac
> > > [ 3217.586731]  [<c0146ee0>] ? state_store+0x0/0xac
> > > [ 3217.586736]  [<c01e7479>] kobj_attr_store+0x1a/0x22
> > > [ 3217.586742]  [<c01b1ac9>] sysfs_write_file+0xb8/0xe3
> > > [ 3217.586750]  [<c01b1a11>] ? sysfs_write_file+0x0/0xe3
> > > [ 3217.586755]  [<c017dbc7>] vfs_write+0x8c/0x108
> > > [ 3217.586762]  [<c017e122>] sys_write+0x3b/0x60
> > > [ 3217.586769]  [<c0104470>] sysenter_past_esp+0x6d/0xc5
> > > [ 3217.586780]  =======================
> > > [ 3217.588064] Breaking affinity for irq 16
> 
> 
> Ok, so cpu_hotplug has a few issues imho:
> 
>  - access to active_writer isn't serialized and thus racey
>  - holding the lock over the 'write' section generates the stuff above
> 
> So basically we want a reader/writer lock, where get/put_online_cpu is
> the read side and cpu_hotplug_begin/done the write side.
> 
> We want:
>  - readers to recurse in readers (code excluding cpu-hotplug can
>    call code needing the same).
> 
>  - readers to recurse in the writer (the code changing the state can
>    call code needing a stable state)
> 
> rwlock_t isn't quite suitable because it doesn't allow reader in writer
> recursion and doesn't allow sleeping.
> 
> No lockdep annotation _yet_, because current lockdep recursive reader
> support is:
>  - broken (have a patch for that)
>  - doesn't support reader in writer recursion (will have to do something
>    about that)
> 
> Ok, so aside from the obviuos disclaimers, I've only compiled this and
> might have made things way too complicated - but a slightly feverish
> brain does that at times. What do people think?

You beat me to it! 

I just whipped up a similar patch, with slight differences, and lockdep
annotations :)

comments below

> 
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
> diff --git a/kernel/cpu.c b/kernel/cpu.c
> index 2011ad8..119d837 100644
> --- a/kernel/cpu.c
> +++ b/kernel/cpu.c
> @@ -27,12 +27,13 @@ static int cpu_hotplug_disabled;
> 
>  static struct {
>  	struct task_struct *active_writer;
> -	struct mutex lock; /* Synchronizes accesses to refcount, */
> +	spinlock_t lock; /* Synchronizes accesses to refcount, */
>  	/*
>  	 * Also blocks the new readers during
>  	 * an ongoing cpu hotplug operation.
>  	 */
>  	int refcount;
> +	wait_queue_head_t reader_queue;
>  	wait_queue_head_t writer_queue;
>  } cpu_hotplug;
> 
> @@ -41,8 +42,9 @@ static struct {
>  void __init cpu_hotplug_init(void)
>  {
>  	cpu_hotplug.active_writer = NULL;
> -	mutex_init(&cpu_hotplug.lock);
> +	spin_lock_init(&cpu_hotplug.lock);
>  	cpu_hotplug.refcount = 0;
> +	init_waitqueue_head(&cpu_hotplug.reader_queue);
>  	init_waitqueue_head(&cpu_hotplug.writer_queue);
>  }
> 
> @@ -51,27 +53,42 @@ void __init cpu_hotplug_init(void)
>  void get_online_cpus(void)
>  {
>  	might_sleep();
> +
> +	spin_lock(&cpu_hotplug.lock);
>  	if (cpu_hotplug.active_writer == current)
> -		return;
We don't need to perform this check holding the spinlock.
The reason being, this check should succeed only for get_online_cpus()
invoked from the CPU-hotplug callback path. and by that time,
the writer thread would have set active_writer to it's task struct
value.

For every other thread, when it's trying to check if it is the
active_writer, the value is either NULL, or the value of the currently
active writer's task_struct, but never current.

Am I missing something ?

	
> -	mutex_lock(&cpu_hotplug.lock);
> +		goto unlock;
> +
> +	if (cpu_hotplug.active_writer) {
> +		DEFINE_WAIT(wait);
> +
> +		for (;;) {
> +			prepare_to_wait(&cpu_hotplug.reader_queue, &wait,
> +					TASK_UNINTERRUPTIBLE);
> +			if (!cpu_hotplug.active_writer)
> +				break;
> +			spin_unlock(&cpu_hotplug.lock);
> +			schedule();
> +			spin_lock(&cpu_hotplug.lock);
> +		}
> +		finish_wait(&cpu_hotplug.reader_queue, &wait);
> +	}
>  	cpu_hotplug.refcount++;
> -	mutex_unlock(&cpu_hotplug.lock);
> -
> + unlock:
> +	spin_unlock(&cpu_hotplug.lock);
>  }
>  EXPORT_SYMBOL_GPL(get_online_cpus);
> 
>  void put_online_cpus(void)
>  {
> +	spin_lock(&cpu_hotplug.lock);
>  	if (cpu_hotplug.active_writer == current)
> -		return;

ditto!

> -	mutex_lock(&cpu_hotplug.lock);
> -	cpu_hotplug.refcount--;
> +		goto unlock;
> 
> -	if (unlikely(writer_exists()) && !cpu_hotplug.refcount)
> +	cpu_hotplug.refcount--;
> +	if (!cpu_hotplug.refcount)
>  		wake_up(&cpu_hotplug.writer_queue);
	hmm.. when there is no active writer, can't we avoid this
	additional wake up ??
> -
> -	mutex_unlock(&cpu_hotplug.lock);
> -
> + unlock:
> +	spin_unlock(&cpu_hotplug.lock);
>  }
>  EXPORT_SYMBOL_GPL(put_online_cpus);
> 
> @@ -95,45 +112,41 @@ void cpu_maps_update_done(void)
>   * This ensures that the hotplug operation can begin only when the
>   * refcount goes to zero.
>   *
> - * Note that during a cpu-hotplug operation, the new readers, if any,
> - * will be blocked by the cpu_hotplug.lock
> - *
> - * Since cpu_maps_update_begin is always called after invoking
> - * cpu_maps_update_begin, we can be sure that only one writer is active.
> - *
> - * Note that theoretically, there is a possibility of a livelock:
> - * - Refcount goes to zero, last reader wakes up the sleeping
> - *   writer.
> - * - Last reader unlocks the cpu_hotplug.lock.
> - * - A new reader arrives at this moment, bumps up the refcount.
> - * - The writer acquires the cpu_hotplug.lock finds the refcount
> - *   non zero and goes to sleep again.
> - *
> - * However, this is very difficult to achieve in practice since
> - * get_online_cpus() not an api which is called all that often.
> - *
> + * cpu_hotplug is basically an unfair recursive reader/writer lock that
> + * allows reader in writer recursion.
>   */
>  static void cpu_hotplug_begin(void)
>  {
> -	DECLARE_WAITQUEUE(wait, current);
> -
> -	mutex_lock(&cpu_hotplug.lock);
> +	might_sleep();
> 
> -	cpu_hotplug.active_writer = current;
> -	add_wait_queue_exclusive(&cpu_hotplug.writer_queue, &wait);
> -	while (cpu_hotplug.refcount) {
> -		set_current_state(TASK_UNINTERRUPTIBLE);
> -		mutex_unlock(&cpu_hotplug.lock);
> -		schedule();
> -		mutex_lock(&cpu_hotplug.lock);
> +	spin_lock(&cpu_hotplug.lock);
> +	if (cpu_hotplug.refcount || cpu_hotplug.active_writer) {
	if we reach this point, there can be only one writer, i.e.
	ourselves!

	Because, the other writers are serialized by the
	cpu_add_remove_lock in cpu_up()/cpu_down().

	Hence we can safely assign cpu_hotplug.active_writer to current.


> +		DEFINE_WAIT(wait);
> +
> +		for (;;) {
> +			prepare_to_wait(&cpu_hotplug.writer_queue, &wait,
> +					TASK_UNINTERRUPTIBLE);
> +			if (!cpu_hotplug.refcount && !cpu_hotplug.active_writer)
> +				break;
> +			spin_unlock(&cpu_hotplug.lock);
> +			schedule();
> +			spin_lock(&cpu_hotplug.lock);
> +		}
> +		finish_wait(&cpu_hotplug.writer_queue, &wait);
>  	}
> -	remove_wait_queue_locked(&cpu_hotplug.writer_queue, &wait);
> +	cpu_hotplug.active_writer = current;


> +	spin_unlock(&cpu_hotplug.lock);
>  }
> 
>  static void cpu_hotplug_done(void)
>  {
> +	spin_lock(&cpu_hotplug.lock);
>  	cpu_hotplug.active_writer = NULL;
> -	mutex_unlock(&cpu_hotplug.lock);
> +	if (!list_empty(&cpu_hotplug.writer_queue.task_list))
> +		wake_up(&cpu_hotplug.writer_queue);
> +	else
> +		wake_up_all(&cpu_hotplug.reader_queue);
> +	spin_unlock(&cpu_hotplug.lock);
>  }
>  /* Need to know about CPUs going up/down? */
>  int __cpuinit register_cpu_notifier(struct notifier_block *nb)
>

Looks good otherwise!

--
Thanks and Regards
gautham

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14 12:27     ` Gautham R Shenoy
@ 2008-04-14 12:42       ` Peter Zijlstra
  2008-04-14 13:28         ` Gautham R Shenoy
                           ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Peter Zijlstra @ 2008-04-14 12:42 UTC (permalink / raw)
  To: ego; +Cc: Miles Lane, LKML, Rafael J. Wysocki, Ingo Molnar

On Mon, 2008-04-14 at 17:57 +0530, Gautham R Shenoy wrote:

> > Ok, so cpu_hotplug has a few issues imho:
> > 
> >  - access to active_writer isn't serialized and thus racey
> >  - holding the lock over the 'write' section generates the stuff above
> > 
> > So basically we want a reader/writer lock, where get/put_online_cpu is
> > the read side and cpu_hotplug_begin/done the write side.
> > 
> > We want:
> >  - readers to recurse in readers (code excluding cpu-hotplug can
> >    call code needing the same).
> > 
> >  - readers to recurse in the writer (the code changing the state can
> >    call code needing a stable state)
> > 
> > rwlock_t isn't quite suitable because it doesn't allow reader in writer
> > recursion and doesn't allow sleeping.
> > 
> > No lockdep annotation _yet_, because current lockdep recursive reader
> > support is:
> >  - broken (have a patch for that)
> >  - doesn't support reader in writer recursion (will have to do something
> >    about that)
> > 
> > Ok, so aside from the obviuos disclaimers, I've only compiled this and
> > might have made things way too complicated - but a slightly feverish
> > brain does that at times. What do people think?
> 
> You beat me to it! 
> 
> I just whipped up a similar patch, with slight differences, and lockdep
> annotations :)

lockdep doesn't quite acecpt reader in writer recursion without a little
patch like so:

(fold of two patches - one fixing the recursion another adding
reader-writer recursion)

cpu_hotplug should use 3.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
Index: linux-2.6-2/kernel/lockdep.c
===================================================================
--- linux-2.6-2.orig/kernel/lockdep.c
+++ linux-2.6-2/kernel/lockdep.c
@@ -1281,6 +1281,13 @@ check_deadlock(struct task_struct *curr,
 		 */
 		if ((read == 2) && prev->read)
 			return 2;
+		/*
+		 * Allow read-after-write recursion of the same
+		 * lock class (i.e. write_lock(lock)+read_lock(lock)):
+		 */
+		if (read == 3)
+			return 2;
+
 		return print_deadlock_bug(curr, prev, next);
 	}
 	return 1;
@@ -1557,12 +1564,11 @@ static int validate_chain(struct task_st
 		if (!ret)
 			return 0;
 		/*
-		 * Mark recursive read, as we jump over it when
-		 * building dependencies (just like we jump over
-		 * trylock entries):
+		 * If we are the first recursive read, don't jump over our
+		 * dependency.
 		 */
-		if (ret == 2)
-			hlock->read = 2;
+		if (hlock->read >= 2 && ret != 2)
+			hlock->read = 1;
 		/*
 		 * Add dependency only if this lock is not the head
 		 * of the chain, and if it's not a secondary read-lock:
Index: linux-2.6-2/lib/locking-selftest.c
===================================================================
--- linux-2.6-2.orig/lib/locking-selftest.c
+++ linux-2.6-2/lib/locking-selftest.c
@@ -1135,12 +1135,12 @@ void locking_selftest(void)
 	debug_locks_silent = !debug_locks_verbose;
 
 	DO_TESTCASE_6R("A-A deadlock", AA);
-	DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
-	DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
-	DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
-	DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
-	DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
-	DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
+	DO_TESTCASE_6("A-B-B-A deadlock", ABBA);
+	DO_TESTCASE_6("A-B-B-C-C-A deadlock", ABBCCA);
+	DO_TESTCASE_6("A-B-C-A-B-C deadlock", ABCABC);
+	DO_TESTCASE_6("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
+	DO_TESTCASE_6("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
+	DO_TESTCASE_6("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
 	DO_TESTCASE_6("double unlock", double_unlock);
 	DO_TESTCASE_6("initialize held", init_held);
 	DO_TESTCASE_6_SUCCESS("bad unlock order", bad_unlock_order);
Index: linux-2.6-2/include/linux/lockdep.h
===================================================================
--- linux-2.6-2.orig/include/linux/lockdep.h
+++ linux-2.6-2/include/linux/lockdep.h
@@ -291,6 +291,7 @@ extern void lockdep_init_map(struct lock
  *   0: exclusive (write) acquire
  *   1: read-acquire (no recursion allowed)
  *   2: read-acquire with same-instance recursion allowed
+ *   3: 2 + reader in writer recursion
  *
  * Values for check:
  *

> comments below
> 
> > 
> > Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > ---
> > diff --git a/kernel/cpu.c b/kernel/cpu.c
> > index 2011ad8..119d837 100644
> > --- a/kernel/cpu.c
> > +++ b/kernel/cpu.c
> > @@ -27,12 +27,13 @@ static int cpu_hotplug_disabled;
> > 
> >  static struct {
> >  	struct task_struct *active_writer;
> > -	struct mutex lock; /* Synchronizes accesses to refcount, */
> > +	spinlock_t lock; /* Synchronizes accesses to refcount, */
> >  	/*
> >  	 * Also blocks the new readers during
> >  	 * an ongoing cpu hotplug operation.
> >  	 */
> >  	int refcount;
> > +	wait_queue_head_t reader_queue;
> >  	wait_queue_head_t writer_queue;
> >  } cpu_hotplug;
> > 
> > @@ -41,8 +42,9 @@ static struct {
> >  void __init cpu_hotplug_init(void)
> >  {
> >  	cpu_hotplug.active_writer = NULL;
> > -	mutex_init(&cpu_hotplug.lock);
> > +	spin_lock_init(&cpu_hotplug.lock);
> >  	cpu_hotplug.refcount = 0;
> > +	init_waitqueue_head(&cpu_hotplug.reader_queue);
> >  	init_waitqueue_head(&cpu_hotplug.writer_queue);
> >  }
> > 
> > @@ -51,27 +53,42 @@ void __init cpu_hotplug_init(void)
> >  void get_online_cpus(void)
> >  {
> >  	might_sleep();
> > +
> > +	spin_lock(&cpu_hotplug.lock);
> >  	if (cpu_hotplug.active_writer == current)
> > -		return;
> We don't need to perform this check holding the spinlock.
> The reason being, this check should succeed only for get_online_cpus()
> invoked from the CPU-hotplug callback path. and by that time,
> the writer thread would have set active_writer to it's task struct
> value.
> 
> For every other thread, when it's trying to check if it is the
> active_writer, the value is either NULL, or the value of the currently
> active writer's task_struct, but never current.
> 
> Am I missing something ?

I guess you're right - inside makes me feel better though :-) And its
not like its a fast path or something like that.

> > -	mutex_lock(&cpu_hotplug.lock);
> > +		goto unlock;
> > +
> > +	if (cpu_hotplug.active_writer) {
> > +		DEFINE_WAIT(wait);
> > +
> > +		for (;;) {
> > +			prepare_to_wait(&cpu_hotplug.reader_queue, &wait,
> > +					TASK_UNINTERRUPTIBLE);
> > +			if (!cpu_hotplug.active_writer)
> > +				break;
> > +			spin_unlock(&cpu_hotplug.lock);
> > +			schedule();
> > +			spin_lock(&cpu_hotplug.lock);
> > +		}
> > +		finish_wait(&cpu_hotplug.reader_queue, &wait);
> > +	}
> >  	cpu_hotplug.refcount++;
> > -	mutex_unlock(&cpu_hotplug.lock);
> > -
> > + unlock:
> > +	spin_unlock(&cpu_hotplug.lock);
> >  }
> >  EXPORT_SYMBOL_GPL(get_online_cpus);
> > 
> >  void put_online_cpus(void)
> >  {
> > +	spin_lock(&cpu_hotplug.lock);
> >  	if (cpu_hotplug.active_writer == current)
> > -		return;
> 
> ditto!
> 
> > -	mutex_lock(&cpu_hotplug.lock);
> > -	cpu_hotplug.refcount--;
> > +		goto unlock;
> > 
> > -	if (unlikely(writer_exists()) && !cpu_hotplug.refcount)
> > +	cpu_hotplug.refcount--;
> > +	if (!cpu_hotplug.refcount)
> >  		wake_up(&cpu_hotplug.writer_queue);
> 	hmm.. when there is no active writer, can't we avoid this
> 	additional wake up ??
> > -
> > -	mutex_unlock(&cpu_hotplug.lock);
> > -
> > + unlock:
> > +	spin_unlock(&cpu_hotplug.lock);
> >  }
> >  EXPORT_SYMBOL_GPL(put_online_cpus);
> > 
> > @@ -95,45 +112,41 @@ void cpu_maps_update_done(void)
> >   * This ensures that the hotplug operation can begin only when the
> >   * refcount goes to zero.
> >   *
> > - * Note that during a cpu-hotplug operation, the new readers, if any,
> > - * will be blocked by the cpu_hotplug.lock
> > - *
> > - * Since cpu_maps_update_begin is always called after invoking
> > - * cpu_maps_update_begin, we can be sure that only one writer is active.
> > - *
> > - * Note that theoretically, there is a possibility of a livelock:
> > - * - Refcount goes to zero, last reader wakes up the sleeping
> > - *   writer.
> > - * - Last reader unlocks the cpu_hotplug.lock.
> > - * - A new reader arrives at this moment, bumps up the refcount.
> > - * - The writer acquires the cpu_hotplug.lock finds the refcount
> > - *   non zero and goes to sleep again.
> > - *
> > - * However, this is very difficult to achieve in practice since
> > - * get_online_cpus() not an api which is called all that often.
> > - *
> > + * cpu_hotplug is basically an unfair recursive reader/writer lock that
> > + * allows reader in writer recursion.
> >   */
> >  static void cpu_hotplug_begin(void)
> >  {
> > -	DECLARE_WAITQUEUE(wait, current);
> > -
> > -	mutex_lock(&cpu_hotplug.lock);
> > +	might_sleep();
> > 
> > -	cpu_hotplug.active_writer = current;
> > -	add_wait_queue_exclusive(&cpu_hotplug.writer_queue, &wait);
> > -	while (cpu_hotplug.refcount) {
> > -		set_current_state(TASK_UNINTERRUPTIBLE);
> > -		mutex_unlock(&cpu_hotplug.lock);
> > -		schedule();
> > -		mutex_lock(&cpu_hotplug.lock);
> > +	spin_lock(&cpu_hotplug.lock);
> > +	if (cpu_hotplug.refcount || cpu_hotplug.active_writer) {
> 	if we reach this point, there can be only one writer, i.e.
> 	ourselves!
> 
> 	Because, the other writers are serialized by the
> 	cpu_add_remove_lock in cpu_up()/cpu_down().
> 
> 	Hence we can safely assign cpu_hotplug.active_writer to current.

Ah, missed that. Does it make sense to keep it like this, in case this
outer lock goes away?

> > +		DEFINE_WAIT(wait);
> > +
> > +		for (;;) {
> > +			prepare_to_wait(&cpu_hotplug.writer_queue, &wait,
> > +					TASK_UNINTERRUPTIBLE);
> > +			if (!cpu_hotplug.refcount && !cpu_hotplug.active_writer)
> > +				break;
> > +			spin_unlock(&cpu_hotplug.lock);
> > +			schedule();
> > +			spin_lock(&cpu_hotplug.lock);
> > +		}
> > +		finish_wait(&cpu_hotplug.writer_queue, &wait);
> >  	}
> > -	remove_wait_queue_locked(&cpu_hotplug.writer_queue, &wait);
> > +	cpu_hotplug.active_writer = current;
> 
> 
> > +	spin_unlock(&cpu_hotplug.lock);
> >  }
> > 
> >  static void cpu_hotplug_done(void)
> >  {
> > +	spin_lock(&cpu_hotplug.lock);
> >  	cpu_hotplug.active_writer = NULL;
> > -	mutex_unlock(&cpu_hotplug.lock);
> > +	if (!list_empty(&cpu_hotplug.writer_queue.task_list))
> > +		wake_up(&cpu_hotplug.writer_queue);
> > +	else
> > +		wake_up_all(&cpu_hotplug.reader_queue);
> > +	spin_unlock(&cpu_hotplug.lock);
> >  }
> >  /* Need to know about CPUs going up/down? */
> >  int __cpuinit register_cpu_notifier(struct notifier_block *nb)
> >
> 
> Looks good otherwise!

Thanks..

lockdep annotations:

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
Index: linux-2.6-2/include/linux/lockdep.h
===================================================================
--- linux-2.6-2.orig/include/linux/lockdep.h
+++ linux-2.6-2/include/linux/lockdep.h
@@ -458,4 +458,19 @@ static inline void print_irqtrace_events
 # define rwsem_release(l, n, i)			do { } while (0)
 #endif
 
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# ifdef CONFIG_PROVE_LOCKING
+#  define cpu_hotplug_acquire(l, s, t, i)	lock_acquire(l, s, t, 0, 2,
i)
+#  define cpu_hotplug_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 3,
2, i)
+# else
+#  define cpu_hotplug_acquire(l, s, t, i)	lock_acquire(l, s, t, 0, 1,
i)
+#  define cpu_hotplug_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 3,
1, i)
+# endif
+# define cpu_hotplug_release(l, n, i)		lock_release(l, n, i)
+#else
+# define cpu_hotplug_acquire(l, s, t, i)	do { } while (0)
+# define cpu_hotplug_acquire_read(l, s, t, i)	do { } while (0)
+# define cpu_hotplug_release(l, n, i)		do { } while (0)
+#endif
+
 #endif /* __LINUX_LOCKDEP_H */
Index: linux-2.6-2/kernel/cpu.c
===================================================================
--- linux-2.6-2.orig/kernel/cpu.c
+++ linux-2.6-2/kernel/cpu.c
@@ -35,12 +35,20 @@ static struct {
 	int refcount;
 	wait_queue_head_t reader_queue;
 	wait_queue_head_t writer_queue;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	struct lockdep_map	dep_map;
+#endif
 } cpu_hotplug;
 
 #define writer_exists() (cpu_hotplug.active_writer != NULL)
 
 void __init cpu_hotplug_init(void)
 {
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	static struct lockdep_class_key __key;
+
+	lockdep_init_map(&cpu_hotplug.dep_map, "cpu_hotplug", &__key, 0);
+#endif
 	cpu_hotplug.active_writer = NULL;
 	spin_lock_init(&cpu_hotplug.lock);
 	cpu_hotplug.refcount = 0;
@@ -54,6 +62,8 @@ void get_online_cpus(void)
 {
 	might_sleep();
 
+	cpu_hotplug_acquire_read(&cpu_hotplug.dep_map, 0, 0, _THIS_IP_);
+
 	spin_lock(&cpu_hotplug.lock);
 	if (cpu_hotplug.active_writer == current)
 		goto unlock;
@@ -80,6 +90,8 @@ EXPORT_SYMBOL_GPL(get_online_cpus);
 
 void put_online_cpus(void)
 {
+	cpu_hotplug_release(&cpu_hotplug.lock, 1, _THIS_IP_);
+
 	spin_lock(&cpu_hotplug.lock);
 	if (cpu_hotplug.active_writer == current)
 		goto unlock;
@@ -119,6 +131,8 @@ static void cpu_hotplug_begin(void)
 {
 	might_sleep();
 
+	cpu_hotplug_acquire(&cpu_hotplug.dep_map, 0, 0, _THIS_IP_);
+
 	spin_lock(&cpu_hotplug.lock);
 	if (cpu_hotplug.refcount || cpu_hotplug.active_writer) {
 		DEFINE_WAIT(wait);
@@ -140,6 +154,8 @@ static void cpu_hotplug_begin(void)
 
 static void cpu_hotplug_done(void)
 {
+	cpu_hotplug_release(&cpu_hotplug.lock, 1, _THIS_IP_);
+
 	spin_lock(&cpu_hotplug.lock);
 	cpu_hotplug.active_writer = NULL;
 	if (!list_empty(&cpu_hotplug.writer_queue.task_list))



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14 12:42       ` Peter Zijlstra
@ 2008-04-14 13:28         ` Gautham R Shenoy
  2008-04-14 14:48         ` Gautham R Shenoy
       [not found]         ` <20080422123304.GA777@osiris.boeblingen.de.ibm.com>
  2 siblings, 0 replies; 23+ messages in thread
From: Gautham R Shenoy @ 2008-04-14 13:28 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Miles Lane, LKML, Rafael J. Wysocki, Ingo Molnar

On Mon, Apr 14, 2008 at 02:42:27PM +0200, Peter Zijlstra wrote:
> On Mon, 2008-04-14 at 17:57 +0530, Gautham R Shenoy wrote:
> 
> > > Ok, so cpu_hotplug has a few issues imho:
> > > 
> > >  - access to active_writer isn't serialized and thus racey
> > >  - holding the lock over the 'write' section generates the stuff above
> > > 
> > > So basically we want a reader/writer lock, where get/put_online_cpu is
> > > the read side and cpu_hotplug_begin/done the write side.
> > > 
> > > We want:
> > >  - readers to recurse in readers (code excluding cpu-hotplug can
> > >    call code needing the same).
> > > 
> > >  - readers to recurse in the writer (the code changing the state can
> > >    call code needing a stable state)
> > > 
> > > rwlock_t isn't quite suitable because it doesn't allow reader in writer
> > > recursion and doesn't allow sleeping.
> > > 
> > > No lockdep annotation _yet_, because current lockdep recursive reader
> > > support is:
> > >  - broken (have a patch for that)
> > >  - doesn't support reader in writer recursion (will have to do something
> > >    about that)
> > > 
> > > Ok, so aside from the obviuos disclaimers, I've only compiled this and
> > > might have made things way too complicated - but a slightly feverish
> > > brain does that at times. What do people think?
> > 
> > You beat me to it! 
> > 
> > I just whipped up a similar patch, with slight differences, and lockdep
> > annotations :)
> 
> lockdep doesn't quite acecpt reader in writer recursion without a little
> patch like so:

For the recursive reads, one could use the rwlock semantics.
That coupled with the lockdep fix you provided
http://lkml.org/lkml/2008/3/12/110
should suffice.

For read after write, we're anyway performing an explicit check to see
if the active_writer is current, in which case, we just return without
troubling the lockdep.

Besides, I was not sure if we had any other scenario where we had a
similar requirement to warrant for the addition within lockdep.

> 
> (fold of two patches - one fixing the recursion another adding
> reader-writer recursion)
> 
> cpu_hotplug should use 3.
> 
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
> Index: linux-2.6-2/kernel/lockdep.c
> ===================================================================
> --- linux-2.6-2.orig/kernel/lockdep.c
> +++ linux-2.6-2/kernel/lockdep.c
> @@ -1281,6 +1281,13 @@ check_deadlock(struct task_struct *curr,
>  		 */
>  		if ((read == 2) && prev->read)
>  			return 2;
> +		/*
> +		 * Allow read-after-write recursion of the same
> +		 * lock class (i.e. write_lock(lock)+read_lock(lock)):
> +		 */
> +		if (read == 3)
> +			return 2;
> +
>  		return print_deadlock_bug(curr, prev, next);
>  	}
>  	return 1;
> @@ -1557,12 +1564,11 @@ static int validate_chain(struct task_st
>  		if (!ret)
>  			return 0;
>  		/*
> -		 * Mark recursive read, as we jump over it when
> -		 * building dependencies (just like we jump over
> -		 * trylock entries):
> +		 * If we are the first recursive read, don't jump over our
> +		 * dependency.
>  		 */
> -		if (ret == 2)
> -			hlock->read = 2;
> +		if (hlock->read >= 2 && ret != 2)
> +			hlock->read = 1;
>  		/*
>  		 * Add dependency only if this lock is not the head
>  		 * of the chain, and if it's not a secondary read-lock:
> Index: linux-2.6-2/lib/locking-selftest.c
> ===================================================================
> --- linux-2.6-2.orig/lib/locking-selftest.c
> +++ linux-2.6-2/lib/locking-selftest.c
> @@ -1135,12 +1135,12 @@ void locking_selftest(void)
>  	debug_locks_silent = !debug_locks_verbose;
> 
>  	DO_TESTCASE_6R("A-A deadlock", AA);
> -	DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
> -	DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
> -	DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
> -	DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
> -	DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
> -	DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
> +	DO_TESTCASE_6("A-B-B-A deadlock", ABBA);
> +	DO_TESTCASE_6("A-B-B-C-C-A deadlock", ABBCCA);
> +	DO_TESTCASE_6("A-B-C-A-B-C deadlock", ABCABC);
> +	DO_TESTCASE_6("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
> +	DO_TESTCASE_6("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
> +	DO_TESTCASE_6("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
>  	DO_TESTCASE_6("double unlock", double_unlock);
>  	DO_TESTCASE_6("initialize held", init_held);
>  	DO_TESTCASE_6_SUCCESS("bad unlock order", bad_unlock_order);
> Index: linux-2.6-2/include/linux/lockdep.h
> ===================================================================
> --- linux-2.6-2.orig/include/linux/lockdep.h
> +++ linux-2.6-2/include/linux/lockdep.h
> @@ -291,6 +291,7 @@ extern void lockdep_init_map(struct lock
>   *   0: exclusive (write) acquire
>   *   1: read-acquire (no recursion allowed)
>   *   2: read-acquire with same-instance recursion allowed
> + *   3: 2 + reader in writer recursion
>   *
>   * Values for check:
>   *
> 
> > comments below
> > 
> > > 
> > > Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > > ---
> > > diff --git a/kernel/cpu.c b/kernel/cpu.c
> > > index 2011ad8..119d837 100644
> > > --- a/kernel/cpu.c
> > > +++ b/kernel/cpu.c
> > > @@ -27,12 +27,13 @@ static int cpu_hotplug_disabled;
> > > 
> > >  static struct {
> > >  	struct task_struct *active_writer;
> > > -	struct mutex lock; /* Synchronizes accesses to refcount, */
> > > +	spinlock_t lock; /* Synchronizes accesses to refcount, */
> > >  	/*
> > >  	 * Also blocks the new readers during
> > >  	 * an ongoing cpu hotplug operation.
> > >  	 */
> > >  	int refcount;
> > > +	wait_queue_head_t reader_queue;
> > >  	wait_queue_head_t writer_queue;
> > >  } cpu_hotplug;
> > > 
> > > @@ -41,8 +42,9 @@ static struct {
> > >  void __init cpu_hotplug_init(void)
> > >  {
> > >  	cpu_hotplug.active_writer = NULL;
> > > -	mutex_init(&cpu_hotplug.lock);
> > > +	spin_lock_init(&cpu_hotplug.lock);
> > >  	cpu_hotplug.refcount = 0;
> > > +	init_waitqueue_head(&cpu_hotplug.reader_queue);
> > >  	init_waitqueue_head(&cpu_hotplug.writer_queue);
> > >  }
> > > 
> > > @@ -51,27 +53,42 @@ void __init cpu_hotplug_init(void)
> > >  void get_online_cpus(void)
> > >  {
> > >  	might_sleep();
> > > +
> > > +	spin_lock(&cpu_hotplug.lock);
> > >  	if (cpu_hotplug.active_writer == current)
> > > -		return;
> > We don't need to perform this check holding the spinlock.
> > The reason being, this check should succeed only for get_online_cpus()
> > invoked from the CPU-hotplug callback path. and by that time,
> > the writer thread would have set active_writer to it's task struct
> > value.
> > 
> > For every other thread, when it's trying to check if it is the
> > active_writer, the value is either NULL, or the value of the currently
> > active writer's task_struct, but never current.
> > 
> > Am I missing something ?
> 
> I guess you're right - inside makes me feel better though :-) And its
> not like its a fast path or something like that.

I guess yes. But as of now, I don't see any point why we should take the
spinlock to perform that particular check.

> 
> > > -	mutex_lock(&cpu_hotplug.lock);
> > > +		goto unlock;
> > > +
> > > +	if (cpu_hotplug.active_writer) {
> > > +		DEFINE_WAIT(wait);
> > > +
> > > +		for (;;) {
> > > +			prepare_to_wait(&cpu_hotplug.reader_queue, &wait,
> > > +					TASK_UNINTERRUPTIBLE);
> > > +			if (!cpu_hotplug.active_writer)
> > > +				break;
> > > +			spin_unlock(&cpu_hotplug.lock);
> > > +			schedule();
> > > +			spin_lock(&cpu_hotplug.lock);
> > > +		}
> > > +		finish_wait(&cpu_hotplug.reader_queue, &wait);
> > > +	}
> > >  	cpu_hotplug.refcount++;
> > > -	mutex_unlock(&cpu_hotplug.lock);
> > > -
> > > + unlock:
> > > +	spin_unlock(&cpu_hotplug.lock);
> > >  }
> > >  EXPORT_SYMBOL_GPL(get_online_cpus);
> > > 
> > >  void put_online_cpus(void)
> > >  {
> > > +	spin_lock(&cpu_hotplug.lock);
> > >  	if (cpu_hotplug.active_writer == current)
> > > -		return;
> > 
> > ditto!
> > 
> > > -	mutex_lock(&cpu_hotplug.lock);
> > > -	cpu_hotplug.refcount--;
> > > +		goto unlock;
> > > 
> > > -	if (unlikely(writer_exists()) && !cpu_hotplug.refcount)
> > > +	cpu_hotplug.refcount--;
> > > +	if (!cpu_hotplug.refcount)
> > >  		wake_up(&cpu_hotplug.writer_queue);
> > 	hmm.. when there is no active writer, can't we avoid this
> > 	additional wake up ??
> > > -
> > > -	mutex_unlock(&cpu_hotplug.lock);
> > > -
> > > + unlock:
> > > +	spin_unlock(&cpu_hotplug.lock);
> > >  }
> > >  EXPORT_SYMBOL_GPL(put_online_cpus);
> > > 
> > > @@ -95,45 +112,41 @@ void cpu_maps_update_done(void)
> > >   * This ensures that the hotplug operation can begin only when the
> > >   * refcount goes to zero.
> > >   *
> > > - * Note that during a cpu-hotplug operation, the new readers, if any,
> > > - * will be blocked by the cpu_hotplug.lock
> > > - *
> > > - * Since cpu_maps_update_begin is always called after invoking
> > > - * cpu_maps_update_begin, we can be sure that only one writer is active.
> > > - *
> > > - * Note that theoretically, there is a possibility of a livelock:
> > > - * - Refcount goes to zero, last reader wakes up the sleeping
> > > - *   writer.
> > > - * - Last reader unlocks the cpu_hotplug.lock.
> > > - * - A new reader arrives at this moment, bumps up the refcount.
> > > - * - The writer acquires the cpu_hotplug.lock finds the refcount
> > > - *   non zero and goes to sleep again.
> > > - *
> > > - * However, this is very difficult to achieve in practice since
> > > - * get_online_cpus() not an api which is called all that often.
> > > - *
> > > + * cpu_hotplug is basically an unfair recursive reader/writer lock that
> > > + * allows reader in writer recursion.
> > >   */
> > >  static void cpu_hotplug_begin(void)
> > >  {
> > > -	DECLARE_WAITQUEUE(wait, current);
> > > -
> > > -	mutex_lock(&cpu_hotplug.lock);
> > > +	might_sleep();
> > > 
> > > -	cpu_hotplug.active_writer = current;
> > > -	add_wait_queue_exclusive(&cpu_hotplug.writer_queue, &wait);
> > > -	while (cpu_hotplug.refcount) {
> > > -		set_current_state(TASK_UNINTERRUPTIBLE);
> > > -		mutex_unlock(&cpu_hotplug.lock);
> > > -		schedule();
> > > -		mutex_lock(&cpu_hotplug.lock);
> > > +	spin_lock(&cpu_hotplug.lock);
> > > +	if (cpu_hotplug.refcount || cpu_hotplug.active_writer) {
> > 	if we reach this point, there can be only one writer, i.e.
> > 	ourselves!
> > 
> > 	Because, the other writers are serialized by the
> > 	cpu_add_remove_lock in cpu_up()/cpu_down().
> > 
> > 	Hence we can safely assign cpu_hotplug.active_writer to current.
> 
> Ah, missed that. Does it make sense to keep it like this, in case this
> outer lock goes away?

I wouldn't want to see the outer lock go away.
It serializes the access to the cpu_present_map, which is
updated on addition of logical cpus, in the Dynamic LPAR scenario.

> 
> > > +		DEFINE_WAIT(wait);
> > > +
> > > +		for (;;) {
> > > +			prepare_to_wait(&cpu_hotplug.writer_queue, &wait,
> > > +					TASK_UNINTERRUPTIBLE);
> > > +			if (!cpu_hotplug.refcount && !cpu_hotplug.active_writer)
> > > +				break;
> > > +			spin_unlock(&cpu_hotplug.lock);
> > > +			schedule();
> > > +			spin_lock(&cpu_hotplug.lock);
> > > +		}
> > > +		finish_wait(&cpu_hotplug.writer_queue, &wait);
> > >  	}
> > > -	remove_wait_queue_locked(&cpu_hotplug.writer_queue, &wait);
> > > +	cpu_hotplug.active_writer = current;
> > 
> > 
> > > +	spin_unlock(&cpu_hotplug.lock);
> > >  }
> > > 
> > >  static void cpu_hotplug_done(void)
> > >  {
> > > +	spin_lock(&cpu_hotplug.lock);
> > >  	cpu_hotplug.active_writer = NULL;
> > > -	mutex_unlock(&cpu_hotplug.lock);
> > > +	if (!list_empty(&cpu_hotplug.writer_queue.task_list))
> > > +		wake_up(&cpu_hotplug.writer_queue);
> > > +	else
> > > +		wake_up_all(&cpu_hotplug.reader_queue);
> > > +	spin_unlock(&cpu_hotplug.lock);
> > >  }
> > >  /* Need to know about CPUs going up/down? */
> > >  int __cpuinit register_cpu_notifier(struct notifier_block *nb)
> > >
> > 
> > Looks good otherwise!
> 
> Thanks..
> 
> lockdep annotations:
> 
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
> Index: linux-2.6-2/include/linux/lockdep.h
> ===================================================================
> --- linux-2.6-2.orig/include/linux/lockdep.h
> +++ linux-2.6-2/include/linux/lockdep.h
> @@ -458,4 +458,19 @@ static inline void print_irqtrace_events
>  # define rwsem_release(l, n, i)			do { } while (0)
>  #endif
> 
> +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> +# ifdef CONFIG_PROVE_LOCKING
> +#  define cpu_hotplug_acquire(l, s, t, i)	lock_acquire(l, s, t, 0, 2,
> i)
> +#  define cpu_hotplug_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 3,
> 2, i)
> +# else
> +#  define cpu_hotplug_acquire(l, s, t, i)	lock_acquire(l, s, t, 0, 1,
> i)
> +#  define cpu_hotplug_acquire_read(l, s, t, i)	lock_acquire(l, s, t, 3,
> 1, i)
> +# endif
> +# define cpu_hotplug_release(l, n, i)		lock_release(l, n, i)
> +#else
> +# define cpu_hotplug_acquire(l, s, t, i)	do { } while (0)
> +# define cpu_hotplug_acquire_read(l, s, t, i)	do { } while (0)
> +# define cpu_hotplug_release(l, n, i)		do { } while (0)
> +#endif
> +
>  #endif /* __LINUX_LOCKDEP_H */
> Index: linux-2.6-2/kernel/cpu.c
> ===================================================================
> --- linux-2.6-2.orig/kernel/cpu.c
> +++ linux-2.6-2/kernel/cpu.c
> @@ -35,12 +35,20 @@ static struct {
>  	int refcount;
>  	wait_queue_head_t reader_queue;
>  	wait_queue_head_t writer_queue;
> +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> +	struct lockdep_map	dep_map;
> +#endif
>  } cpu_hotplug;
> 
>  #define writer_exists() (cpu_hotplug.active_writer != NULL)
> 
>  void __init cpu_hotplug_init(void)
>  {
> +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> +	static struct lockdep_class_key __key;
> +
> +	lockdep_init_map(&cpu_hotplug.dep_map, "cpu_hotplug", &__key, 0);
> +#endif
>  	cpu_hotplug.active_writer = NULL;
>  	spin_lock_init(&cpu_hotplug.lock);
>  	cpu_hotplug.refcount = 0;
> @@ -54,6 +62,8 @@ void get_online_cpus(void)
>  {
>  	might_sleep();
> 
> +	cpu_hotplug_acquire_read(&cpu_hotplug.dep_map, 0, 0, _THIS_IP_);
> +
>  	spin_lock(&cpu_hotplug.lock);
>  	if (cpu_hotplug.active_writer == current)
>  		goto unlock;
> @@ -80,6 +90,8 @@ EXPORT_SYMBOL_GPL(get_online_cpus);
> 
>  void put_online_cpus(void)
>  {
> +	cpu_hotplug_release(&cpu_hotplug.lock, 1, _THIS_IP_);
> +
>  	spin_lock(&cpu_hotplug.lock);
>  	if (cpu_hotplug.active_writer == current)
>  		goto unlock;
> @@ -119,6 +131,8 @@ static void cpu_hotplug_begin(void)
>  {
>  	might_sleep();
> 
> +	cpu_hotplug_acquire(&cpu_hotplug.dep_map, 0, 0, _THIS_IP_);
> +
>  	spin_lock(&cpu_hotplug.lock);
>  	if (cpu_hotplug.refcount || cpu_hotplug.active_writer) {
>  		DEFINE_WAIT(wait);
> @@ -140,6 +154,8 @@ static void cpu_hotplug_begin(void)
> 
>  static void cpu_hotplug_done(void)
>  {
> +	cpu_hotplug_release(&cpu_hotplug.lock, 1, _THIS_IP_);
> +
>  	spin_lock(&cpu_hotplug.lock);
>  	cpu_hotplug.active_writer = NULL;
>  	if (!list_empty(&cpu_hotplug.writer_queue.task_list))
> 

Looks good. Will test the series and report back.

But w.r.t the problem at hand, I susupect
some more changes are required in the
cpufreq-cpuhotplug interations.

-- 
Thanks and Regards
gautham

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14 12:42       ` Peter Zijlstra
  2008-04-14 13:28         ` Gautham R Shenoy
@ 2008-04-14 14:48         ` Gautham R Shenoy
  2008-04-14 15:19           ` Heiko Carstens
       [not found]         ` <20080422123304.GA777@osiris.boeblingen.de.ibm.com>
  2 siblings, 1 reply; 23+ messages in thread
From: Gautham R Shenoy @ 2008-04-14 14:48 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Miles Lane, LKML, Rafael J. Wysocki, Ingo Molnar

On Mon, Apr 14, 2008 at 02:42:27PM +0200, Peter Zijlstra wrote:
> 
>  void __init cpu_hotplug_init(void)
>  {
> +#ifdef CONFIG_DEBUG_LOCK_ALLOC
> +	static struct lockdep_class_key __key;
		      ^^^^^^^^^^^^^^^^^
		      should be lock_class_key.

> +
> +	lockdep_init_map(&cpu_hotplug.dep_map, "cpu_hotplug", &__key, 0);
> +#endif
>  	cpu_hotplug.active_writer = NULL;
>  	spin_lock_init(&cpu_hotplug.lock);
>  	cpu_hotplug.refcount = 0;
> @@ -54,6 +62,8 @@ void get_online_cpus(void)
>  {
>  	might_sleep();
> 
> +	cpu_hotplug_acquire_read(&cpu_hotplug.dep_map, 0, 0, _THIS_IP_);
> +
>  	spin_lock(&cpu_hotplug.lock);
>  	if (cpu_hotplug.active_writer == current)
>  		goto unlock;
> @@ -80,6 +90,8 @@ EXPORT_SYMBOL_GPL(get_online_cpus);
> 
>  void put_online_cpus(void)
>  {
> +	cpu_hotplug_release(&cpu_hotplug.lock, 1, _THIS_IP_);
> +
>  	spin_lock(&cpu_hotplug.lock);
>  	if (cpu_hotplug.active_writer == current)
>  		goto unlock;
> @@ -119,6 +131,8 @@ static void cpu_hotplug_begin(void)
>  {
>  	might_sleep();
> 
> +	cpu_hotplug_acquire(&cpu_hotplug.dep_map, 0, 0, _THIS_IP_);
> +
>  	spin_lock(&cpu_hotplug.lock);
>  	if (cpu_hotplug.refcount || cpu_hotplug.active_writer) {
>  		DEFINE_WAIT(wait);
> @@ -140,6 +154,8 @@ static void cpu_hotplug_begin(void)
> 
>  static void cpu_hotplug_done(void)
>  {
> +	cpu_hotplug_release(&cpu_hotplug.lock, 1, _THIS_IP_);
> +
>  	spin_lock(&cpu_hotplug.lock);
>  	cpu_hotplug.active_writer = NULL;
>  	if (!list_empty(&cpu_hotplug.writer_queue.task_list))
> 

-- 
Thanks and Regards
gautham

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14 14:48         ` Gautham R Shenoy
@ 2008-04-14 15:19           ` Heiko Carstens
  2008-04-14 15:46             ` Gautham R Shenoy
  0 siblings, 1 reply; 23+ messages in thread
From: Heiko Carstens @ 2008-04-14 15:19 UTC (permalink / raw)
  To: Gautham R Shenoy
  Cc: Peter Zijlstra, Miles Lane, LKML, Rafael J. Wysocki, Ingo Molnar

On Mon, Apr 14, 2008 at 08:18:01PM +0530, Gautham R Shenoy wrote:
> On Mon, Apr 14, 2008 at 02:42:27PM +0200, Peter Zijlstra wrote:

While you're fixing the cpu hotplug stuff anyway, there's still a bug
present in a few modules init code:

Usually they do something like:

	register_hotcpu_notifier(...);
	for_each_online_cpu(i)
		...

A module's init functions gets called from sys_init_module and there is nothing
that would protect from cpu hotplug.
Therefore the sequence of for_each_online_cpu() and register_hotcpu_notifier()
better should be protected by a surrounding get/put_online_cpus() like this:

	get_online_cpus();
	register_hotcpu_notifier(...);
	for_each_online_cpu(i)
		...
	put_online_cpus();

But as far as I can see that can lead to a deadlock if e.g. cpu 0 would
execute the code above whild cpu 1 is executing some cpu hotplug code:

cpu0: get_online_cpus()
       -> increase cpu_hotplug.refcount
cpu1: cpu_down()
       -> cpu_maps_update_begin()
       -> grab cpu_add_remove_lock
       -> wait for cpu_hotplug.refcount to drop to zero again
cpu0: register_hotcpu_notifier()
       -> cpu_maps_update_begin
       -> tries to grab cpu_add_remove_lock that cpu 1 holds already
          -> dead

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14 15:19           ` Heiko Carstens
@ 2008-04-14 15:46             ` Gautham R Shenoy
  2008-04-14 19:35               ` Heiko Carstens
  0 siblings, 1 reply; 23+ messages in thread
From: Gautham R Shenoy @ 2008-04-14 15:46 UTC (permalink / raw)
  To: Heiko Carstens
  Cc: Peter Zijlstra, Miles Lane, LKML, Rafael J. Wysocki, Ingo Molnar

On Mon, Apr 14, 2008 at 05:19:46PM +0200, Heiko Carstens wrote:
> On Mon, Apr 14, 2008 at 08:18:01PM +0530, Gautham R Shenoy wrote:
> > On Mon, Apr 14, 2008 at 02:42:27PM +0200, Peter Zijlstra wrote:
> 
> While you're fixing the cpu hotplug stuff anyway, there's still a bug
> present in a few modules init code:
> 
> Usually they do something like:
> 
> 	register_hotcpu_notifier(...);
> 	for_each_online_cpu(i)
> 		...
> 
> A module's init functions gets called from sys_init_module and there is nothing
> that would protect from cpu hotplug.
> Therefore the sequence of for_each_online_cpu() and register_hotcpu_notifier()
> better should be protected by a surrounding get/put_online_cpus() like this:
> 
> 	get_online_cpus();
> 	register_hotcpu_notifier(...);
> 	for_each_online_cpu(i)
> 		...
> 	put_online_cpus();

But shouldn't this be:
	register_hotcpu_notifier(...);
	get_online_cpus();
	for_each_online_cpus()
		...
	put_online_cpus();

What's the problem with this ordering?

> 
> But as far as I can see that can lead to a deadlock if e.g. cpu 0 would
> execute the code above whild cpu 1 is executing some cpu hotplug code:
> 
> cpu0: get_online_cpus()
>        -> increase cpu_hotplug.refcount
> cpu1: cpu_down()
>        -> cpu_maps_update_begin()
>        -> grab cpu_add_remove_lock
>        -> wait for cpu_hotplug.refcount to drop to zero again
> cpu0: register_hotcpu_notifier()
>        -> cpu_maps_update_begin
>        -> tries to grab cpu_add_remove_lock that cpu 1 holds already
>           -> dead

-- 
Thanks and Regards
gautham

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14 15:46             ` Gautham R Shenoy
@ 2008-04-14 19:35               ` Heiko Carstens
  2008-04-15 13:52                 ` Gautham R Shenoy
  0 siblings, 1 reply; 23+ messages in thread
From: Heiko Carstens @ 2008-04-14 19:35 UTC (permalink / raw)
  To: Gautham R Shenoy
  Cc: Peter Zijlstra, Miles Lane, LKML, Rafael J. Wysocki, Ingo Molnar

On Mon, Apr 14, 2008 at 09:16:42PM +0530, Gautham R Shenoy wrote:
> On Mon, Apr 14, 2008 at 05:19:46PM +0200, Heiko Carstens wrote:
> > On Mon, Apr 14, 2008 at 08:18:01PM +0530, Gautham R Shenoy wrote:
> > > On Mon, Apr 14, 2008 at 02:42:27PM +0200, Peter Zijlstra wrote:
> > 
> > While you're fixing the cpu hotplug stuff anyway, there's still a bug
> > present in a few modules init code:
> > 
> > Usually they do something like:
> > 
> > 	register_hotcpu_notifier(...);
> > 	for_each_online_cpu(i)
> > 		...
> > 
> > A module's init functions gets called from sys_init_module and there is nothing
> > that would protect from cpu hotplug.
> > Therefore the sequence of for_each_online_cpu() and register_hotcpu_notifier()
> > better should be protected by a surrounding get/put_online_cpus() like this:
> > 
> > 	get_online_cpus();
> > 	register_hotcpu_notifier(...);
> > 	for_each_online_cpu(i)
> > 		...
> > 	put_online_cpus();
> 
> But shouldn't this be:
> 	register_hotcpu_notifier(...);
> 	get_online_cpus();
> 	for_each_online_cpus()
> 		...
> 	put_online_cpus();
> 
> What's the problem with this ordering?

The problem here is that between register_hotcpu_notifier() and
get_online_cpus() a cpu might have been hotplugged.
So on cpu down the registered function might try to undo something that
wasn't prepared in the first place.
On cpu up however it will do things twice. Once for the cpus that got
added between register_hotcpu_notifier() and for_each_online_cpus()
and then again in the for_each_online_cpus() loop.

Of course all of these scenarios could be fixed in each driver, but that
would be a lot of duplicated work. Making sure the combination of
get_online_cpus() and register_hotcpu_notifier() cannot deadlock would
make things much easier.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-14 19:35               ` Heiko Carstens
@ 2008-04-15 13:52                 ` Gautham R Shenoy
  2008-04-15 14:37                   ` Heiko Carstens
  0 siblings, 1 reply; 23+ messages in thread
From: Gautham R Shenoy @ 2008-04-15 13:52 UTC (permalink / raw)
  To: Heiko Carstens
  Cc: Peter Zijlstra, Miles Lane, LKML, Rafael J. Wysocki, Ingo Molnar

On Mon, Apr 14, 2008 at 09:35:39PM +0200, Heiko Carstens wrote:
> On Mon, Apr 14, 2008 at 09:16:42PM +0530, Gautham R Shenoy wrote:
> > On Mon, Apr 14, 2008 at 05:19:46PM +0200, Heiko Carstens wrote:
> > > On Mon, Apr 14, 2008 at 08:18:01PM +0530, Gautham R Shenoy wrote:
> > > > On Mon, Apr 14, 2008 at 02:42:27PM +0200, Peter Zijlstra wrote:
> > > 
> > > While you're fixing the cpu hotplug stuff anyway, there's still a bug
> > > present in a few modules init code:
> > > 
> > > Usually they do something like:
> > > 
> > > 	register_hotcpu_notifier(...);
> > > 	for_each_online_cpu(i)
> > > 		...
> > > 
> > > A module's init functions gets called from sys_init_module and there is nothing
> > > that would protect from cpu hotplug.
> > > Therefore the sequence of for_each_online_cpu() and register_hotcpu_notifier()
> > > better should be protected by a surrounding get/put_online_cpus() like this:
> > > 
> > > 	get_online_cpus();
> > > 	register_hotcpu_notifier(...);
> > > 	for_each_online_cpu(i)
> > > 		...
> > > 	put_online_cpus();
> > 
> > But shouldn't this be:
> > 	register_hotcpu_notifier(...);
> > 	get_online_cpus();
> > 	for_each_online_cpus()
> > 		...
> > 	put_online_cpus();
> > 
> > What's the problem with this ordering?
> 
> The problem here is that between register_hotcpu_notifier() and
> get_online_cpus() a cpu might have been hotplugged.
> So on cpu down the registered function might try to undo something that
> wasn't prepared in the first place.
> On cpu up however it will do things twice. Once for the cpus that got
> added between register_hotcpu_notifier() and for_each_online_cpus()
> and then again in the for_each_online_cpus() loop.
> 
> Of course all of these scenarios could be fixed in each driver, but that
> would be a lot of duplicated work. Making sure the combination of
> get_online_cpus() and register_hotcpu_notifier() cannot deadlock would
> make things much easier.

Ah, okay. Thanks for the explanation.
So how about having a new API,
something along the lines of:

kernel/cpu.c
------------------------------------------------------
register_hot_cpu_notifier_init(notifier_name, driver_hotcpu_init_function)
{
	mutex_lock(&cpu_add_remove_lock);
	get_online_cpus();
	__register_hot_cpu_notifier(notifier_name);
	driver_hotcpu_init_function();
	put_online_cpus();
	mutex_unlock(&cpu_add_remove_lock);
}

drivers/mydriver.c
--------------------------------------------------------------
driver_hotcpu_init_function()
{
	for_each_online_cpus()
		perform_subsystem_hotcpu_initialization();
}


driver_init()
{
	register_hotcpu_notifier_init(notifier_name,
			driver_hotcpu_init_function);
}



-- 
Thanks and Regards
gautham

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: 2.6.25-rc9 -- INFO: possible circular locking dependency detected
  2008-04-15 13:52                 ` Gautham R Shenoy
@ 2008-04-15 14:37                   ` Heiko Carstens
  0 siblings, 0 replies; 23+ messages in thread
From: Heiko Carstens @ 2008-04-15 14:37 UTC (permalink / raw)
  To: Gautham R Shenoy
  Cc: Peter Zijlstra, Miles Lane, LKML, Rafael J. Wysocki, Ingo Molnar

On Tue, Apr 15, 2008 at 07:22:10PM +0530, Gautham R Shenoy wrote:
> On Mon, Apr 14, 2008 at 09:35:39PM +0200, Heiko Carstens wrote:
> > The problem here is that between register_hotcpu_notifier() and
> > get_online_cpus() a cpu might have been hotplugged.
> > So on cpu down the registered function might try to undo something that
> > wasn't prepared in the first place.
> > On cpu up however it will do things twice. Once for the cpus that got
> > added between register_hotcpu_notifier() and for_each_online_cpus()
> > and then again in the for_each_online_cpus() loop.
> > 
> > Of course all of these scenarios could be fixed in each driver, but that
> > would be a lot of duplicated work. Making sure the combination of
> > get_online_cpus() and register_hotcpu_notifier() cannot deadlock would
> > make things much easier.
> 
> Ah, okay. Thanks for the explanation.
> So how about having a new API,
> something along the lines of:
> 
> kernel/cpu.c
> ------------------------------------------------------
> register_hot_cpu_notifier_init(notifier_name, driver_hotcpu_init_function)
> {
> 	mutex_lock(&cpu_add_remove_lock);
> 	get_online_cpus();
> 	__register_hot_cpu_notifier(notifier_name);
> 	driver_hotcpu_init_function();
> 	put_online_cpus();
> 	mutex_unlock(&cpu_add_remove_lock);
> }
> 
> drivers/mydriver.c
> --------------------------------------------------------------
> driver_hotcpu_init_function()
> {
> 	for_each_online_cpus()
> 		perform_subsystem_hotcpu_initialization();
> }
> 
> 
> driver_init()
> {
> 	register_hotcpu_notifier_init(notifier_name,
> 			driver_hotcpu_init_function);
> }

That looks fine to me.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* get_online_cpus() && workqueues
       [not found]                         ` <20080425064044.GA10817@osiris.boeblingen.de.ibm.com>
@ 2008-04-26 14:43                           ` Oleg Nesterov
  2008-04-27 12:22                             ` Heiko Carstens
                                               ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Oleg Nesterov @ 2008-04-26 14:43 UTC (permalink / raw)
  To: Heiko Carstens
  Cc: Peter Zijlstra, Gautham R Shenoy, Johannes Berg,
	Martin Schwidefsky, Srivatsa Vaddagiri, linux-kernel

Gautham, Srivatsa, seriously, can't we uglify cpu.c a little bit to solve
the problem. Please see the illustration patch below. It looks complicated,
but in fact it is quite trivial.

In short: work_struct can't use get_online_cpus() due to deadlock with the
CPU_DEAD phase.

Can't we add another nested lock which is dropped right after __cpu_die()?
(in fact I think it could be dropped after __stop_machine_run).

The new read-lock is get_online_map() (just a random name for now). The only
difference wrt get_online_cpus() is that it doesn't protect against CPU_DEAD,
but most users of get_online_cpus() doesn't need this, they only need a
stable cpu_online_map and sometimes they need to be sure that some per-cpu
object (say, cpu_workqueue_struct->thread) can't be destroyed under this
lock.

get_online_map() seem to fit for this, and can be used from work->func().
(actually, I think most users of use get_online_cpus() could use the new
helper instead, but this doen't matter).

Heiko, what do you think? Is it suitable for arch_reinit_sched_domains()?

Oleg.

--- 25/kernel/cpu.c~HP_LOCK	2008-02-16 18:36:37.000000000 +0300
+++ 25/kernel/cpu.c	2008-04-26 18:14:25.000000000 +0400
@@ -25,7 +25,7 @@ static __cpuinitdata RAW_NOTIFIER_HEAD(c
  */
 static int cpu_hotplug_disabled;
 
-static struct {
+static struct cpu_lock {
 	struct task_struct *active_writer;
 	struct mutex lock; /* Synchronizes accesses to refcount, */
 	/*
@@ -33,41 +33,65 @@ static struct {
 	 * an ongoing cpu hotplug operation.
 	 */
 	int refcount;
-} cpu_hotplug;
+} cpu_hotplug, online_map;
+
+static inline void __cpu_hotplug_init(struct cpu_lock *cpu_lock)
+{
+	cpu_lock->active_writer = NULL;
+	mutex_init(&cpu_lock->lock);
+	cpu_lock->refcount = 0;
+}
 
 void __init cpu_hotplug_init(void)
 {
-	cpu_hotplug.active_writer = NULL;
-	mutex_init(&cpu_hotplug.lock);
-	cpu_hotplug.refcount = 0;
+	__cpu_hotplug_init(&cpu_hotplug);
+	__cpu_hotplug_init(&online_map);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
 
-void get_online_cpus(void)
+void cpu_read_lock(struct cpu_lock *cpu_lock)
 {
 	might_sleep();
-	if (cpu_hotplug.active_writer == current)
+	if (cpu_lock->active_writer == current)
 		return;
-	mutex_lock(&cpu_hotplug.lock);
-	cpu_hotplug.refcount++;
-	mutex_unlock(&cpu_hotplug.lock);
+	mutex_lock(&cpu_lock->lock);
+	cpu_lock->refcount++;
+	mutex_unlock(&cpu_lock->lock);
+}
 
+void get_online_cpus(void)
+{
+	cpu_read_lock(&cpu_hotplug);
 }
 EXPORT_SYMBOL_GPL(get_online_cpus);
 
-void put_online_cpus(void)
+void get_online_map(void)
 {
-	if (cpu_hotplug.active_writer == current)
+	cpu_read_lock(&online_map);
+}
+
+void cpu_read_unlock(struct cpu_lock *cpu_lock)
+{
+	if (cpu_lock->active_writer == current)
 		return;
-	mutex_lock(&cpu_hotplug.lock);
-	if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
-		wake_up_process(cpu_hotplug.active_writer);
-	mutex_unlock(&cpu_hotplug.lock);
+	mutex_lock(&cpu_lock->lock);
+	if (!--cpu_lock->refcount && unlikely(cpu_lock->active_writer))
+		wake_up_process(cpu_lock->active_writer);
+	mutex_unlock(&cpu_lock->lock);
+}
 
+void put_online_cpus(void)
+{
+	cpu_read_unlock(&cpu_hotplug);
 }
 EXPORT_SYMBOL_GPL(put_online_cpus);
 
+void put_online_map(void)
+{
+	cpu_read_unlock(&online_map);
+}
+
 #endif	/* CONFIG_HOTPLUG_CPU */
 
 /*
@@ -91,7 +115,7 @@ void cpu_maps_update_done(void)
  * Note that during a cpu-hotplug operation, the new readers, if any,
  * will be blocked by the cpu_hotplug.lock
  *
- * Since cpu_hotplug_begin() is always called after invoking
+ * Since cpu_write_lock() is always called after invoking
  * cpu_maps_update_begin(), we can be sure that only one writer is active.
  *
  * Note that theoretically, there is a possibility of a livelock:
@@ -106,25 +130,26 @@ void cpu_maps_update_done(void)
  * get_online_cpus() not an api which is called all that often.
  *
  */
-static void cpu_hotplug_begin(void)
+static void cpu_write_lock(struct cpu_lock *cpu_lock)
 {
-	cpu_hotplug.active_writer = current;
+	cpu_lock->active_writer = current;
 
 	for (;;) {
-		mutex_lock(&cpu_hotplug.lock);
-		if (likely(!cpu_hotplug.refcount))
+		mutex_lock(&cpu_lock->lock);
+		if (likely(!cpu_lock->refcount))
 			break;
 		__set_current_state(TASK_UNINTERRUPTIBLE);
-		mutex_unlock(&cpu_hotplug.lock);
+		mutex_unlock(&cpu_lock->lock);
 		schedule();
 	}
 }
 
-static void cpu_hotplug_done(void)
+static void cpu_write_unlock(struct cpu_lock *cpu_lock)
 {
-	cpu_hotplug.active_writer = NULL;
-	mutex_unlock(&cpu_hotplug.lock);
+	cpu_lock->active_writer = NULL;
+	mutex_unlock(&cpu_lock->lock);
 }
+
 /* Need to know about CPUs going up/down? */
 int __cpuinit register_cpu_notifier(struct notifier_block *nb)
 {
@@ -207,7 +232,8 @@ static int _cpu_down(unsigned int cpu, i
 	if (!cpu_online(cpu))
 		return -EINVAL;
 
-	cpu_hotplug_begin();
+	cpu_write_lock(&cpu_hotplug);
+	cpu_write_lock(&online_map);
 	err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
 					hcpu, -1, &nr_calls);
 	if (err == NOTIFY_BAD) {
@@ -238,6 +264,7 @@ static int _cpu_down(unsigned int cpu, i
 			err = PTR_ERR(p);
 			goto out_allowed;
 		}
+		err = -EAGAIN;
 		goto out_thread;
 	}
 
@@ -247,6 +274,7 @@ static int _cpu_down(unsigned int cpu, i
 
 	/* This actually kills the CPU. */
 	__cpu_die(cpu);
+	cpu_write_unlock(&online_map);
 
 	/* CPU is completely dead: tell everyone.  Too late to complain. */
 	if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD | mod,
@@ -260,7 +288,9 @@ out_thread:
 out_allowed:
 	set_cpus_allowed(current, old_allowed);
 out_release:
-	cpu_hotplug_done();
+	if (err)
+		cpu_write_unlock(&online_map);
+	cpu_write_unlock(&cpu_hotplug);
 	return err;
 }
 
@@ -289,7 +319,8 @@ static int __cpuinit _cpu_up(unsigned in
 	if (cpu_online(cpu) || !cpu_present(cpu))
 		return -EINVAL;
 
-	cpu_hotplug_begin();
+	cpu_write_lock(&cpu_hotplug);
+	cpu_write_lock(&online_map);
 	ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu,
 							-1, &nr_calls);
 	if (ret == NOTIFY_BAD) {
@@ -313,7 +344,8 @@ out_notify:
 	if (ret != 0)
 		__raw_notifier_call_chain(&cpu_chain,
 				CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
-	cpu_hotplug_done();
+	cpu_write_unlock(&online_map);
+	cpu_write_unlock(&cpu_hotplug);
 
 	return ret;
 }


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: get_online_cpus() && workqueues
  2008-04-26 14:43                           ` get_online_cpus() && workqueues Oleg Nesterov
@ 2008-04-27 12:22                             ` Heiko Carstens
  2008-04-27 14:25                               ` Oleg Nesterov
  2008-04-28  7:02                             ` Gautham R Shenoy
  2008-04-28 11:57                             ` Gautham R Shenoy
  2 siblings, 1 reply; 23+ messages in thread
From: Heiko Carstens @ 2008-04-27 12:22 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Peter Zijlstra, Gautham R Shenoy, Johannes Berg,
	Martin Schwidefsky, Srivatsa Vaddagiri, linux-kernel

On Sat, Apr 26, 2008 at 06:43:30PM +0400, Oleg Nesterov wrote:
> Gautham, Srivatsa, seriously, can't we uglify cpu.c a little bit to solve
> the problem. Please see the illustration patch below. It looks complicated,
> but in fact it is quite trivial.
> 
> In short: work_struct can't use get_online_cpus() due to deadlock with the
> CPU_DEAD phase.
> 
> Can't we add another nested lock which is dropped right after __cpu_die()?
> (in fact I think it could be dropped after __stop_machine_run).
> 
> The new read-lock is get_online_map() (just a random name for now). The only
> difference wrt get_online_cpus() is that it doesn't protect against CPU_DEAD,
> but most users of get_online_cpus() doesn't need this, they only need a
> stable cpu_online_map and sometimes they need to be sure that some per-cpu
> object (say, cpu_workqueue_struct->thread) can't be destroyed under this
> lock.
> 
> get_online_map() seem to fit for this, and can be used from work->func().
> (actually, I think most users of use get_online_cpus() could use the new
> helper instead, but this doen't matter).
> 
> Heiko, what do you think? Is it suitable for arch_reinit_sched_domains()?

Uhm, no. For arch_reinit_sched_domains that would allow for concurrent
callers for arch_init_sched_domains since sched.c calls that function in
quite a lot of the CPU_* phases (including CPU_DEAD) in update_sched_domains.
Not sure why it does that however.

But on the other hand there can be already concurrent callers via
sched_power_savings_store().

And with s390 calling arch_reinit_sched_domais() from outside there can be
yet another concurrent caller. Looks like the locking is broken anyway.
Sigh.

Looks like we need a new lock in arch_reinit_sched_domains() to prevent
concurrent callers to arch_init_sched_domains().
The calls from update_sched_domains() are implicitly prevented by the
cpu hotplug lock _and_ the fact that arch_reinit_sched_domains does
the get/put_online_cpus thing.

So conclusion is: the new get_online_map() wouldn't solve the deadlock
here, but we have a bug anyway :) Will see, if I can come up with a
tested patch tomorrow.

For the "don't call get_online_cpus() from within a work_struct" I have
the patch below. Even though I think it sucks. But at least it should
work.

 arch/s390/kernel/topology.c |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff -urpN linux-2.6/arch/s390/kernel/topology.c linux-2.6-patched/arch/s390/kernel/topology.c
--- linux-2.6/arch/s390/kernel/topology.c	2008-04-25 14:16:25.000000000 +0200
+++ linux-2.6-patched/arch/s390/kernel/topology.c	2008-04-25 14:16:25.000000000 +0200
@@ -9,6 +9,7 @@
 #include <linux/device.h>
 #include <linux/bootmem.h>
 #include <linux/sched.h>
+#include <linux/kthread.h>
 #include <linux/workqueue.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
@@ -229,9 +230,20 @@ void arch_update_cpu_topology(void)
 	}
 }
 
-static void topology_work_fn(struct work_struct *work)
+static int topology_kthread(void *data)
 {
 	arch_reinit_sched_domains();
+	return 0;
+}
+
+static void topology_work_fn(struct work_struct *work)
+{
+	/* We can't call arch_reinit_sched_domains() from a multi-threaded
+	 * workqueue context since it may deadlock in case of cpu hotplug.
+	 * So we have to create a kernel thread in order to call
+	 * arch_reinit_sched_domains().
+	 */
+	kthread_run(topology_kthread, NULL, "topology_update");
 }
 
 void topology_schedule_update(void)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: get_online_cpus() && workqueues
  2008-04-27 12:22                             ` Heiko Carstens
@ 2008-04-27 14:25                               ` Oleg Nesterov
  0 siblings, 0 replies; 23+ messages in thread
From: Oleg Nesterov @ 2008-04-27 14:25 UTC (permalink / raw)
  To: Heiko Carstens
  Cc: Peter Zijlstra, Gautham R Shenoy, Johannes Berg,
	Martin Schwidefsky, Srivatsa Vaddagiri, linux-kernel

On 04/27, Heiko Carstens wrote:
>
> On Sat, Apr 26, 2008 at 06:43:30PM +0400, Oleg Nesterov wrote:
> > 
> > In short: work_struct can't use get_online_cpus() due to deadlock with the
> > CPU_DEAD phase.
> > 
> > Can't we add another nested lock which is dropped right after __cpu_die()?
> > (in fact I think it could be dropped after __stop_machine_run).
> > 
> > The new read-lock is get_online_map() (just a random name for now). The only
> > difference wrt get_online_cpus() is that it doesn't protect against CPU_DEAD,
> > but most users of get_online_cpus() doesn't need this, they only need a
> > stable cpu_online_map and sometimes they need to be sure that some per-cpu
> > object (say, cpu_workqueue_struct->thread) can't be destroyed under this
> > lock.
> > 
> > get_online_map() seem to fit for this, and can be used from work->func().
> > (actually, I think most users of use get_online_cpus() could use the new
> > helper instead, but this doen't matter).
> > 
> > Heiko, what do you think? Is it suitable for arch_reinit_sched_domains()?
> 
> Uhm, no. For arch_reinit_sched_domains that would allow for concurrent
> callers for arch_init_sched_domains since sched.c calls that function in
> quite a lot of the CPU_* phases (including CPU_DEAD)

OK, thanks,

> But on the other hand there can be already concurrent callers via
> sched_power_savings_store().
> 
> And with s390 calling arch_reinit_sched_domais() from outside there can be
> yet another concurrent caller. Looks like the locking is broken anyway.
> Sigh.
> 
> Looks like we need a new lock in arch_reinit_sched_domains() to prevent
> concurrent callers to arch_init_sched_domains().
...
> So conclusion is: the new get_online_map() wouldn't solve the deadlock
> here,

Well, if we add a new lock to arch_reinit_sched_domains(), perhaps we can
solve the deadlock, but this means we should also change update_sched_domains()
to take this lock too. Not pleasant, and

> For the "don't call get_online_cpus() from within a work_struct" I have
> the patch below.

yes, I think it is much better.



Still. It would be nice to find the general (and simple!) solution.
Especially because it can happen that some work->func() will use
get_online_cpus() indirectly.

Currently I am thinking about something like the patch below, but it
is so ugly...

Oleg.

--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -210,6 +210,8 @@ static inline int notifier_to_errno(int 
 #define CPU_DYING		0x0008 /* CPU (unsigned)v not running any task,
 				        * not handling interrupts, soon dead */
 
+#define CPU_DEAD_XXX		0x0002 /* HACK!!! for workqueus */
+
 /* Used for CPU hotplug events occuring while tasks are frozen due to a suspend
  * operation in progress
  */
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -271,6 +271,11 @@ static int _cpu_down(unsigned int cpu,
 	set_cpus_allowed(current, old_allowed);
 out_release:
 	cpu_hotplug_done();
+
+	if (!err)
+		// HAAAAAACK !!!!!!!!!!!
+		raw_notifier_call_chain(&cpu_chain, CPU_DEAD_XXX, hcpu);
+
 	return err;
 }
 
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -780,7 +780,7 @@ struct workqueue_struct *__create_workqu
 		err = create_workqueue_thread(cwq, singlethread_cpu);
 		start_workqueue_thread(cwq, -1);
 	} else {
-		get_online_cpus();
+		cpu_maps_update_begin();
 		spin_lock(&workqueue_lock);
 		list_add(&wq->list, &workqueues);
 		spin_unlock(&workqueue_lock);
@@ -792,7 +792,7 @@ struct workqueue_struct *__create_workqu
 			err = create_workqueue_thread(cwq, cpu);
 			start_workqueue_thread(cwq, cpu);
 		}
-		put_online_cpus();
+		cpu_maps_update_done();
 	}
 
 	if (err) {
@@ -807,7 +807,7 @@ static void cleanup_workqueue_thread(str
 {
 	/*
 	 * Our caller is either destroy_workqueue() or CPU_DEAD,
-	 * get_online_cpus() protects cwq->thread.
+	 * cpu_add_remove_lock protects cwq->thread.
 	 */
 	if (cwq->thread == NULL)
 		return;
@@ -841,14 +841,14 @@ void destroy_workqueue(struct workqueue_
 	const cpumask_t *cpu_map = wq_cpu_map(wq);
 	int cpu;
 
-	get_online_cpus();
+	cpu_maps_update_begin();
 	spin_lock(&workqueue_lock);
 	list_del(&wq->list);
 	spin_unlock(&workqueue_lock);
 
 	for_each_cpu_mask(cpu, *cpu_map)
 		cleanup_workqueue_thread(per_cpu_ptr(wq->cpu_wq, cpu));
-	put_online_cpus();
+	cpu_maps_update_done();
 
 	free_percpu(wq->cpu_wq);
 	kfree(wq);
@@ -887,7 +887,7 @@ static int __devinit workqueue_cpu_callb
 
 		case CPU_UP_CANCELED:
 			start_workqueue_thread(cwq, -1);
-		case CPU_DEAD:
+		case CPU_DEAD_XXX:
 			cleanup_workqueue_thread(cwq);
 			break;
 		}


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: get_online_cpus() && workqueues
  2008-04-26 14:43                           ` get_online_cpus() && workqueues Oleg Nesterov
  2008-04-27 12:22                             ` Heiko Carstens
@ 2008-04-28  7:02                             ` Gautham R Shenoy
  2008-04-28 10:56                               ` Oleg Nesterov
  2008-04-28 11:57                             ` Gautham R Shenoy
  2 siblings, 1 reply; 23+ messages in thread
From: Gautham R Shenoy @ 2008-04-28  7:02 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Heiko Carstens, Peter Zijlstra, Johannes Berg, Martin Schwidefsky,
	Srivatsa Vaddagiri, linux-kernel

On Sat, Apr 26, 2008 at 06:43:30PM +0400, Oleg Nesterov wrote:
> Gautham, Srivatsa, seriously, can't we uglify cpu.c a little bit to solve
> the problem. Please see the illustration patch below. It looks complicated,
> but in fact it is quite trivial.
> 
> In short: work_struct can't use get_online_cpus() due to deadlock with the
> CPU_DEAD phase.
> 
> Can't we add another nested lock which is dropped right after __cpu_die()?
> (in fact I think it could be dropped after __stop_machine_run).
> 
> The new read-lock is get_online_map() (just a random name for now). The only
> difference wrt get_online_cpus() is that it doesn't protect against CPU_DEAD,
> but most users of get_online_cpus() doesn't need this, they only need a
> stable cpu_online_map and sometimes they need to be sure that some per-cpu
> object (say, cpu_workqueue_struct->thread) can't be destroyed under this
> lock.
> 
> get_online_map() seem to fit for this, and can be used from work->func().
> (actually, I think most users of use get_online_cpus() could use the new
> helper instead, but this doen't matter).

Sorry for the late reply.

Haven't looked at the patch yet, but I am okay with the idea,
since it is useful for subsystems that need the cpu_online_map
to be consistent while performing some operation and aren't really
concerned with serialization wrt entire CPU-Hotplug operation.

However, subsystems such as cpufreq require serialization with respect
to the whole CPU-Hotplug operation since they do initialization and
cleanup pre and  post the change of the cpu_online_map.
The current code, or this patch doesn't help in such cases
when such subsystems have multithreaded workqueues!

Case in point:
the ondemand governor code. If you look at the problems mentioned in the
earlier mails, we have a dependency between the cpufreq per_cpu rwsem
and the cpu_hotplug lock, as on the read-path, we aren't nesting
the rwsem with get_online_cpus(), but on the write path we are.

However, the solution is not as simple as nesting the
down_read/write(per_cpu(cpufreq_rwsem) with get_online_cpus(), since it
may deadlock with the do_dbs_timer() ondemand governor workitem code.

One of the thoughts I have is to provide an API along the lines of
try_get_online_cpus() which will return 1 if there is no CPU Hotplug
operation in progress and will return 0 otherwise. In case where
a cpu-hotplug operation is in progress, the workitem could simply
do nothing other than requeue itself and wait for the cpu-hotplug
operation to complete.

Else, we might want to do something like what slab.c does.
It sets the per-cpu work.func of the cpu-going down to NULL in
CPU_DOWN_PREPARE.

Thoughts?

--
Thanks and Regards
gautham.
>
> Heiko, what do you think? Is it suitable for arch_reinit_sched_domains()?
>
> Oleg.
>
> --- 25/kernel/cpu.c~HP_LOCK	2008-02-16 18:36:37.000000000 +0300
> +++ 25/kernel/cpu.c	2008-04-26 18:14:25.000000000 +0400
> @@ -25,7 +25,7 @@ static __cpuinitdata RAW_NOTIFIER_HEAD(c
>   */
>  static int cpu_hotplug_disabled;
> 
> -static struct {
> +static struct cpu_lock {
>  	struct task_struct *active_writer;
>  	struct mutex lock; /* Synchronizes accesses to refcount, */
>  	/*
> @@ -33,41 +33,65 @@ static struct {
>  	 * an ongoing cpu hotplug operation.
>  	 */
>  	int refcount;
> -} cpu_hotplug;
> +} cpu_hotplug, online_map;
> +
> +static inline void __cpu_hotplug_init(struct cpu_lock *cpu_lock)
> +{
> +	cpu_lock->active_writer = NULL;
> +	mutex_init(&cpu_lock->lock);
> +	cpu_lock->refcount = 0;
> +}
> 
>  void __init cpu_hotplug_init(void)
>  {
> -	cpu_hotplug.active_writer = NULL;
> -	mutex_init(&cpu_hotplug.lock);
> -	cpu_hotplug.refcount = 0;
> +	__cpu_hotplug_init(&cpu_hotplug);
> +	__cpu_hotplug_init(&online_map);
>  }
> 
>  #ifdef CONFIG_HOTPLUG_CPU
> 
> -void get_online_cpus(void)
> +void cpu_read_lock(struct cpu_lock *cpu_lock)
>  {
>  	might_sleep();
> -	if (cpu_hotplug.active_writer == current)
> +	if (cpu_lock->active_writer == current)
>  		return;
> -	mutex_lock(&cpu_hotplug.lock);
> -	cpu_hotplug.refcount++;
> -	mutex_unlock(&cpu_hotplug.lock);
> +	mutex_lock(&cpu_lock->lock);
> +	cpu_lock->refcount++;
> +	mutex_unlock(&cpu_lock->lock);
> +}
> 
> +void get_online_cpus(void)
> +{
> +	cpu_read_lock(&cpu_hotplug);
>  }
>  EXPORT_SYMBOL_GPL(get_online_cpus);
> 
> -void put_online_cpus(void)
> +void get_online_map(void)
>  {
> -	if (cpu_hotplug.active_writer == current)
> +	cpu_read_lock(&online_map);
> +}
> +
> +void cpu_read_unlock(struct cpu_lock *cpu_lock)
> +{
> +	if (cpu_lock->active_writer == current)
>  		return;
> -	mutex_lock(&cpu_hotplug.lock);
> -	if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
> -		wake_up_process(cpu_hotplug.active_writer);
> -	mutex_unlock(&cpu_hotplug.lock);
> +	mutex_lock(&cpu_lock->lock);
> +	if (!--cpu_lock->refcount && unlikely(cpu_lock->active_writer))
> +		wake_up_process(cpu_lock->active_writer);
> +	mutex_unlock(&cpu_lock->lock);
> +}
> 
> +void put_online_cpus(void)
> +{
> +	cpu_read_unlock(&cpu_hotplug);
>  }
>  EXPORT_SYMBOL_GPL(put_online_cpus);
> 
> +void put_online_map(void)
> +{
> +	cpu_read_unlock(&online_map);
> +}
> +
>  #endif	/* CONFIG_HOTPLUG_CPU */
> 
>  /*
> @@ -91,7 +115,7 @@ void cpu_maps_update_done(void)
>   * Note that during a cpu-hotplug operation, the new readers, if any,
>   * will be blocked by the cpu_hotplug.lock
>   *
> - * Since cpu_hotplug_begin() is always called after invoking
> + * Since cpu_write_lock() is always called after invoking
>   * cpu_maps_update_begin(), we can be sure that only one writer is active.
>   *
>   * Note that theoretically, there is a possibility of a livelock:
> @@ -106,25 +130,26 @@ void cpu_maps_update_done(void)
>   * get_online_cpus() not an api which is called all that often.
>   *
>   */
> -static void cpu_hotplug_begin(void)
> +static void cpu_write_lock(struct cpu_lock *cpu_lock)
>  {
> -	cpu_hotplug.active_writer = current;
> +	cpu_lock->active_writer = current;
> 
>  	for (;;) {
> -		mutex_lock(&cpu_hotplug.lock);
> -		if (likely(!cpu_hotplug.refcount))
> +		mutex_lock(&cpu_lock->lock);
> +		if (likely(!cpu_lock->refcount))
>  			break;
>  		__set_current_state(TASK_UNINTERRUPTIBLE);
> -		mutex_unlock(&cpu_hotplug.lock);
> +		mutex_unlock(&cpu_lock->lock);
>  		schedule();
>  	}
>  }
> 
> -static void cpu_hotplug_done(void)
> +static void cpu_write_unlock(struct cpu_lock *cpu_lock)
>  {
> -	cpu_hotplug.active_writer = NULL;
> -	mutex_unlock(&cpu_hotplug.lock);
> +	cpu_lock->active_writer = NULL;
> +	mutex_unlock(&cpu_lock->lock);
>  }
> +
>  /* Need to know about CPUs going up/down? */
>  int __cpuinit register_cpu_notifier(struct notifier_block *nb)
>  {
> @@ -207,7 +232,8 @@ static int _cpu_down(unsigned int cpu, i
>  	if (!cpu_online(cpu))
>  		return -EINVAL;
> 
> -	cpu_hotplug_begin();
> +	cpu_write_lock(&cpu_hotplug);
> +	cpu_write_lock(&online_map);
>  	err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
>  					hcpu, -1, &nr_calls);
>  	if (err == NOTIFY_BAD) {
> @@ -238,6 +264,7 @@ static int _cpu_down(unsigned int cpu, i
>  			err = PTR_ERR(p);
>  			goto out_allowed;
>  		}
> +		err = -EAGAIN;
>  		goto out_thread;
>  	}
> 
> @@ -247,6 +274,7 @@ static int _cpu_down(unsigned int cpu, i
> 
>  	/* This actually kills the CPU. */
>  	__cpu_die(cpu);
> +	cpu_write_unlock(&online_map);
> 
>  	/* CPU is completely dead: tell everyone.  Too late to complain. */
>  	if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD | mod,
> @@ -260,7 +288,9 @@ out_thread:
>  out_allowed:
>  	set_cpus_allowed(current, old_allowed);
>  out_release:
> -	cpu_hotplug_done();
> +	if (err)
> +		cpu_write_unlock(&online_map);
> +	cpu_write_unlock(&cpu_hotplug);
>  	return err;
>  }
> 
> @@ -289,7 +319,8 @@ static int __cpuinit _cpu_up(unsigned in
>  	if (cpu_online(cpu) || !cpu_present(cpu))
>  		return -EINVAL;
> 
> -	cpu_hotplug_begin();
> +	cpu_write_lock(&cpu_hotplug);
> +	cpu_write_lock(&online_map);
>  	ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu,
>  							-1, &nr_calls);
>  	if (ret == NOTIFY_BAD) {
> @@ -313,7 +344,8 @@ out_notify:
>  	if (ret != 0)
>  		__raw_notifier_call_chain(&cpu_chain,
>  				CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
> -	cpu_hotplug_done();
> +	cpu_write_unlock(&online_map);
> +	cpu_write_unlock(&cpu_hotplug);
> 
>  	return ret;
>  }

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: get_online_cpus() && workqueues
  2008-04-28  7:02                             ` Gautham R Shenoy
@ 2008-04-28 10:56                               ` Oleg Nesterov
  2008-04-28 12:03                                 ` Gautham R Shenoy
  0 siblings, 1 reply; 23+ messages in thread
From: Oleg Nesterov @ 2008-04-28 10:56 UTC (permalink / raw)
  To: Gautham R Shenoy
  Cc: Heiko Carstens, Peter Zijlstra, Johannes Berg, Martin Schwidefsky,
	Srivatsa Vaddagiri, linux-kernel

On 04/28, Gautham R Shenoy wrote:
>
> On Sat, Apr 26, 2008 at 06:43:30PM +0400, Oleg Nesterov wrote:
> > 
> > Can't we add another nested lock which is dropped right after __cpu_die()?
> > (in fact I think it could be dropped after __stop_machine_run).
> > 
> > The new read-lock is get_online_map() (just a random name for now). The only
> > difference wrt get_online_cpus() is that it doesn't protect against CPU_DEAD,
> > but most users of get_online_cpus() doesn't need this, they only need a
> > stable cpu_online_map and sometimes they need to be sure that some per-cpu
> > object (say, cpu_workqueue_struct->thread) can't be destroyed under this
> > lock.
> > 
> > get_online_map() seem to fit for this, and can be used from work->func().
> > (actually, I think most users of use get_online_cpus() could use the new
> > helper instead, but this doen't matter).
> 
> However, subsystems such as cpufreq require serialization with respect
> to the whole CPU-Hotplug operation since they do initialization and
> cleanup pre and  post the change of the cpu_online_map.
> The current code, or this patch doesn't help in such cases
> when such subsystems have multithreaded workqueues!

Yes, I see, thanks. Heiko has pointed this too.

> One of the thoughts I have is to provide an API along the lines of
> try_get_online_cpus() which will return 1 if there is no CPU Hotplug
> operation in progress and will return 0 otherwise. In case where
> a cpu-hotplug operation is in progress, the workitem could simply
> do nothing other than requeue itself and wait for the cpu-hotplug
> operation to complete.

Yes, possible, but it is not nice that work->func() can't just use
get_online_cpus()...

> Else, we might want to do something like what slab.c does.
> It sets the per-cpu work.func of the cpu-going down to NULL in
> CPU_DOWN_PREPARE.

Yes, but this is different. Please note also that this particular
work must not use get_online_cpus(), no matter what changes we can
make. Otherwise cancel_delayed_work_sync() can deadlock.

What do you think about another patch I sent? I am not happy with it,
and it certainly uglifies cpu.c, but it is simple...

Oleg.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: get_online_cpus() && workqueues
  2008-04-26 14:43                           ` get_online_cpus() && workqueues Oleg Nesterov
  2008-04-27 12:22                             ` Heiko Carstens
  2008-04-28  7:02                             ` Gautham R Shenoy
@ 2008-04-28 11:57                             ` Gautham R Shenoy
  2 siblings, 0 replies; 23+ messages in thread
From: Gautham R Shenoy @ 2008-04-28 11:57 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Heiko Carstens, Peter Zijlstra, Johannes Berg, Martin Schwidefsky,
	Srivatsa Vaddagiri, linux-kernel

On Sat, Apr 26, 2008 at 06:43:30PM +0400, Oleg Nesterov wrote:
> Gautham, Srivatsa, seriously, can't we uglify cpu.c a little bit to solve
> the problem. Please see the illustration patch below. It looks complicated,
> but in fact it is quite trivial.
> 
> In short: work_struct can't use get_online_cpus() due to deadlock with the
> CPU_DEAD phase.
> 
> Can't we add another nested lock which is dropped right after __cpu_die()?
> (in fact I think it could be dropped after __stop_machine_run).
> 
> The new read-lock is get_online_map() (just a random name for now). The only
> difference wrt get_online_cpus() is that it doesn't protect against CPU_DEAD,
> but most users of get_online_cpus() doesn't need this, they only need a
> stable cpu_online_map and sometimes they need to be sure that some per-cpu
> object (say, cpu_workqueue_struct->thread) can't be destroyed under this
> lock.
> 
> get_online_map() seem to fit for this, and can be used from work->func().
> (actually, I think most users of use get_online_cpus() could use the new
> helper instead, but this doen't matter).
> 
> Heiko, what do you think? Is it suitable for arch_reinit_sched_domains()?
> 
> Oleg.
> 
> --- 25/kernel/cpu.c~HP_LOCK	2008-02-16 18:36:37.000000000 +0300
> +++ 25/kernel/cpu.c	2008-04-26 18:14:25.000000000 +0400
> @@ -25,7 +25,7 @@ static __cpuinitdata RAW_NOTIFIER_HEAD(c
>   */
>  static int cpu_hotplug_disabled;
> 
> -static struct {
> +static struct cpu_lock {
>  	struct task_struct *active_writer;
>  	struct mutex lock; /* Synchronizes accesses to refcount, */
>  	/*
> @@ -33,41 +33,65 @@ static struct {
>  	 * an ongoing cpu hotplug operation.
>  	 */
>  	int refcount;
> -} cpu_hotplug;
> +} cpu_hotplug, online_map;
> +
> +static inline void __cpu_hotplug_init(struct cpu_lock *cpu_lock)
> +{
> +	cpu_lock->active_writer = NULL;
> +	mutex_init(&cpu_lock->lock);
> +	cpu_lock->refcount = 0;
> +}
> 
>  void __init cpu_hotplug_init(void)
>  {
> -	cpu_hotplug.active_writer = NULL;
> -	mutex_init(&cpu_hotplug.lock);
> -	cpu_hotplug.refcount = 0;
> +	__cpu_hotplug_init(&cpu_hotplug);
> +	__cpu_hotplug_init(&online_map);
>  }
> 
>  #ifdef CONFIG_HOTPLUG_CPU
> 
> -void get_online_cpus(void)
> +void cpu_read_lock(struct cpu_lock *cpu_lock)
>  {
>  	might_sleep();
> -	if (cpu_hotplug.active_writer == current)
> +	if (cpu_lock->active_writer == current)
>  		return;
> -	mutex_lock(&cpu_hotplug.lock);
> -	cpu_hotplug.refcount++;
> -	mutex_unlock(&cpu_hotplug.lock);
> +	mutex_lock(&cpu_lock->lock);
> +	cpu_lock->refcount++;
> +	mutex_unlock(&cpu_lock->lock);
> +}
> 
> +void get_online_cpus(void)
> +{
> +	cpu_read_lock(&cpu_hotplug);
>  }
>  EXPORT_SYMBOL_GPL(get_online_cpus);
> 
> -void put_online_cpus(void)
> +void get_online_map(void)
>  {
> -	if (cpu_hotplug.active_writer == current)
> +	cpu_read_lock(&online_map);
> +}
> +
> +void cpu_read_unlock(struct cpu_lock *cpu_lock)
> +{
> +	if (cpu_lock->active_writer == current)
>  		return;
> -	mutex_lock(&cpu_hotplug.lock);
> -	if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
> -		wake_up_process(cpu_hotplug.active_writer);
> -	mutex_unlock(&cpu_hotplug.lock);
> +	mutex_lock(&cpu_lock->lock);
> +	if (!--cpu_lock->refcount && unlikely(cpu_lock->active_writer))
> +		wake_up_process(cpu_lock->active_writer);
> +	mutex_unlock(&cpu_lock->lock);
> +}
> 
> +void put_online_cpus(void)
> +{
> +	cpu_read_unlock(&cpu_hotplug);
>  }
>  EXPORT_SYMBOL_GPL(put_online_cpus);
> 
> +void put_online_map(void)
> +{
> +	cpu_read_unlock(&online_map);
> +}
> +
>  #endif	/* CONFIG_HOTPLUG_CPU */
> 
>  /*
> @@ -91,7 +115,7 @@ void cpu_maps_update_done(void)
>   * Note that during a cpu-hotplug operation, the new readers, if any,
>   * will be blocked by the cpu_hotplug.lock
>   *
> - * Since cpu_hotplug_begin() is always called after invoking
> + * Since cpu_write_lock() is always called after invoking
>   * cpu_maps_update_begin(), we can be sure that only one writer is active.
>   *
>   * Note that theoretically, there is a possibility of a livelock:
> @@ -106,25 +130,26 @@ void cpu_maps_update_done(void)
>   * get_online_cpus() not an api which is called all that often.
>   *
>   */
> -static void cpu_hotplug_begin(void)
> +static void cpu_write_lock(struct cpu_lock *cpu_lock)
>  {
> -	cpu_hotplug.active_writer = current;
> +	cpu_lock->active_writer = current;
> 
>  	for (;;) {
> -		mutex_lock(&cpu_hotplug.lock);
> -		if (likely(!cpu_hotplug.refcount))
> +		mutex_lock(&cpu_lock->lock);
> +		if (likely(!cpu_lock->refcount))
>  			break;
>  		__set_current_state(TASK_UNINTERRUPTIBLE);
> -		mutex_unlock(&cpu_hotplug.lock);
> +		mutex_unlock(&cpu_lock->lock);
>  		schedule();
>  	}
>  }
> 
> -static void cpu_hotplug_done(void)
> +static void cpu_write_unlock(struct cpu_lock *cpu_lock)
>  {
> -	cpu_hotplug.active_writer = NULL;
> -	mutex_unlock(&cpu_hotplug.lock);
> +	cpu_lock->active_writer = NULL;
> +	mutex_unlock(&cpu_lock->lock);
>  }
> +
>  /* Need to know about CPUs going up/down? */
>  int __cpuinit register_cpu_notifier(struct notifier_block *nb)
>  {
> @@ -207,7 +232,8 @@ static int _cpu_down(unsigned int cpu, i
>  	if (!cpu_online(cpu))
>  		return -EINVAL;
> 
> -	cpu_hotplug_begin();
> +	cpu_write_lock(&cpu_hotplug);
> +	cpu_write_lock(&online_map);

IMO, we should acquire the cpu_write_lock(&online_map)
just before __stop_machine_run() and release it once
stop_machine_run() returns.

IIUC, this lock protects only the cpu_online_map.

Ditto in case of cpu_up() where we should acquire the lock
just before calling __cpu_up() and release it immediately thereafter.


>  	err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
>  					hcpu, -1, &nr_calls);
>  	if (err == NOTIFY_BAD) {
> @@ -238,6 +264,7 @@ static int _cpu_down(unsigned int cpu, i
>  			err = PTR_ERR(p);
>  			goto out_allowed;
>  		}
> +		err = -EAGAIN;
>  		goto out_thread;
>  	}
> 
> @@ -247,6 +274,7 @@ static int _cpu_down(unsigned int cpu, i
> 
>  	/* This actually kills the CPU. */
>  	__cpu_die(cpu);
> +	cpu_write_unlock(&online_map);
> 
>  	/* CPU is completely dead: tell everyone.  Too late to complain. */
>  	if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD | mod,
> @@ -260,7 +288,9 @@ out_thread:
>  out_allowed:
>  	set_cpus_allowed(current, old_allowed);
>  out_release:
> -	cpu_hotplug_done();
> +	if (err)
> +		cpu_write_unlock(&online_map);
> +	cpu_write_unlock(&cpu_hotplug);
>  	return err;
>  }
> 
> @@ -289,7 +319,8 @@ static int __cpuinit _cpu_up(unsigned in
>  	if (cpu_online(cpu) || !cpu_present(cpu))
>  		return -EINVAL;
> 
> -	cpu_hotplug_begin();
> +	cpu_write_lock(&cpu_hotplug);
> +	cpu_write_lock(&online_map);
>  	ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu,
>  							-1, &nr_calls);
>  	if (ret == NOTIFY_BAD) {
> @@ -313,7 +344,8 @@ out_notify:
>  	if (ret != 0)
>  		__raw_notifier_call_chain(&cpu_chain,
>  				CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
> -	cpu_hotplug_done();
> +	cpu_write_unlock(&online_map);
> +	cpu_write_unlock(&cpu_hotplug);
> 
>  	return ret;
>  }

-- 
Thanks and Regards
gautham

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: get_online_cpus() && workqueues
  2008-04-28 10:56                               ` Oleg Nesterov
@ 2008-04-28 12:03                                 ` Gautham R Shenoy
  2008-04-28 12:40                                   ` Oleg Nesterov
  0 siblings, 1 reply; 23+ messages in thread
From: Gautham R Shenoy @ 2008-04-28 12:03 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Heiko Carstens, Peter Zijlstra, Johannes Berg, Martin Schwidefsky,
	Srivatsa Vaddagiri, linux-kernel

On Mon, Apr 28, 2008 at 02:56:49PM +0400, Oleg Nesterov wrote:
> On 04/28, Gautham R Shenoy wrote:
> >
> > On Sat, Apr 26, 2008 at 06:43:30PM +0400, Oleg Nesterov wrote:
> > > 
> > > Can't we add another nested lock which is dropped right after __cpu_die()?
> > > (in fact I think it could be dropped after __stop_machine_run).
> > > 
> > > The new read-lock is get_online_map() (just a random name for now). The only
> > > difference wrt get_online_cpus() is that it doesn't protect against CPU_DEAD,
> > > but most users of get_online_cpus() doesn't need this, they only need a
> > > stable cpu_online_map and sometimes they need to be sure that some per-cpu
> > > object (say, cpu_workqueue_struct->thread) can't be destroyed under this
> > > lock.
> > > 
> > > get_online_map() seem to fit for this, and can be used from work->func().
> > > (actually, I think most users of use get_online_cpus() could use the new
> > > helper instead, but this doen't matter).
> > 
> > However, subsystems such as cpufreq require serialization with respect
> > to the whole CPU-Hotplug operation since they do initialization and
> > cleanup pre and  post the change of the cpu_online_map.
> > The current code, or this patch doesn't help in such cases
> > when such subsystems have multithreaded workqueues!
> 
> Yes, I see, thanks. Heiko has pointed this too.
> 
> > One of the thoughts I have is to provide an API along the lines of
> > try_get_online_cpus() which will return 1 if there is no CPU Hotplug
> > operation in progress and will return 0 otherwise. In case where
> > a cpu-hotplug operation is in progress, the workitem could simply
> > do nothing other than requeue itself and wait for the cpu-hotplug
> > operation to complete.
>
> Yes, possible, but it is not nice that work->func() can't just use
> get_online_cpus()...

Like I said, it depends on what they want to use it for. If it is just
protection against the changing of the cpu_online_map then, it's simple
as using get_online_map(), i.e the patch you provided.

BTW, the other thing I am concerned about is the
naming. Dont the names get_online_cpus() and get_online_map()
appear very similar. The last thing we want is driver writers getting
confused over what API to use!

>
> > Else, we might want to do something like what slab.c does.
> > It sets the per-cpu work.func of the cpu-going down to NULL in
> > CPU_DOWN_PREPARE.


>
> Yes, but this is different. Please note also that this particular
> work must not use get_online_cpus(), no matter what changes we can
> make. Otherwise cancel_delayed_work_sync() can deadlock.
>
> What do you think about another patch I sent? I am not happy with it,
> and it certainly uglifies cpu.c, but it is simple...

I am currently testing out the patchstack sent
by peterz. Once that's done I will see if I can integrate this patch
with the previous patches and repost the whole series.

>
> Oleg.

-- 
Thanks and Regards
gautham

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: get_online_cpus() && workqueues
  2008-04-28 12:03                                 ` Gautham R Shenoy
@ 2008-04-28 12:40                                   ` Oleg Nesterov
  0 siblings, 0 replies; 23+ messages in thread
From: Oleg Nesterov @ 2008-04-28 12:40 UTC (permalink / raw)
  To: Gautham R Shenoy
  Cc: Heiko Carstens, Peter Zijlstra, Johannes Berg, Martin Schwidefsky,
	Srivatsa Vaddagiri, linux-kernel

On 04/28, Gautham R Shenoy wrote:
>
> On Mon, Apr 28, 2008 at 02:56:49PM +0400, Oleg Nesterov wrote:
> >
> > Yes, possible, but it is not nice that work->func() can't just use
> > get_online_cpus()...
> 
> Like I said, it depends on what they want to use it for. If it is just
> protection against the changing of the cpu_online_map then, it's simple
> as using get_online_map(), i.e the patch you provided.
> 
> BTW, the other thing I am concerned about is the
> naming. Dont the names get_online_cpus() and get_online_map()
> appear very similar. The last thing we want is driver writers getting
> confused over what API to use!

Yes, yes, please forget this patch. I don't like 2 very similar nested
locks, this was a bad idea. I am talking about another (uncompiled)
patch I sent.

> > What do you think about another patch I sent? I am not happy with it,
> > and it certainly uglifies cpu.c, but it is simple...
>
> I am currently testing out the patchstack sent
> by peterz. Once that's done I will see if I can integrate this patch
> with the previous patches and repost the whole series.

OK.

Oleg.


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2008-04-28 12:40 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-14  3:04 2.6.25-rc9 -- INFO: possible circular locking dependency detected Miles Lane
2008-04-14  3:29 ` Miles Lane
2008-04-14  6:54 ` Peter Zijlstra
2008-04-14  7:02   ` Heiko Carstens
2008-04-14  7:18     ` Ingo Molnar
2008-04-14 12:06   ` Peter Zijlstra
2008-04-14 12:27     ` Gautham R Shenoy
2008-04-14 12:42       ` Peter Zijlstra
2008-04-14 13:28         ` Gautham R Shenoy
2008-04-14 14:48         ` Gautham R Shenoy
2008-04-14 15:19           ` Heiko Carstens
2008-04-14 15:46             ` Gautham R Shenoy
2008-04-14 19:35               ` Heiko Carstens
2008-04-15 13:52                 ` Gautham R Shenoy
2008-04-15 14:37                   ` Heiko Carstens
     [not found]         ` <20080422123304.GA777@osiris.boeblingen.de.ibm.com>
     [not found]           ` <1208868236.7115.249.camel@twins>
     [not found]             ` <20080423035802.GA8895@in.ibm.com>
     [not found]               ` <20080424150714.GA8273@osiris.boeblingen.de.ibm.com>
     [not found]                 ` <1209052984.7115.369.camel@twins>
     [not found]                   ` <20080424155946.GA11160@tv-sign.ru>
     [not found]                     ` <20080424194810.GA4821@osiris.boeblingen.de.ibm.com>
     [not found]                       ` <20080424192706.GA165@tv-sign.ru>
     [not found]                         ` <20080425064044.GA10817@osiris.boeblingen.de.ibm.com>
2008-04-26 14:43                           ` get_online_cpus() && workqueues Oleg Nesterov
2008-04-27 12:22                             ` Heiko Carstens
2008-04-27 14:25                               ` Oleg Nesterov
2008-04-28  7:02                             ` Gautham R Shenoy
2008-04-28 10:56                               ` Oleg Nesterov
2008-04-28 12:03                                 ` Gautham R Shenoy
2008-04-28 12:40                                   ` Oleg Nesterov
2008-04-28 11:57                             ` Gautham R Shenoy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox