* [BUG] long freezes on thinkpad t60
@ 2007-05-24 12:04 Miklos Szeredi
2007-05-24 12:54 ` Ingo Molnar
2007-05-24 22:08 ` Henrique de Moraes Holschuh
0 siblings, 2 replies; 13+ messages in thread
From: Miklos Szeredi @ 2007-05-24 12:04 UTC (permalink / raw)
To: linux-kernel; +Cc: mingo, linux-acpi
On some strange workload involving strace and fuse I get ocasional
long periods (10-100s) of total unresponsiveness, not even SysRq-*
working. Then the machine continues as normal. Nothing in dmesg,
absolutely no indication about what is happening.
Tried nmi_watchdog=1, but then the machine locks up hard shortly after
boot.
Tried nmi_watchdog=1 acpi=off, then I can't reproduce the problem.
Tried 2.6.22-rc2 and 2.6.21, both with the same result.
.config and dmesg attached.
Any ideas? Possibly something ACPI related?
Thanks,
Miklos
Linux version 2.6.22-rc2 (mszeredi@tucsk) (gcc version 4.1.2 20061115 (prerelease) (SUSE Linux)) #3 SMP Tue May 22 17:55:42 CEST 2007
Command line: root=/dev/sda2
BIOS-provided physical RAM map:
BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
BIOS-e820: 000000000009f000 - 00000000000a0000 (reserved)
BIOS-e820: 00000000000d2000 - 00000000000d4000 (reserved)
BIOS-e820: 00000000000dc000 - 0000000000100000 (reserved)
BIOS-e820: 0000000000100000 - 000000003fed0000 (usable)
BIOS-e820: 000000003fed0000 - 000000003fedf000 (ACPI data)
BIOS-e820: 000000003fedf000 - 000000003ff00000 (ACPI NVS)
BIOS-e820: 000000003ff00000 - 0000000040000000 (reserved)
BIOS-e820: 00000000f0000000 - 00000000f4000000 (reserved)
BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved)
BIOS-e820: 00000000fed00000 - 00000000fed00400 (reserved)
BIOS-e820: 00000000fed14000 - 00000000fed1a000 (reserved)
BIOS-e820: 00000000fed1c000 - 00000000fed90000 (reserved)
BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
BIOS-e820: 00000000ff800000 - 0000000100000000 (reserved)
Entering add_active_range(0, 0, 159) 0 entries of 256 used
Entering add_active_range(0, 256, 261840) 1 entries of 256 used
end_pfn_map = 1048576
DMI present.
ACPI: RSDP 000F67D0, 0024 (r2 LENOVO)
ACPI: XSDT 3FED1308, 008C (r1 LENOVO TP-79 2110 LTP 0)
ACPI: FACP 3FED1400, 00F4 (r3 LENOVO TP-79 2110 LNVO 1)
ACPI Warning (tbfadt-0434): Optional field "Gpe1Block" has zero address or length: 000000000000102C/0 [20070126]
ACPI: DSDT 3FED175E, D481 (r1 LENOVO TP-79 2110 MSFT 100000E)
ACPI: FACS 3FEF4000, 0040
ACPI: SSDT 3FED15B4, 01AA (r1 LENOVO TP-79 2110 MSFT 100000E)
ACPI: ECDT 3FEDEBDF, 0052 (r1 LENOVO TP-79 2110 LNVO 1)
ACPI: TCPA 3FEDEC31, 0032 (r2 LENOVO TP-79 2110 LNVO 1)
ACPI: APIC 3FEDEC63, 0068 (r1 LENOVO TP-79 2110 LNVO 1)
ACPI: MCFG 3FEDECCB, 003C (r1 LENOVO TP-79 2110 LNVO 1)
ACPI: HPET 3FEDED07, 0038 (r1 LENOVO TP-79 2110 LNVO 1)
ACPI: SLIC 3FEDEE62, 0176 (r1 LENOVO TP-79 2110 LTP 0)
ACPI: BOOT 3FEDEFD8, 0028 (r1 LENOVO TP-79 2110 LTP 1)
ACPI: SSDT 3FEF2655, 025F (r1 LENOVO TP-79 2110 INTL 20050513)
ACPI: SSDT 3FEF28B4, 00A6 (r1 LENOVO TP-79 2110 INTL 20050513)
ACPI: SSDT 3FEF295A, 04F7 (r1 LENOVO TP-79 2110 INTL 20050513)
ACPI: SSDT 3FEF2E51, 01D8 (r1 LENOVO TP-79 2110 INTL 20050513)
Entering add_active_range(0, 0, 159) 0 entries of 256 used
Entering add_active_range(0, 256, 261840) 1 entries of 256 used
Zone PFN ranges:
DMA 0 -> 4096
DMA32 4096 -> 1048576
Normal 1048576 -> 1048576
early_node_map[2] active PFN ranges
0: 0 -> 159
0: 256 -> 261840
On node 0 totalpages: 261743
DMA zone: 56 pages used for memmap
DMA zone: 1115 pages reserved
DMA zone: 2828 pages, LIFO batch:0
DMA32 zone: 3523 pages used for memmap
DMA32 zone: 254221 pages, LIFO batch:31
Normal zone: 0 pages used for memmap
ACPI: PM-Timer IO Port: 0x1008
ACPI: Local APIC address 0xfee00000
ACPI: LAPIC (acpi_id[0x00] lapic_id[0x00] enabled)
Processor #0 (Bootup-CPU)
ACPI: LAPIC (acpi_id[0x01] lapic_id[0x01] enabled)
Processor #1
ACPI: LAPIC_NMI (acpi_id[0x00] high edge lint[0x1])
ACPI: LAPIC_NMI (acpi_id[0x01] high edge lint[0x1])
ACPI: IOAPIC (id[0x01] address[0xfec00000] gsi_base[0])
IOAPIC[0]: apic_id 1, address 0xfec00000, GSI 0-23
ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
ACPI: IRQ0 used by override.
ACPI: IRQ2 used by override.
ACPI: IRQ9 used by override.
Setting APIC routing to flat
ACPI: HPET id: 0x8086a201 base: 0xfed00000
Using ACPI (MADT) for SMP configuration information
swsusp: Registered nosave memory region: 000000000009f000 - 00000000000a0000
swsusp: Registered nosave memory region: 00000000000a0000 - 00000000000d2000
swsusp: Registered nosave memory region: 00000000000d2000 - 00000000000d4000
swsusp: Registered nosave memory region: 00000000000d4000 - 00000000000dc000
swsusp: Registered nosave memory region: 00000000000dc000 - 0000000000100000
Allocating PCI resources starting at 50000000 (gap: 40000000:b0000000)
SMP: Allowing 2 CPUs, 0 hotplug CPUs
PERCPU: Allocating 32616 bytes of per cpu data
Built 1 zonelists. Total pages: 257049
Kernel command line: root=/dev/sda2
Initializing CPU#0
PID hash table entries: 4096 (order: 12, 32768 bytes)
Extended CMOS year: 2000
Marking TSC unstable due to TSCs unsynchronized
time.c: Detected 1828.747 MHz processor.
Console: colour VGA+ 80x25
Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes)
Inode-cache hash table entries: 65536 (order: 7, 524288 bytes)
Checking aperture...
Memory: 1026060k/1047360k available (2254k kernel code, 20612k reserved, 1395k data, 184k init)
Calibrating delay using timer specific routine.. 3662.19 BogoMIPS (lpj=7324383)
Mount-cache hash table entries: 256
CPU: L1 I cache: 32K, L1 D cache: 32K
CPU: L2 cache: 2048K
using mwait in idle threads.
CPU: Physical Processor ID: 0
CPU: Processor Core ID: 0
CPU0: Thermal monitoring enabled (TM2)
SMP alternatives: switching to UP code
ACPI: Core revision 20070126
Using local APIC timer interrupts.
result 10390601
Detected 10.390 MHz APIC timer.
SMP alternatives: switching to SMP code
Booting processor 1/2 APIC 0x1
Initializing CPU#1
Calibrating delay using timer specific routine.. 3657.64 BogoMIPS (lpj=7315290)
CPU: L1 I cache: 32K, L1 D cache: 32K
CPU: L2 cache: 2048K
CPU: Physical Processor ID: 0
CPU: Processor Core ID: 1
CPU1: Thermal monitoring enabled (TM2)
Intel(R) Core(TM)2 CPU T5600 @ 1.83GHz stepping 06
Brought up 2 CPUs
migration_cost=28
NET: Registered protocol family 16
ACPI: bus type pci registered
PCI: Using configuration type 1
ACPI: Interpreter enabled
ACPI: (supports S0 S3 S4 S5)
ACPI: Using IOAPIC for interrupt routing
ACPI: PCI Root Bridge [PCI0] (0000:00)
PCI: Probing PCI hardware (bus 00)
PCI quirk: region 1000-107f claimed by ICH6 ACPI/GPIO/TCO
PCI quirk: region 1180-11bf claimed by ICH6 GPIO
PCI: Transparent bridge - 0000:00:1e.0
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.AGP_._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.EXP0._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.EXP1._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.EXP2._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.EXP3._PRT]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.PCI1._PRT]
ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 5 6 7 9 10 *11)
ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 6 7 9 10 *11)
ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 5 6 7 9 10 *11)
ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 6 7 9 10 *11)
ACPI: PCI Interrupt Link [LNKE] (IRQs 3 4 5 6 7 9 10 *11)
ACPI: PCI Interrupt Link [LNKF] (IRQs 3 4 5 6 7 9 10 *11)
ACPI: PCI Interrupt Link [LNKG] (IRQs 3 4 5 6 7 9 10 *11)
ACPI: PCI Interrupt Link [LNKH] (IRQs 3 4 5 6 7 9 10 *11)
ACPI: Power Resource [PUBS] (on)
Linux Plug and Play Support v0.97 (c) Adam Belay
pnp: PnP ACPI init
ACPI: bus type pnp registered
pnp: PnP ACPI: found 12 devices
ACPI: ACPI bus type pnp unregistered
SCSI subsystem initialized
libata version 2.20 loaded.
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
PCI: Using ACPI for IRQ routing
PCI: If a device doesn't work, try "pci=routeirq". If it helps, post a report
BUG: at mm/slab.c:777 __find_general_cachep()
Call Trace:
[<ffffffff8026fe8b>] __kmalloc+0x3e/0xbe
[<ffffffff8021c337>] cache_k8_northbridges+0x7f/0xf0
[<ffffffff805b2e7d>] gart_iommu_init+0x13/0x4f4
[<ffffffff80227ce1>] __wake_up+0x38/0x4f
[<ffffffff803ec306>] genl_rcv+0x0/0x59
[<ffffffff803eadaf>] netlink_kernel_create+0x12c/0x156
[<ffffffff8042fda3>] mutex_lock+0xd/0x1e
[<ffffffff805aed1b>] pci_iommu_init+0x9/0x12
[<ffffffff805ac600>] kernel_init+0x167/0x2d1
[<ffffffff8020a3e8>] child_rip+0xa/0x12
[<ffffffff802f4538>] acpi_ds_init_one_object+0x0/0x7c
[<ffffffff805ac499>] kernel_init+0x0/0x2d1
[<ffffffff8020a3de>] child_rip+0x0/0x12
PCI-GART: No AMD northbridge found.
hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0
hpet0: 3 64-bit timers, 14318180 Hz
pnp: 00:00: iomem range 0x0-0x9ffff could not be reserved
pnp: 00:00: iomem range 0xc0000-0xc3fff has been reserved
Time: hpet clocksource has been installed.
pnp: 00:00: iomem range 0xc4000-0xc7fff has been reserved
pnp: 00:00: iomem range 0xc8000-0xcbfff has been reserved
pnp: 00:02: iomem range 0xf0000000-0xf3ffffff could not be reserved
pnp: 00:02: iomem range 0xfed1c000-0xfed1ffff could not be reserved
pnp: 00:02: iomem range 0xfed14000-0xfed17fff could not be reserved
pnp: 00:02: iomem range 0xfed18000-0xfed18fff could not be reserved
PCI: Bridge: 0000:00:01.0
IO window: 2000-2fff
MEM window: ee100000-ee1fffff
PREFETCH window: d8000000-dfffffff
PCI: Bridge: 0000:00:1c.0
IO window: 3000-3fff
MEM window: ee000000-ee0fffff
PREFETCH window: disabled.
PCI: Bridge: 0000:00:1c.1
IO window: 4000-5fff
MEM window: ec000000-edffffff
PREFETCH window: e4000000-e40fffff
PCI: Bridge: 0000:00:1c.2
IO window: 6000-7fff
MEM window: e8000000-e9ffffff
PREFETCH window: e4100000-e41fffff
PCI: Bridge: 0000:00:1c.3
IO window: 8000-9fff
MEM window: ea000000-ebffffff
PREFETCH window: e4200000-e42fffff
PCI: Bus 22, cardbus bridge: 0000:15:00.0
IO window: 0000a000-0000a0ff
IO window: 0000a400-0000a4ff
PREFETCH window: e0000000-e3ffffff
MEM window: 50000000-53ffffff
PCI: Bridge: 0000:00:1e.0
IO window: a000-dfff
MEM window: e4300000-e7ffffff
PREFETCH window: e0000000-e3ffffff
ACPI: PCI Interrupt 0000:00:01.0[A] -> GSI 16 (level, low) -> IRQ 16
PCI: Setting latency timer of device 0000:00:01.0 to 64
ACPI: PCI Interrupt 0000:00:1c.0[A] -> GSI 20 (level, low) -> IRQ 20
PCI: Setting latency timer of device 0000:00:1c.0 to 64
ACPI: PCI Interrupt 0000:00:1c.1[B] -> GSI 21 (level, low) -> IRQ 21
PCI: Setting latency timer of device 0000:00:1c.1 to 64
ACPI: PCI Interrupt 0000:00:1c.2[C] -> GSI 22 (level, low) -> IRQ 22
PCI: Setting latency timer of device 0000:00:1c.2 to 64
ACPI: PCI Interrupt 0000:00:1c.3[D] -> GSI 23 (level, low) -> IRQ 23
PCI: Setting latency timer of device 0000:00:1c.3 to 64
PCI: Enabling device 0000:00:1e.0 (0005 -> 0007)
PCI: Setting latency timer of device 0000:00:1e.0 to 64
ACPI: PCI Interrupt 0000:15:00.0[A] -> GSI 16 (level, low) -> IRQ 16
NET: Registered protocol family 2
IP route cache hash table entries: 32768 (order: 6, 262144 bytes)
TCP established hash table entries: 131072 (order: 9, 3145728 bytes)
TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
TCP: Hash tables configured (established 131072 bind 65536)
TCP reno registered
Simple Boot Flag at 0x35 set to 0x1
io scheduler noop registered
io scheduler cfq registered (default)
Boot video device is 0000:01:00.0
PCI: Setting latency timer of device 0000:00:01.0 to 64
assign_interrupt_mode Found MSI capability
Allocate Port Service[0000:00:01.0:pcie00]
PCI: Setting latency timer of device 0000:00:1c.0 to 64
assign_interrupt_mode Found MSI capability
Allocate Port Service[0000:00:1c.0:pcie00]
Allocate Port Service[0000:00:1c.0:pcie02]
PCI: Setting latency timer of device 0000:00:1c.1 to 64
assign_interrupt_mode Found MSI capability
Allocate Port Service[0000:00:1c.1:pcie00]
Allocate Port Service[0000:00:1c.1:pcie02]
PCI: Setting latency timer of device 0000:00:1c.2 to 64
assign_interrupt_mode Found MSI capability
Allocate Port Service[0000:00:1c.2:pcie00]
Allocate Port Service[0000:00:1c.2:pcie02]
PCI: Setting latency timer of device 0000:00:1c.3 to 64
assign_interrupt_mode Found MSI capability
Allocate Port Service[0000:00:1c.3:pcie00]
Allocate Port Service[0000:00:1c.3:pcie02]
ACPI: AC Adapter [AC] (on-line)
ACPI: Battery Slot [BAT0] (battery absent)
input: Power Button (FF) as /class/input/input0
ACPI: Power Button (FF) [PWRF]
input: Lid Switch as /class/input/input1
ACPI: Lid Switch [LID]
input: Sleep Button (CM) as /class/input/input2
ACPI: Sleep Button (CM) [SLPB]
ACPI: SSDT 3FEF1D36, 0240 (r1 PmRef Cpu0Ist 100 INTL 20050513)
ACPI: SSDT 3FEF1FFB, 065A (r1 PmRef Cpu0Cst 100 INTL 20050513)
Monitor-Mwait will be used to enter C-1 state
Monitor-Mwait will be used to enter C-2 state
Monitor-Mwait will be used to enter C-3 state
ACPI: CPU0 (power states: C1[C1] C2[C2] C3[C3])
ACPI: Processor [CPU0] (supports 8 throttling states)
ACPI: SSDT 3FEF1C6E, 00C8 (r1 PmRef Cpu1Ist 100 INTL 20050513)
ACPI: SSDT 3FEF1F76, 0085 (r1 PmRef Cpu1Cst 100 INTL 20050513)
ACPI: CPU1 (power states: C1[C1] C2[C2] C3[C3])
ACPI: Processor [CPU1] (supports 8 throttling states)
ACPI: Thermal Zone [THM0] (39 C)
ACPI: Thermal Zone [THM1] (39 C)
Real Time Clock Driver v1.12ac
hpet_resources: 0xfed00000 is busy
Linux agpgart interface v0.102 (c) Dave Jones
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
loop: module loaded
thinkpad_acpi: ThinkPad ACPI Extras v0.14
thinkpad_acpi: http://ibm-acpi.sf.net/
thinkpad_acpi: ThinkPad EC firmware 79HT50WW-1.07
tun: Universal TUN/TAP device driver, 1.6
tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
ICH7: IDE controller at PCI slot 0000:00:1f.1
ACPI: PCI Interrupt 0000:00:1f.1[C] -> GSI 16 (level, low) -> IRQ 16
ICH7: chipset revision 2
ICH7: not 100% native mode: will probe irqs later
ide0: BM-DMA at 0x1880-0x1887, BIOS settings: hda:DMA, hdb:pio
Probing IDE interface ide0...
hda: MATSHITADVD-RAM UJ-842, ATAPI CD/DVD-ROM drive
hda: selected mode 0x42
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
Probing IDE interface ide1...
hda: ATAPI 24X DVD-ROM DVD-R-RAM CD-R/RW drive, 2048kB Cache, UDMA(33)
Uniform CD-ROM driver Revision: 3.20
ahci 0000:00:1f.2: version 2.1
ACPI: PCI Interrupt 0000:00:1f.2[B] -> GSI 16 (level, low) -> IRQ 16
ahci 0000:00:1f.2: AHCI 0001.0100 32 slots 4 ports 1.5 Gbps 0xf impl SATA mode
ahci 0000:00:1f.2: flags: 64bit ncq pm led clo pio slum part
PCI: Setting latency timer of device 0000:00:1f.2 to 64
scsi0 : ahci
scsi1 : ahci
scsi2 : ahci
scsi3 : ahci
ata1: SATA max UDMA/133 cmd 0xffffc2000003a500 ctl 0x0000000000000000 bmdma 0x0000000000000000 irq 0
ata2: SATA max UDMA/133 cmd 0xffffc2000003a580 ctl 0x0000000000000000 bmdma 0x0000000000000000 irq 0
ata3: SATA max UDMA/133 cmd 0xffffc2000003a600 ctl 0x0000000000000000 bmdma 0x0000000000000000 irq 0
ata4: SATA max UDMA/133 cmd 0xffffc2000003a680 ctl 0x0000000000000000 bmdma 0x0000000000000000 irq 0
ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
ata1.00: ata_hpa_resize 1: sectors = 156301488, hpa_sectors = 156301488
ata1.00: ATA-7: HTS541080G9SA00, MB4IC60R, max UDMA/100
ata1.00: 156301488 sectors, multi 16: LBA48
ata1.00: ata_hpa_resize 1: sectors = 156301488, hpa_sectors = 156301488
ata1.00: configured for UDMA/100
ata2: SATA link down (SStatus 0 SControl 0)
ata3: SATA link down (SStatus 0 SControl 0)
ata4: SATA link down (SStatus 0 SControl 0)
scsi 0:0:0:0: Direct-Access ATA HTS541080G9SA00 MB4I PQ: 0 ANSI: 5
sd 0:0:0:0: [sda] 156301488 512-byte hardware sectors (80026 MB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
sd 0:0:0:0: [sda] 156301488 512-byte hardware sectors (80026 MB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
sda: sda1 sda2 sda3 < sda5 >
sd 0:0:0:0: [sda] Attached SCSI disk
sd 0:0:0:0: Attached scsi generic sg0 type 0
usbmon: debugfs is not available
ACPI: PCI Interrupt 0000:00:1d.7[D] -> GSI 19 (level, low) -> IRQ 19
PCI: Setting latency timer of device 0000:00:1d.7 to 64
ehci_hcd 0000:00:1d.7: EHCI Host Controller
ehci_hcd 0000:00:1d.7: new USB bus registered, assigned bus number 1
ehci_hcd 0000:00:1d.7: debug port 1
PCI: cache line size of 32 is not supported by device 0000:00:1d.7
ehci_hcd 0000:00:1d.7: irq 19, io mem 0xee404000
ehci_hcd 0000:00:1d.7: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 8 ports detected
USB Universal Host Controller Interface driver v3.0
ACPI: PCI Interrupt 0000:00:1d.0[A] -> GSI 16 (level, low) -> IRQ 16
PCI: Setting latency timer of device 0000:00:1d.0 to 64
uhci_hcd 0000:00:1d.0: UHCI Host Controller
uhci_hcd 0000:00:1d.0: new USB bus registered, assigned bus number 2
uhci_hcd 0000:00:1d.0: irq 16, io base 0x00001800
usb usb2: configuration #1 chosen from 1 choice
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 2 ports detected
ACPI: PCI Interrupt 0000:00:1d.1[B] -> GSI 17 (level, low) -> IRQ 17
PCI: Setting latency timer of device 0000:00:1d.1 to 64
uhci_hcd 0000:00:1d.1: UHCI Host Controller
uhci_hcd 0000:00:1d.1: new USB bus registered, assigned bus number 3
uhci_hcd 0000:00:1d.1: irq 17, io base 0x00001820
usb usb3: configuration #1 chosen from 1 choice
hub 3-0:1.0: USB hub found
hub 3-0:1.0: 2 ports detected
ACPI: PCI Interrupt 0000:00:1d.2[C] -> GSI 18 (level, low) -> IRQ 18
PCI: Setting latency timer of device 0000:00:1d.2 to 64
uhci_hcd 0000:00:1d.2: UHCI Host Controller
uhci_hcd 0000:00:1d.2: new USB bus registered, assigned bus number 4
uhci_hcd 0000:00:1d.2: irq 18, io base 0x00001840
usb usb4: configuration #1 chosen from 1 choice
hub 4-0:1.0: USB hub found
hub 4-0:1.0: 2 ports detected
ACPI: PCI Interrupt 0000:00:1d.3[D] -> GSI 19 (level, low) -> IRQ 19
PCI: Setting latency timer of device 0000:00:1d.3 to 64
uhci_hcd 0000:00:1d.3: UHCI Host Controller
uhci_hcd 0000:00:1d.3: new USB bus registered, assigned bus number 5
uhci_hcd 0000:00:1d.3: irq 19, io base 0x00001860
usb usb5: configuration #1 chosen from 1 choice
hub 5-0:1.0: USB hub found
hub 5-0:1.0: 2 ports detected
PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
serio: i8042 KBD port at 0x60,0x64 irq 1
serio: i8042 AUX port at 0x60,0x64 irq 12
mice: PS/2 mouse device common for all mice
input: AT Translated Set 2 keyboard as /class/input/input3
coretemp: This driver uses undocumented features of Core CPU. Temperature might be wrong!
usb 2-2: new low speed USB device using uhci_hcd and address 2
usb 2-2: configuration #1 chosen from 1 choice
Synaptics Touchpad, model: 1, fw: 6.2, id: 0x81a0b1, caps: 0xa04793/0x300000
serio: Synaptics pass-through port at isa0060/serio1/input0
usb 5-2: new full speed USB device using uhci_hcd and address 2
input: SynPS/2 Synaptics TouchPad as /class/input/input4
usb 5-2: configuration #1 chosen from 1 choice
input: Microsoft Basic Optical Mouse as /class/input/input5
input: USB HID v1.10 Mouse [Microsoft Basic Optical Mouse] on usb-0000:00:1d.0-2
usbcore: registered new interface driver usbhid
drivers/hid/usbhid/hid-core.c: v2.6:USB HID core driver
Advanced Linux Sound Architecture Driver Version 1.0.14rc4 (Wed May 16 09:45:46 2007 UTC).
ACPI: PCI Interrupt 0000:00:1b.0[B] -> GSI 17 (level, low) -> IRQ 17
PCI: Setting latency timer of device 0000:00:1b.0 to 64
ALSA device list:
#0: HDA Intel at 0xee400000 irq 17
Netfilter messages via NETLINK v0.30.
nf_conntrack version 0.5.0 (4091 buckets, 32728 max)
ip_tables: (C) 2000-2006 Netfilter Core Team
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
IBM TrackPoint firmware: 0x0e, buttons: 3/3
input: TPPS/2 IBM TrackPoint as /class/input/input6
EXT3-fs: INFO: recovery required on readonly filesystem.
EXT3-fs: write access will be enabled during recovery.
kjournald starting. Commit interval 5 seconds
EXT3-fs: recovery complete.
EXT3-fs: mounted filesystem with ordered data mode.
VFS: Mounted root (ext3 filesystem) readonly.
Freeing unused kernel memory: 184k freed
Intel(R) PRO/1000 Network Driver - version 7.3.20-k2
Copyright (c) 1999-2006 Intel Corporation.
ACPI: PCI Interrupt 0000:02:00.0[A] -> GSI 16 (level, low) -> IRQ 16
PCI: Setting latency timer of device 0000:02:00.0 to 64
e1000: 0000:02:00.0: e1000_validate_option: Receive Interrupt Delay set to 32
e1000: 0000:02:00.0: e1000_probe: (PCI Express:2.5Gb/s:Width x1) 00:16:41:e3:2c:76
e1000: eth0: e1000_probe: Intel(R) PRO/1000 Network Connection
Adding 1542196k swap on /dev/sda1. Priority:-1 extents:1 across:1542196k
EXT3 FS on sda2, internal journal
fuse init (API version 7.8)
e1000: eth0: e1000_watchdog: NIC Link is Up 100 Mbps Full Duplex, Flow Control: RX/TX
e1000: eth0: e1000_watchdog: 10/100 speed: disabling TSO
IA-32 Microcode Update Driver: v1.14a <tigran@aivazian.fsnet.co.uk>
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.22-rc2
# Tue May 22 16:51:07 2007
#
CONFIG_X86_64=y
CONFIG_64BIT=y
CONFIG_X86=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_ZONE_DMA32=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_CMPXCHG=y
CONFIG_EARLY_PRINTK=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_DMI=y
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=18
# CONFIG_CPUSETS is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
# CONFIG_BLK_DEV_INITRD is not set
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_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_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
#
# Loadable module support
#
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
#
# Block layer
#
CONFIG_BLOCK=y
# CONFIG_BLK_DEV_IO_TRACE is not set
#
# 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"
#
# Processor type and features
#
CONFIG_X86_PC=y
# CONFIG_X86_VSMP is not set
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
CONFIG_MCORE2=y
# CONFIG_GENERIC_CPU is not set
CONFIG_X86_L1_CACHE_BYTES=64
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_INTERNODE_CACHE_BYTES=64
CONFIG_X86_TSC=y
CONFIG_X86_GOOD_APIC=y
CONFIG_MICROCODE=m
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
CONFIG_X86_HT=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_MTRR=y
CONFIG_SMP=y
# CONFIG_SCHED_SMT is not set
CONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_BKL is not set
# CONFIG_NUMA is not set
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_NR_CPUS=2
CONFIG_HOTPLUG_CPU=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_IOMMU=y
# CONFIG_CALGARY_IOMMU is not set
CONFIG_SWIOTLB=y
CONFIG_X86_MCE=y
CONFIG_X86_MCE_INTEL=y
# CONFIG_X86_MCE_AMD is not set
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_START=0x200000
# CONFIG_SECCOMP is not set
# CONFIG_CC_STACKPROTECTOR is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_K8_NB=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_ISA_DMA_API=y
CONFIG_GENERIC_PENDING_IRQ=y
#
# Power management options
#
CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
CONFIG_SOFTWARE_SUSPEND=y
CONFIG_PM_STD_PARTITION=""
CONFIG_SUSPEND_SMP=y
#
# ACPI (Advanced Configuration and Power Interface) Support
#
CONFIG_ACPI=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_SLEEP_PROC_FS=y
# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_AC=y
CONFIG_ACPI_BATTERY=y
CONFIG_ACPI_BUTTON=y
# CONFIG_ACPI_VIDEO is not set
CONFIG_ACPI_FAN=y
# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=y
# CONFIG_ACPI_ASUS is not set
# CONFIG_ACPI_TOSHIBA is not set
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
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
#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
# CONFIG_CPU_FREQ_DEBUG is not set
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
#
# CPUFreq processor drivers
#
# CONFIG_X86_POWERNOW_K8 is not set
# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
CONFIG_X86_ACPI_CPUFREQ=y
#
# shared options
#
# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
# CONFIG_X86_SPEEDSTEP_LIB is not set
#
# Bus options (PCI etc.)
#
CONFIG_PCI=y
CONFIG_PCI_DIRECT=y
# CONFIG_PCI_MMCONFIG is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_HT_IRQ is not set
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_IA32_EMULATION=y
# CONFIG_IA32_AOUT is not set
CONFIG_COMPAT=y
CONFIG_SYSVIPC_COMPAT=y
#
# Networking
#
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# 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 is not set
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
#
# IP: Virtual Server Configuration
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_NETLINK=y
# CONFIG_NETFILTER_NETLINK_QUEUE is not set
# CONFIG_NETFILTER_NETLINK_LOG is not set
CONFIG_NF_CONNTRACK_ENABLED=y
CONFIG_NF_CONNTRACK=y
# CONFIG_NF_CT_ACCT is not set
# CONFIG_NF_CONNTRACK_MARK is not set
# CONFIG_NF_CONNTRACK_EVENTS is not set
# CONFIG_NF_CT_PROTO_SCTP is not set
# CONFIG_NF_CONNTRACK_AMANDA is not set
# CONFIG_NF_CONNTRACK_FTP is not set
# CONFIG_NF_CONNTRACK_H323 is not set
# CONFIG_NF_CONNTRACK_IRC is not set
# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
# CONFIG_NF_CONNTRACK_PPTP is not set
# CONFIG_NF_CONNTRACK_SANE is not set
# CONFIG_NF_CONNTRACK_SIP is not set
# CONFIG_NF_CONNTRACK_TFTP is not set
# CONFIG_NF_CT_NETLINK is not set
CONFIG_NETFILTER_XTABLES=y
# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
# CONFIG_NETFILTER_XT_TARGET_MARK is not set
# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
# CONFIG_NETFILTER_XT_MATCH_ESP is not set
# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
# CONFIG_NETFILTER_XT_MATCH_MAC is not set
# CONFIG_NETFILTER_XT_MATCH_MARK is not set
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
# CONFIG_NETFILTER_XT_MATCH_REALM is not set
# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
CONFIG_NETFILTER_XT_MATCH_STATE=y
# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
# CONFIG_NETFILTER_XT_MATCH_STRING is not set
# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
#
# IP: Netfilter Configuration
#
CONFIG_NF_CONNTRACK_IPV4=y
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
# CONFIG_IP_NF_QUEUE is not set
CONFIG_IP_NF_IPTABLES=y
# CONFIG_IP_NF_MATCH_IPRANGE is not set
# CONFIG_IP_NF_MATCH_TOS is not set
# CONFIG_IP_NF_MATCH_RECENT is not set
# CONFIG_IP_NF_MATCH_ECN is not set
# CONFIG_IP_NF_MATCH_AH is not set
# CONFIG_IP_NF_MATCH_TTL is not set
# CONFIG_IP_NF_MATCH_OWNER is not set
# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_TARGET_LOG=y
# CONFIG_IP_NF_TARGET_ULOG is not set
CONFIG_NF_NAT=y
CONFIG_NF_NAT_NEEDED=y
# CONFIG_IP_NF_TARGET_MASQUERADE is not set
# CONFIG_IP_NF_TARGET_REDIRECT is not set
# CONFIG_IP_NF_TARGET_NETMAP is not set
# CONFIG_IP_NF_TARGET_SAME is not set
# CONFIG_NF_NAT_SNMP_BASIC is not set
# CONFIG_NF_NAT_FTP is not set
# CONFIG_NF_NAT_IRC is not set
# CONFIG_NF_NAT_TFTP is not set
# CONFIG_NF_NAT_AMANDA is not set
# CONFIG_NF_NAT_PPTP is not set
# CONFIG_NF_NAT_H323 is not set
# CONFIG_NF_NAT_SIP is not set
CONFIG_IP_NF_MANGLE=y
# CONFIG_IP_NF_TARGET_TOS is not set
# CONFIG_IP_NF_TARGET_ECN is not set
# CONFIG_IP_NF_TARGET_TTL is not set
# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
# CONFIG_IP_NF_RAW is not set
# CONFIG_IP_NF_ARPTABLES is not set
#
# DCCP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
#
# TIPC Configuration (EXPERIMENTAL)
#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
#
# Wireless
#
# CONFIG_CFG80211 is not set
CONFIG_WIRELESS_EXT=y
# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
# CONFIG_RFKILL is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
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
#
# Connector - unified userspace <-> kernelspace linker
#
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
#
# Plug and Play support
#
CONFIG_PNP=y
# CONFIG_PNP_DEBUG is not set
#
# Protocols
#
CONFIG_PNPACPI=y
#
# Block devices
#
# CONFIG_BLK_DEV_FD 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=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# 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 is not set
# CONFIG_ATA_OVER_ETH is not set
#
# Misc devices
#
# CONFIG_IBM_ASM is not set
# CONFIG_PHANTOM is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_MSI_LAPTOP is not set
# CONFIG_SONY_LAPTOP is not set
CONFIG_THINKPAD_ACPI=y
# CONFIG_THINKPAD_ACPI_DEBUG is not set
# CONFIG_THINKPAD_ACPI_DOCK is not set
CONFIG_THINKPAD_ACPI_BAY=y
# CONFIG_BLINK is not set
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_IDE_SATA is not set
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
CONFIG_BLK_DEV_IDEACPI=y
# CONFIG_IDE_TASK_IOCTL is not set
CONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_IDEPCI_PCIBUS_ORDER=y
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
# CONFIG_IDEDMA_ONLYDISK is not set
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_BLK_DEV_ATIIXP is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5520 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not set
CONFIG_BLK_DEV_PIIX=y
# CONFIG_BLK_DEV_IT8213 is not set
# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_TC86C001 is not set
# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
# CONFIG_SCSI_PROC_FS is not set
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
# 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 is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
#
# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD 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_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_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR 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_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_ESP_CORE is not set
# CONFIG_SCSI_SRP is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_ACPI=y
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SVW is not set
# CONFIG_ATA_PIIX is not set
# 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_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_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_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD 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 is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
#
# I2O device support
#
# CONFIG_I2O is not set
# CONFIG_MACINTOSH_DRIVERS is not set
#
# Network device support
#
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=y
# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
#
# Ethernet (10 or 100Mbit)
#
# CONFIG_NET_ETHERNET is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
CONFIG_E1000=m
# CONFIG_E1000_NAPI is not set
# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_NETDEV_10000 is not set
#
# Token Ring devices
#
# CONFIG_TR is not set
#
# Wireless LAN
#
# CONFIG_WLAN_PRE80211 is not set
CONFIG_WLAN_80211=y
# CONFIG_IPW2100 is not set
# CONFIG_IPW2200 is not set
# CONFIG_LIBERTAS_USB is not set
# CONFIG_AIRO is not set
# CONFIG_HERMES is not set
# CONFIG_ATMEL is not set
# CONFIG_PRISM54 is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_HOSTAP is not set
#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET_MII is not set
# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
#
# CONFIG_ISDN is not set
#
# Telephony Support
#
# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV 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 is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_LIFEBOOK=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_APPLETOUCH is not set
# CONFIG_MOUSE_VSXXXAA is not set
# 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 is not set
# CONFIG_SERIO_CT82C710 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
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_PNP=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# 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=y
CONFIG_LEGACY_PTY_COUNT=256
#
# IPMI
#
# CONFIG_IPMI_HANDLER is not set
# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_NVRAM is not set
CONFIG_RTC=y
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
CONFIG_AGP=y
CONFIG_AGP_AMD64=y
# CONFIG_AGP_INTEL is not set
# CONFIG_AGP_SIS is not set
# CONFIG_AGP_VIA is not set
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
# CONFIG_PC8736x_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
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
# CONFIG_I2C is not set
#
# SPI support
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_K8TEMP is not set
# CONFIG_SENSORS_F71805F is not set
CONFIG_SENSORS_CORETEMP=y
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_HDAPS is not set
# CONFIG_SENSORS_APPLESMC is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Multifunction device drivers
#
# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
# CONFIG_DAB is not set
#
# Graphics support
#
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_PROGEAR is not set
#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
# CONFIG_VGASTATE is not set
# CONFIG_FB is not set
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128
CONFIG_VIDEO_SELECT=y
CONFIG_DUMMY_CONSOLE=y
#
# Sound
#
CONFIG_SOUND=y
#
# Advanced Linux Sound Architecture
#
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
# CONFIG_SND_SEQUENCER is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
CONFIG_SND_PCM_OSS_PLUGINS=y
# CONFIG_SND_RTCTIMER is not set
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
#
# Generic devices
#
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 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_CS4281 is not set
# CONFIG_SND_CS46XX 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=y
# CONFIG_SND_HDSP is not set
# CONFIG_SND_HDSPM is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
# CONFIG_SND_INTEL8X0 is not set
# CONFIG_SND_INTEL8X0M is not set
# 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_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_VX222 is not set
# CONFIG_SND_YMFPCI is not set
#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
# CONFIG_SND_USB_USX2Y is not set
# CONFIG_SND_USB_CAIAQ is not set
#
# System on Chip audio support
#
# CONFIG_SND_SOC is not set
#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
#
# HID Devices
#
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
#
# USB Input Devices
#
CONFIG_USB_HID=y
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
#
# Miscellaneous USB options
#
# CONFIG_USB_DEVICEFS is not set
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
#
# USB Host Controller Drivers
#
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
#
# USB Device Class drivers
#
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
#
# 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 is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_LIBUSUAL is not set
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
CONFIG_USB_MON=y
#
# USB port drivers
#
#
# USB Serial Converter support
#
# CONFIG_USB_SERIAL 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
#
# USB DSL modem support
#
#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
# CONFIG_MMC is not set
#
# LED devices
#
# CONFIG_NEW_LEDS is not set
#
# LED drivers
#
#
# LED Triggers
#
#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
#
# CONFIG_EDAC is not set
#
# Real Time Clock
#
# CONFIG_RTC_CLASS is not set
#
# DMA Engine support
#
# CONFIG_DMA_ENGINE is not set
#
# DMA Clients
#
#
# DMA Devices
#
#
# Virtualization
#
# CONFIG_KVM is not set
#
# Firmware Drivers
#
# CONFIG_EDD is not set
# CONFIG_DELL_RBU is not set
# CONFIG_DCDBAS is not set
#
# File systems
#
# CONFIG_EXT2_FS is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
# 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_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=m
CONFIG_GENERIC_ACL=y
#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
# CONFIG_ZISOFS is not set
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 is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
#
# Network File Systems
#
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
# CONFIG_9P_FS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
#
# Native Language Support
#
CONFIG_NLS=m
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=m
# 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 is not set
CONFIG_NLS_ISO8859_1=m
# 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 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
#
# Distributed Lock Manager
#
# CONFIG_DLM is not set
#
# Instrumentation Support
#
# CONFIG_PROFILING is not set
# CONFIG_KPROBES is not set
#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_UNUSED_SYMBOLS=y
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_FRAME_POINTER is not set
# CONFIG_FORCED_INLINING is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_DEBUG_RODATA is not set
# CONFIG_IOMMU_DEBUG is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_SHA1 is not set
# 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=y
# CONFIG_CRYPTO_CBC is not set
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_LRW 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_X86_64 is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_AES is not set
CONFIG_CRYPTO_AES_X86_64=y
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
# CONFIG_CRYPTO_TEA is not set
CONFIG_CRYPTO_ARC4=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_DEFLATE is not set
CONFIG_CRYPTO_MICHAEL_MIC=y
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
#
# Hardware crypto devices
#
#
# Library routines
#
CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 12:04 [BUG] long freezes on thinkpad t60 Miklos Szeredi
@ 2007-05-24 12:54 ` Ingo Molnar
2007-05-24 14:03 ` Miklos Szeredi
2007-05-24 22:08 ` Henrique de Moraes Holschuh
1 sibling, 1 reply; 13+ messages in thread
From: Ingo Molnar @ 2007-05-24 12:54 UTC (permalink / raw)
To: Miklos Szeredi; +Cc: linux-kernel, linux-acpi, Thomas Gleixner
[-- Attachment #1: Type: text/plain, Size: 1006 bytes --]
* Miklos Szeredi <miklos@szeredi.hu> wrote:
> On some strange workload involving strace and fuse I get ocasional
> long periods (10-100s) of total unresponsiveness, not even SysRq-*
> working. Then the machine continues as normal. Nothing in dmesg,
> absolutely no indication about what is happening.
> Any ideas? Possibly something ACPI related?
how reproducable are these lockups - could you possibly trace it? If yes
then please apply:
http://www.tglx.de/private/tglx/ht-debug/tracer.diff
and run the attached trace-it-1sec.c thing in a loop:
echo 1 > /proc/sys/kernel/mcount_enabled
while true; do
./trace-it-1sec > trace-`date`.txt
done
and wait for the lockup. Once it happens, please upload the trace*.txt
file that contains the lockup, i guess we'll be able to tell you more
about the nature of the lockup. (Perhaps increase the sleep(1) to
sleep(5) to capture longer periods and to increase the odds that you
catch the lockup while the utility is tracing.)
Ingo
[-- Attachment #2: trace-it-1sec.c --]
[-- Type: text/plain, Size: 2306 bytes --]
/*
* Copyright (C) 2005, Ingo Molnar <mingo@redhat.com>
*
* user-triggered tracing.
*
* The -rt kernel has a built-in kernel tracer, which will trace
* all kernel function calls (and a couple of special events as well),
* by using a build-time gcc feature that instruments all kernel
* functions.
*
* The tracer is highly automated for a number of latency tracing purposes,
* but it can also be switched into 'user-triggered' mode, which is a
* half-automatic tracing mode where userspace apps start and stop the
* tracer. This file shows a dumb example how to turn user-triggered
* tracing on, and how to start/stop tracing. Note that if you do
* multiple start/stop sequences, the kernel will do a maximum search
* over their latencies, and will keep the trace of the largest latency
* in /proc/latency_trace. The maximums are also reported to the kernel
* log. (but can also be read from /proc/sys/kernel/preempt_max_latency)
*
* For the tracer to be activated, turn on CONFIG_WAKEUP_TIMING and
* CONFIG_LATENCY_TRACE in the .config, rebuild the kernel and boot
* into it. Note that the tracer can have significant runtime overhead,
* so you dont want to use it for performance testing :)
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <linux/unistd.h>
int main (int argc, char **argv)
{
int ret;
if (getuid() != 0) {
fprintf(stderr, "needs to run as root.\n");
exit(1);
}
ret = system("cat /proc/sys/kernel/mcount_enabled >/dev/null 2>/dev/null");
if (ret) {
fprintf(stderr, "CONFIG_LATENCY_TRACING not enabled?\n");
exit(1);
}
system("echo 1 > /proc/sys/kernel/trace_enabled");
// system("echo 0 > /proc/sys/kernel/trace_freerunning");
system("echo 0 > /proc/sys/kernel/trace_print_at_crash");
system("echo 1 > /proc/sys/kernel/trace_user_triggered");
system("echo 0 > /proc/sys/kernel/trace_verbose");
system("echo 0 > /proc/sys/kernel/preempt_max_latency");
system("echo 0 > /proc/sys/kernel/preempt_thresh");
system("[ -e /proc/sys/kernel/wakeup_timing ] && echo 1 > /proc/sys/kernel/wakeup_timing");
// system("echo 1 > /proc/sys/kernel/mcount_enabled");
prctl(0, 1); // start tracing
sleep(1);
prctl(0, 0); // stop tracing
system("cat /proc/latency_trace");
return 0;
}
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 12:54 ` Ingo Molnar
@ 2007-05-24 14:03 ` Miklos Szeredi
2007-05-24 14:10 ` Ingo Molnar
0 siblings, 1 reply; 13+ messages in thread
From: Miklos Szeredi @ 2007-05-24 14:03 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, linux-acpi, tglx
> > On some strange workload involving strace and fuse I get ocasional
> > long periods (10-100s) of total unresponsiveness, not even SysRq-*
> > working. Then the machine continues as normal. Nothing in dmesg,
> > absolutely no indication about what is happening.
>
> > Any ideas? Possibly something ACPI related?
>
> how reproducable are these lockups - could you possibly trace it? If yes
> then please apply:
>
> http://www.tglx.de/private/tglx/ht-debug/tracer.diff
With this patch boot stops at segfaulting fsck. I enabled all the new
config options, is that not a good idea? Which one exactly do I need?
Thanks,
Miklos
PS. tracer.diff needed some hacking to make it apply/compile.
Index: linux-2.6.22-rc2/include/linux/linkage.h
===================================================================
--- linux-2.6.22-rc2.orig/include/linux/linkage.h 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/include/linux/linkage.h 2007-05-24 15:57:43.000000000 +0200
@@ -3,6 +3,8 @@
#include <asm/linkage.h>
+#define notrace __attribute ((no_instrument_function))
+
#ifdef __cplusplus
#define CPP_ASMLINKAGE extern "C"
#else
Index: linux-2.6.22-rc2/Documentation/stable_api_nonsense.txt
===================================================================
--- linux-2.6.22-rc2.orig/Documentation/stable_api_nonsense.txt 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/Documentation/stable_api_nonsense.txt 2007-05-24 15:57:42.000000000 +0200
@@ -62,6 +62,9 @@ consider the following facts about the L
- different structures can contain different fields
- Some functions may not be implemented at all, (i.e. some locks
compile away to nothing for non-SMP builds.)
+ - Parameter passing of variables from function to function can be
+ done in different ways (the CONFIG_REGPARM option controls
+ this.)
- Memory within the kernel can be aligned in different ways,
depending on the build options.
- Linux runs on a wide range of different processor architectures.
Index: linux-2.6.22-rc2/arch/i386/Kconfig
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/Kconfig 2007-05-22 16:25:05.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/Kconfig 2007-05-24 15:57:42.000000000 +0200
@@ -764,6 +764,14 @@ config BOOT_IOREMAP
depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI))
default y
+#
+# function tracing might turn this off:
+#
+config REGPARM
+ bool
+ depends on !MCOUNT
+ default y
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
depends on PROC_FS
Index: linux-2.6.22-rc2/arch/i386/Makefile
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/Makefile 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/Makefile 2007-05-24 15:57:42.000000000 +0200
@@ -31,7 +31,7 @@ LDFLAGS_vmlinux := --emit-relocs
endif
CHECKFLAGS += -D__i386__
-CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return
+CFLAGS += -pipe -msoft-float
# prevent gcc from keeping the stack 16 byte aligned
CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
@@ -39,6 +39,8 @@ CFLAGS += $(call cc-option,-mpreferred-s
# CPU-specific tuning. Anything which can be shared with UML should go here.
include $(srctree)/arch/i386/Makefile.cpu
+cflags-$(CONFIG_REGPARM) += -mregparm=3 -freg-struct-return
+
# temporary until string.h is fixed
cflags-y += -ffreestanding
Index: linux-2.6.22-rc2/include/asm-i386/module.h
===================================================================
--- linux-2.6.22-rc2.orig/include/asm-i386/module.h 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/include/asm-i386/module.h 2007-05-24 15:57:43.000000000 +0200
@@ -64,12 +64,18 @@ struct mod_arch_specific
#error unknown processor family
#endif
+#ifdef CONFIG_REGPARM
+#define MODULE_REGPARM "REGPARM "
+#else
+#define MODULE_REGPARM ""
+#endif
+
#ifdef CONFIG_4KSTACKS
#define MODULE_STACKSIZE "4KSTACKS "
#else
#define MODULE_STACKSIZE ""
#endif
-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
#endif /* _ASM_I386_MODULE_H */
Index: linux-2.6.22-rc2/Makefile
===================================================================
--- linux-2.6.22-rc2.orig/Makefile 2007-05-22 16:25:01.000000000 +0200
+++ linux-2.6.22-rc2/Makefile 2007-05-24 15:57:42.000000000 +0200
@@ -490,10 +490,14 @@ endif
include $(srctree)/arch/$(ARCH)/Makefile
-ifdef CONFIG_FRAME_POINTER
-CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
+ifdef CONFIG_MCOUNT
+CFLAGS += -pg -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
else
-CFLAGS += -fomit-frame-pointer
+ ifdef CONFIG_FRAME_POINTER
+ CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
+ else
+ CFLAGS += -fomit-frame-pointer
+ endif
endif
ifdef CONFIG_DEBUG_INFO
Index: linux-2.6.22-rc2/arch/i386/lib/delay.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/lib/delay.c 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/lib/delay.c 2007-05-24 15:57:43.000000000 +0200
@@ -23,7 +23,7 @@
#endif
/* simple loop based delay: */
-static void delay_loop(unsigned long loops)
+static notrace void delay_loop(unsigned long loops)
{
int d0;
@@ -38,7 +38,7 @@ static void delay_loop(unsigned long loo
}
/* TSC based delay: */
-static void delay_tsc(unsigned long loops)
+static notrace void delay_tsc(unsigned long loops)
{
unsigned long bclock, now;
@@ -69,7 +69,7 @@ int read_current_timer(unsigned long *ti
return -1;
}
-void __delay(unsigned long loops)
+void notrace __delay(unsigned long loops)
{
delay_fn(loops);
}
Index: linux-2.6.22-rc2/arch/x86_64/kernel/tsc.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/kernel/tsc.c 2007-05-22 16:25:10.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/kernel/tsc.c 2007-05-24 15:57:42.000000000 +0200
@@ -176,13 +176,13 @@ __setup("notsc", notsc_setup);
/* clock source code: */
-static cycle_t read_tsc(void)
+static notrace cycle_t read_tsc(void)
{
cycle_t ret = (cycle_t)get_cycles_sync();
return ret;
}
-static cycle_t __vsyscall_fn vread_tsc(void)
+static notrace cycle_t __vsyscall_fn vread_tsc(void)
{
cycle_t ret = (cycle_t)get_cycles_sync();
return ret;
Index: linux-2.6.22-rc2/drivers/clocksource/acpi_pm.c
===================================================================
--- linux-2.6.22-rc2.orig/drivers/clocksource/acpi_pm.c 2007-05-22 16:25:11.000000000 +0200
+++ linux-2.6.22-rc2/drivers/clocksource/acpi_pm.c 2007-05-24 15:57:42.000000000 +0200
@@ -30,13 +30,13 @@
*/
u32 pmtmr_ioport __read_mostly;
-static inline u32 read_pmtmr(void)
+static notrace inline u32 read_pmtmr(void)
{
/* mask the output to 24 bits */
return inl(pmtmr_ioport) & ACPI_PM_MASK;
}
-u32 acpi_pm_read_verified(void)
+u32 notrace acpi_pm_read_verified(void)
{
u32 v1 = 0, v2 = 0, v3 = 0;
@@ -56,12 +56,12 @@ u32 acpi_pm_read_verified(void)
return v2;
}
-static cycle_t acpi_pm_read_slow(void)
+static notrace cycle_t acpi_pm_read_slow(void)
{
return (cycle_t)acpi_pm_read_verified();
}
-static cycle_t acpi_pm_read(void)
+static notrace cycle_t acpi_pm_read(void)
{
return (cycle_t)read_pmtmr();
}
Index: linux-2.6.22-rc2/fs/proc/proc_misc.c
===================================================================
--- linux-2.6.22-rc2.orig/fs/proc/proc_misc.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/fs/proc/proc_misc.c 2007-05-24 15:57:42.000000000 +0200
@@ -623,6 +623,20 @@ static int execdomains_read_proc(char *p
return proc_calc_metrics(page, start, off, count, eof, len);
}
+#ifdef CONFIG_EVENT_TRACE
+extern struct seq_operations latency_trace_op;
+static int latency_trace_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &latency_trace_op);
+}
+static struct file_operations proc_latency_trace_operations = {
+ .open = latency_trace_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+#endif
+
#ifdef CONFIG_MAGIC_SYSRQ
/*
* writing 'C' to /proc/sysrq-trigger is like sysrq-C
@@ -716,6 +730,9 @@ void __init proc_misc_init(void)
#ifdef CONFIG_SCHEDSTATS
create_seq_entry("schedstat", 0, &proc_schedstat_operations);
#endif
+#ifdef CONFIG_EVENT_TRACE
+ create_seq_entry("latency_trace", 0, &proc_latency_trace_operations);
+#endif
#ifdef CONFIG_PROC_KCORE
proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
if (proc_root_kcore) {
Index: linux-2.6.22-rc2/include/linux/clocksource.h
===================================================================
--- linux-2.6.22-rc2.orig/include/linux/clocksource.h 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/include/linux/clocksource.h 2007-05-24 15:57:43.000000000 +0200
@@ -21,6 +21,9 @@
typedef u64 cycle_t;
struct clocksource;
+extern unsigned long preempt_max_latency;
+extern unsigned long preempt_thresh;
+
/**
* struct clocksource - hardware abstraction for a free running counter
* Provides mostly state-free accessors to the underlying hardware.
@@ -172,8 +175,20 @@ static inline cycle_t clocksource_read(s
*/
static inline s64 cyc2ns(struct clocksource *cs, cycle_t cycles)
{
- u64 ret = (u64)cycles;
- ret = (ret * cs->mult) >> cs->shift;
+ return ((u64)cycles * cs->mult) >> cs->shift;
+}
+
+/**
+ * ns2cyc - converts nanoseconds to clocksource cycles
+ * @cs: Pointer to clocksource
+ * @nsecs: Nanoseconds
+ */
+static inline cycles_t ns2cyc(struct clocksource *cs, u64 nsecs)
+{
+ cycles_t ret = nsecs << cs->shift;
+
+ do_div(ret, cs->mult + 1);
+
return ret;
}
@@ -221,4 +236,8 @@ static inline void update_vsyscall(struc
}
#endif
+extern cycle_t get_monotonic_cycles(void);
+extern unsigned long cycles_to_usecs(cycle_t);
+extern cycle_t usecs_to_cycles(unsigned long);
+
#endif /* _LINUX_CLOCKSOURCE_H */
Index: linux-2.6.22-rc2/include/linux/kernel.h
===================================================================
--- linux-2.6.22-rc2.orig/include/linux/kernel.h 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/include/linux/kernel.h 2007-05-24 15:57:43.000000000 +0200
@@ -156,6 +156,8 @@ asmlinkage int vprintk(const char *fmt,
__attribute__ ((format (printf, 1, 0)));
asmlinkage int printk(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2)));
+extern void early_printk(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
#else
static inline int vprintk(const char *s, va_list args)
__attribute__ ((format (printf, 1, 0)));
Index: linux-2.6.22-rc2/include/linux/latency_hist.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.22-rc2/include/linux/latency_hist.h 2007-05-24 15:57:43.000000000 +0200
@@ -0,0 +1,32 @@
+/*
+ * kernel/latency_hist.h
+ *
+ * Add support for histograms of preemption-off latency and
+ * interrupt-off latency and wakeup latency, it depends on
+ * Real-Time Preemption Support.
+ *
+ * Copyright (C) 2005 MontaVista Software, Inc.
+ * Yi Yang <yyang@ch.mvista.com>
+ *
+ */
+#ifndef _LINUX_LATENCY_HIST_H_
+#define _LINUX_LATENCY_HIST_H_
+
+enum {
+ INTERRUPT_LATENCY = 0,
+ PREEMPT_LATENCY,
+ WAKEUP_LATENCY
+};
+
+#define MAX_ENTRY_NUM 10240
+#define LATENCY_TYPE_NUM 3
+
+#ifdef CONFIG_LATENCY_HIST
+extern void latency_hist(int latency_type, int cpu, unsigned long latency);
+# define latency_hist_flag 1
+#else
+# define latency_hist(a,b,c) do { (void)(cpu); } while (0)
+# define latency_hist_flag 0
+#endif /* CONFIG_LATENCY_HIST */
+
+#endif /* ifndef _LINUX_LATENCY_HIST_H_ */
Index: linux-2.6.22-rc2/include/linux/preempt.h
===================================================================
--- linux-2.6.22-rc2.orig/include/linux/preempt.h 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/include/linux/preempt.h 2007-05-24 15:57:43.000000000 +0200
@@ -9,12 +9,26 @@
#include <linux/thread_info.h>
#include <linux/linkage.h>
-#ifdef CONFIG_DEBUG_PREEMPT
- extern void fastcall add_preempt_count(int val);
- extern void fastcall sub_preempt_count(int val);
+#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_CRITICAL_TIMING)
+ extern void notrace add_preempt_count(unsigned int val);
+ extern void notrace sub_preempt_count(unsigned int val);
+ extern void notrace mask_preempt_count(unsigned int mask);
+ extern void notrace unmask_preempt_count(unsigned int mask);
#else
# define add_preempt_count(val) do { preempt_count() += (val); } while (0)
# define sub_preempt_count(val) do { preempt_count() -= (val); } while (0)
+# define mask_preempt_count(mask) \
+ do { preempt_count() |= (mask); } while (0)
+# define unmask_preempt_count(mask) \
+ do { preempt_count() &= ~(mask); } while (0)
+#endif
+
+#ifdef CONFIG_CRITICAL_TIMING
+ extern void touch_critical_timing(void);
+ extern void stop_critical_timing(void);
+#else
+# define touch_critical_timing() do { } while (0)
+# define stop_critical_timing() do { } while (0)
#endif
#define inc_preempt_count() add_preempt_count(1)
Index: linux-2.6.22-rc2/include/linux/sched.h
===================================================================
--- linux-2.6.22-rc2.orig/include/linux/sched.h 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/include/linux/sched.h 2007-05-24 15:57:43.000000000 +0200
@@ -215,6 +215,7 @@ static inline void show_state(void)
}
extern void show_regs(struct pt_regs *);
+extern void irq_show_regs_callback(int cpu, struct pt_regs *regs);
/*
* TASK is a pointer to the task whose backtrace we want to see (or NULL for current
@@ -251,6 +252,105 @@ static inline void touch_all_softlockup_
}
#endif
+#if defined(CONFIG_PREEMPT_TRACE) || defined(CONFIG_EVENT_TRACE)
+ extern void print_traces(struct task_struct *task);
+#else
+# define print_traces(task) do { } while (0)
+#endif
+
+#ifdef CONFIG_FRAME_POINTER
+# ifndef CONFIG_ARM
+# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
+# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
+# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
+# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
+# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
+# else
+ extern unsigned long arm_return_addr(int level);
+# define CALLER_ADDR0 arm_return_addr(0)
+# define CALLER_ADDR1 arm_return_addr(1)
+# define CALLER_ADDR2 arm_return_addr(2)
+# define CALLER_ADDR3 arm_return_addr(3)
+# define CALLER_ADDR4 arm_return_addr(4)
+# define CALLER_ADDR5 arm_return_addr(5)
+#endif
+#else
+# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+# define CALLER_ADDR1 0UL
+# define CALLER_ADDR2 0UL
+# define CALLER_ADDR3 0UL
+# define CALLER_ADDR4 0UL
+# define CALLER_ADDR5 0UL
+#endif
+
+#ifdef CONFIG_MCOUNT
+ extern void notrace mcount(void);
+#else
+# define mcount() do { } while (0)
+#endif
+
+#ifdef CONFIG_EVENT_TRACE
+ extern int mcount_enabled, trace_enabled, trace_user_triggered,
+ trace_user_trigger_irq, trace_freerunning, trace_verbose,
+ trace_print_on_crash, trace_all_cpus, print_functions,
+ syscall_tracing, stackframe_tracing, trace_use_raw_cycles,
+ trace_all_runnable;
+ extern void notrace trace_special(unsigned long v1, unsigned long v2, unsigned long v3);
+ extern void notrace trace_special_pid(int pid, unsigned long v1, unsigned long v2);
+ extern void notrace trace_special_u64(unsigned long long v1, unsigned long v2);
+ extern void notrace trace_special_sym(void);
+ extern void stop_trace(void);
+# define start_trace() do { trace_enabled = 1; } while (0)
+ extern void print_last_trace(void);
+ extern void nmi_trace(unsigned long eip, unsigned long parent_eip,
+ unsigned long flags);
+ extern long user_trace_start(void);
+ extern long user_trace_stop(void);
+ extern void trace_cmdline(void);
+ extern void init_tracer(void);
+#else
+# define mcount_enabled 0
+# define trace_enabled 0
+# define syscall_tracing 0
+# define stackframe_tracing 0
+# define trace_user_triggered 0
+# define trace_freerunning 0
+# define trace_all_cpus 0
+# define trace_verbose 0
+# define trace_special(v1,v2,v3) do { } while (0)
+# define trace_special_pid(pid,v1,v2) do { } while (0)
+# define trace_special_u64(v1,v2) do { } while (0)
+# define trace_special_sym() do { } while (0)
+# define stop_trace() do { } while (0)
+# define start_trace() do { } while (0)
+# define print_last_trace() do { } while (0)
+# define nmi_trace(eip, parent_eip, flags) do { } while (0)
+# define user_trace_start() do { } while (0)
+# define user_trace_stop() do { } while (0)
+# define trace_cmdline() do { } while (0)
+# define init_tracer() do { } while (0)
+#endif
+
+#ifdef CONFIG_WAKEUP_TIMING
+ extern int wakeup_timing;
+ extern void __trace_start_sched_wakeup(struct task_struct *p);
+ extern void trace_stop_sched_switched(struct task_struct *p);
+ extern void trace_change_sched_cpu(struct task_struct *p, int new_cpu);
+#else
+# define wakeup_timing 0
+# define __trace_start_sched_wakeup(p) do { } while (0)
+# define trace_stop_sched_switched(p) do { } while (0)
+# define trace_change_sched_cpu(p, cpu) do { } while (0)
+#endif
+
+#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING
+ extern void notrace time_hardirqs_on(unsigned long a0, unsigned long a1);
+ extern void notrace time_hardirqs_off(unsigned long a0, unsigned long a1);
+#else
+# define time_hardirqs_on(a0, a1) do { } while (0)
+# define time_hardirqs_off(a0, a1) do { } while (0)
+#endif
/* Attach to any functions which should be ignored in wchan output. */
#define __sched __attribute__((__section__(".sched.text")))
@@ -1014,6 +1114,13 @@ struct task_struct {
unsigned int lockdep_recursion;
#endif
+#define MAX_PREEMPT_TRACE 16
+
+#ifdef CONFIG_PREEMPT_TRACE
+ unsigned long preempt_trace_eip[MAX_PREEMPT_TRACE];
+ unsigned long preempt_trace_parent_eip[MAX_PREEMPT_TRACE];
+#endif
+
/* journalling filesystem info */
void *journal_info;
@@ -1636,6 +1743,7 @@ static inline unsigned int task_cpu(cons
static inline void set_task_cpu(struct task_struct *p, unsigned int cpu)
{
+ trace_change_sched_cpu(p, cpu);
task_thread_info(p)->cpu = cpu;
}
Index: linux-2.6.22-rc2/init/main.c
===================================================================
--- linux-2.6.22-rc2.orig/init/main.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/init/main.c 2007-05-24 15:57:42.000000000 +0200
@@ -576,6 +576,8 @@ asmlinkage void __init start_kernel(void
if (panic_later)
panic(panic_later, panic_param);
+ init_tracer();
+
lockdep_info();
/*
Index: linux-2.6.22-rc2/kernel/Makefile
===================================================================
--- linux-2.6.22-rc2.orig/kernel/Makefile 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/Makefile 2007-05-24 15:57:42.000000000 +0200
@@ -38,6 +38,11 @@ obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_CPUSETS) += cpuset.o
obj-$(CONFIG_IKCONFIG) += configs.o
obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
+obj-$(CONFIG_DEBUG_PREEMPT) += latency_trace.o
+obj-$(CONFIG_WAKEUP_TIMING) += latency_trace.o
+obj-$(CONFIG_EVENT_TRACE) += latency_trace.o
+obj-$(CONFIG_CRITICAL_TIMING) += latency_trace.o
+obj-$(CONFIG_LATENCY_HIST) += latency_hist.o
obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
obj-$(CONFIG_KPROBES) += kprobes.o
Index: linux-2.6.22-rc2/kernel/fork.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/fork.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/fork.c 2007-05-24 15:57:42.000000000 +0200
@@ -990,7 +990,7 @@ static struct task_struct *copy_process(
rt_mutex_init_task(p);
-#ifdef CONFIG_TRACE_IRQFLAGS
+#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_LOCKDEP)
DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
#endif
Index: linux-2.6.22-rc2/kernel/latency_hist.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.22-rc2/kernel/latency_hist.c 2007-05-24 15:57:42.000000000 +0200
@@ -0,0 +1,267 @@
+/*
+ * kernel/latency_hist.c
+ *
+ * Add support for histograms of preemption-off latency and
+ * interrupt-off latency and wakeup latency, it depends on
+ * Real-Time Preemption Support.
+ *
+ * Copyright (C) 2005 MontaVista Software, Inc.
+ * Yi Yang <yyang@ch.mvista.com>
+ *
+ */
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/percpu.h>
+#include <linux/latency_hist.h>
+#include <linux/calc64.h>
+#include <asm/atomic.h>
+
+typedef struct hist_data_struct {
+ atomic_t hist_mode; /* 0 log, 1 don't log */
+ unsigned long min_lat;
+ unsigned long avg_lat;
+ unsigned long max_lat;
+ unsigned long long beyond_hist_bound_samples;
+ unsigned long long accumulate_lat;
+ unsigned long long total_samples;
+ unsigned long long hist_array[MAX_ENTRY_NUM];
+} hist_data_t;
+
+static struct proc_dir_entry * latency_hist_root = NULL;
+static char * latency_hist_proc_dir_root = "latency_hist";
+
+static char * percpu_proc_name = "CPU";
+
+#ifdef CONFIG_INTERRUPT_OFF_HIST
+static DEFINE_PER_CPU(hist_data_t, interrupt_off_hist);
+static char * interrupt_off_hist_proc_dir = "interrupt_off_latency";
+#endif
+
+#ifdef CONFIG_PREEMPT_OFF_HIST
+static DEFINE_PER_CPU(hist_data_t, preempt_off_hist);
+static char * preempt_off_hist_proc_dir = "preempt_off_latency";
+#endif
+
+#ifdef CONFIG_WAKEUP_LATENCY_HIST
+static DEFINE_PER_CPU(hist_data_t, wakeup_latency_hist);
+static char * wakeup_latency_hist_proc_dir = "wakeup_latency";
+#endif
+
+static struct proc_dir_entry *entry[LATENCY_TYPE_NUM][NR_CPUS];
+
+static inline u64 u64_div(u64 x, u64 y)
+{
+ do_div(x, y);
+ return x;
+}
+
+void latency_hist(int latency_type, int cpu, unsigned long latency)
+{
+ hist_data_t * my_hist;
+
+ if ((cpu < 0) || (cpu >= NR_CPUS) || (latency_type < INTERRUPT_LATENCY)
+ || (latency_type > WAKEUP_LATENCY) || (latency < 0))
+ return;
+
+ switch(latency_type) {
+#ifdef CONFIG_INTERRUPT_OFF_HIST
+ case INTERRUPT_LATENCY:
+ my_hist = (hist_data_t *)&per_cpu(interrupt_off_hist, cpu);
+ break;
+#endif
+
+#ifdef CONFIG_PREEMPT_OFF_HIST
+ case PREEMPT_LATENCY:
+ my_hist = (hist_data_t *)&per_cpu(preempt_off_hist, cpu);
+ break;
+#endif
+
+#ifdef CONFIG_WAKEUP_LATENCY_HIST
+ case WAKEUP_LATENCY:
+ my_hist = (hist_data_t *)&per_cpu(wakeup_latency_hist, cpu);
+ break;
+#endif
+ default:
+ return;
+ }
+
+ if (atomic_read(&my_hist->hist_mode) == 0)
+ return;
+
+ if (latency >= MAX_ENTRY_NUM)
+ my_hist->beyond_hist_bound_samples++;
+ else
+ my_hist->hist_array[latency]++;
+
+ if (latency < my_hist->min_lat)
+ my_hist->min_lat = latency;
+ else if (latency > my_hist->max_lat)
+ my_hist->max_lat = latency;
+
+ my_hist->total_samples++;
+ my_hist->accumulate_lat += latency;
+ my_hist->avg_lat = (unsigned long) u64_div(my_hist->accumulate_lat,
+ my_hist->total_samples);
+ return;
+}
+
+static void *l_start(struct seq_file *m, loff_t * pos)
+{
+ loff_t *index_ptr = kmalloc(sizeof(loff_t), GFP_KERNEL);
+ loff_t index = *pos;
+ hist_data_t *my_hist = (hist_data_t *) m->private;
+
+ if (!index_ptr)
+ return NULL;
+
+ if (index == 0) {
+ atomic_dec(&my_hist->hist_mode);
+ seq_printf(m, "#Minimum latency: %lu microseconds.\n"
+ "#Average latency: %lu microseconds.\n"
+ "#Maximum latency: %lu microseconds.\n"
+ "#Total samples: %llu\n"
+ "#There are %llu samples greater or equal than %d microseconds\n"
+ "#usecs\t%16s\n"
+ , my_hist->min_lat
+ , my_hist->avg_lat
+ , my_hist->max_lat
+ , my_hist->total_samples
+ , my_hist->beyond_hist_bound_samples
+ , MAX_ENTRY_NUM, "samples");
+ }
+ if (index >= MAX_ENTRY_NUM)
+ return NULL;
+
+ *index_ptr = index;
+ return index_ptr;
+}
+
+static void *l_next(struct seq_file *m, void *p, loff_t * pos)
+{
+ loff_t *index_ptr = p;
+ hist_data_t *my_hist = (hist_data_t *) m->private;
+
+ if (++*pos >= MAX_ENTRY_NUM) {
+ atomic_inc(&my_hist->hist_mode);
+ return NULL;
+ }
+ *index_ptr = *pos;
+ return index_ptr;
+}
+
+static void l_stop(struct seq_file *m, void *p)
+{
+ kfree(p);
+}
+
+static int l_show(struct seq_file *m, void *p)
+{
+ int index = *(loff_t *) p;
+ hist_data_t *my_hist = (hist_data_t *) m->private;
+
+ seq_printf(m, "%5d\t%16llu\n", index, my_hist->hist_array[index]);
+ return 0;
+}
+
+static struct seq_operations latency_hist_seq_op = {
+ .start = l_start,
+ .next = l_next,
+ .stop = l_stop,
+ .show = l_show
+};
+
+static int latency_hist_seq_open(struct inode *inode, struct file *file)
+{
+ struct proc_dir_entry *entry_ptr = NULL;
+ int ret, i, j, break_flags = 0;
+ struct seq_file *seq;
+
+ entry_ptr = PDE(file->f_dentry->d_inode);
+ for (i = 0; i < LATENCY_TYPE_NUM; i++) {
+ for (j = 0; j < NR_CPUS; j++) {
+ if (entry[i][j] == NULL)
+ continue;
+ if (entry_ptr->low_ino == entry[i][j]->low_ino) {
+ break_flags = 1;
+ break;
+ }
+ }
+ if (break_flags == 1)
+ break;
+ }
+ ret = seq_open(file, &latency_hist_seq_op);
+ if (break_flags == 1) {
+ seq = (struct seq_file *)file->private_data;
+ seq->private = entry[i][j]->data;
+ }
+ return ret;
+}
+
+static struct file_operations latency_hist_seq_fops = {
+ .open = latency_hist_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static __init int latency_hist_init(void)
+{
+ struct proc_dir_entry *tmp_parent_proc_dir;
+ int i = 0, len = 0;
+ hist_data_t *my_hist;
+ char procname[64];
+
+ latency_hist_root = proc_mkdir(latency_hist_proc_dir_root, NULL);
+
+
+#ifdef CONFIG_INTERRUPT_OFF_HIST
+ tmp_parent_proc_dir = proc_mkdir(interrupt_off_hist_proc_dir, latency_hist_root);
+ for (i = 0; i < NR_CPUS; i++) {
+ len = sprintf(procname, "%s%d", percpu_proc_name, i);
+ procname[len] = '\0';
+ entry[INTERRUPT_LATENCY][i] =
+ create_proc_entry(procname, 0, tmp_parent_proc_dir);
+ entry[INTERRUPT_LATENCY][i]->data = (void *)&per_cpu(interrupt_off_hist, i);
+ entry[INTERRUPT_LATENCY][i]->proc_fops = &latency_hist_seq_fops;
+ my_hist = (hist_data_t *) entry[INTERRUPT_LATENCY][i]->data;
+ atomic_set(&my_hist->hist_mode,1);
+ my_hist->min_lat = 0xFFFFFFFFUL;
+ }
+#endif
+
+#ifdef CONFIG_PREEMPT_OFF_HIST
+ tmp_parent_proc_dir = proc_mkdir(preempt_off_hist_proc_dir, latency_hist_root);
+ for (i = 0; i < NR_CPUS; i++) {
+ len = sprintf(procname, "%s%d", percpu_proc_name, i);
+ procname[len] = '\0';
+ entry[PREEMPT_LATENCY][i] =
+ create_proc_entry(procname, 0, tmp_parent_proc_dir);
+ entry[PREEMPT_LATENCY][i]->data = (void *)&per_cpu(preempt_off_hist, i);
+ entry[PREEMPT_LATENCY][i]->proc_fops = &latency_hist_seq_fops;
+ my_hist = (hist_data_t *) entry[PREEMPT_LATENCY][i]->data;
+ atomic_set(&my_hist->hist_mode,1);
+ my_hist->min_lat = 0xFFFFFFFFUL;
+ }
+#endif
+
+#ifdef CONFIG_WAKEUP_LATENCY_HIST
+ tmp_parent_proc_dir = proc_mkdir(wakeup_latency_hist_proc_dir, latency_hist_root);
+ for (i = 0; i < NR_CPUS; i++) {
+ len = sprintf(procname, "%s%d", percpu_proc_name, i);
+ procname[len] = '\0';
+ entry[WAKEUP_LATENCY][i] =
+ create_proc_entry(procname, 0, tmp_parent_proc_dir);
+ entry[WAKEUP_LATENCY][i]->data = (void *)&per_cpu(wakeup_latency_hist, i);
+ entry[WAKEUP_LATENCY][i]->proc_fops = &latency_hist_seq_fops;
+ my_hist = (hist_data_t *) entry[WAKEUP_LATENCY][i]->data;
+ atomic_set(&my_hist->hist_mode,1);
+ my_hist->min_lat = 0xFFFFFFFFUL;
+ }
+#endif
+ return 0;
+
+}
+
+__initcall(latency_hist_init);
+
Index: linux-2.6.22-rc2/kernel/latency_trace.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.22-rc2/kernel/latency_trace.c 2007-05-24 15:57:42.000000000 +0200
@@ -0,0 +1,2763 @@
+/*
+ * kernel/latency_trace.c
+ *
+ * Copyright (C) 2004-2006 Ingo Molnar
+ * Copyright (C) 2004 William Lee Irwin III
+ */
+#include <linux/mm.h>
+#include <linux/nmi.h>
+#include <linux/rtc.h>
+#include <linux/sched.h>
+#include <linux/percpu.h>
+
+#include <linux/module.h>
+#include <linux/profile.h>
+#include <linux/bootmem.h>
+#include <linux/version.h>
+#include <linux/notifier.h>
+#include <linux/kallsyms.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/proc_fs.h>
+#include <linux/latency_hist.h>
+#include <linux/utsrelease.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+#include <asm/rtc.h>
+#include <asm/asm-offsets.h>
+#include <linux/stacktrace.h>
+
+#ifndef DEFINE_RAW_SPINLOCK
+# define DEFINE_RAW_SPINLOCK DEFINE_SPINLOCK
+#endif
+
+#ifndef RAW_SPIN_LOCK_UNLOCKED
+# define RAW_SPIN_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED
+#endif
+
+int trace_use_raw_cycles = 0;
+
+#define __raw_spinlock_t raw_spinlock_t
+#define need_resched_delayed() 0
+
+#ifdef CONFIG_EVENT_TRACE
+/*
+ * Convert raw cycles to usecs.
+ * Note: this is not the 'clocksource cycles' value, it's the raw
+ * cycle counter cycles. We use GTOD to timestamp latency start/end
+ * points, but the trace entries inbetween are timestamped with
+ * get_cycles().
+ */
+static unsigned long notrace cycles_to_us(cycle_t delta)
+{
+ if (!trace_use_raw_cycles)
+ return cycles_to_usecs(delta);
+#ifdef CONFIG_X86
+ do_div(delta, cpu_khz/1000+1);
+#elif defined(CONFIG_PPC)
+ delta = mulhwu(tb_to_us, delta);
+#elif defined(CONFIG_ARM)
+ delta = mach_cycles_to_usecs(delta);
+#else
+ #error Implement cycles_to_usecs.
+#endif
+
+ return (unsigned long) delta;
+}
+#endif
+
+static notrace inline cycle_t now(void)
+{
+ if (trace_use_raw_cycles)
+ return get_cycles();
+ return get_monotonic_cycles();
+}
+
+#ifndef irqs_off
+# define irqs_off() 0
+#endif
+
+#ifndef DEBUG_WARN_ON
+static inline int DEBUG_WARN_ON(int cond)
+{
+ WARN_ON(cond);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING
+# ifdef CONFIG_CRITICAL_PREEMPT_TIMING
+# define irqs_off_preempt_count() preempt_count()
+# else
+# define irqs_off_preempt_count() 0
+# endif
+#endif
+
+#ifdef CONFIG_WAKEUP_TIMING
+struct sch_struct {
+ __raw_spinlock_t trace_lock;
+ struct task_struct *task;
+ int cpu;
+ struct cpu_trace *tr;
+} ____cacheline_aligned_in_smp;
+
+static __cacheline_aligned_in_smp struct sch_struct sch =
+ { trace_lock: __RAW_SPIN_LOCK_UNLOCKED };
+
+int wakeup_timing = 1;
+#endif
+
+/*
+ * Track maximum latencies and save the trace:
+ */
+
+/*
+ * trace_stop_sched_switched must not be called with runqueue locks held!
+ */
+static __cacheline_aligned_in_smp DECLARE_MUTEX(max_mutex);
+
+/*
+ * Sequence count - we record it when starting a measurement and
+ * skip the latency if the sequence has changed - some other section
+ * did a maximum and could disturb our measurement with serial console
+ * printouts, etc. Truly coinciding maximum latencies should be rare
+ * and what happens together happens separately as well, so this doesnt
+ * decrease the validity of the maximum found:
+ */
+static __cacheline_aligned_in_smp unsigned long max_sequence;
+
+enum trace_type
+{
+ __TRACE_FIRST_TYPE = 0,
+
+ TRACE_FN,
+ TRACE_SPECIAL,
+ TRACE_SPECIAL_PID,
+ TRACE_SPECIAL_U64,
+ TRACE_SPECIAL_SYM,
+ TRACE_CMDLINE,
+ TRACE_SYSCALL,
+ TRACE_SYSRET,
+
+ __TRACE_LAST_TYPE
+};
+
+enum trace_flag_type
+{
+ TRACE_FLAG_IRQS_OFF = 0x01,
+ TRACE_FLAG_NEED_RESCHED = 0x02,
+ TRACE_FLAG_NEED_RESCHED_DELAYED = 0x04,
+ TRACE_FLAG_HARDIRQ = 0x08,
+ TRACE_FLAG_SOFTIRQ = 0x10,
+ TRACE_FLAG_IRQS_HARD_OFF = 0x20,
+};
+
+/*
+ * Maximum preemption latency measured. Initialize to maximum,
+ * we clear it after bootup.
+ */
+#ifdef CONFIG_LATENCY_HIST
+unsigned long preempt_max_latency = (cycle_t)0UL;
+#else
+unsigned long preempt_max_latency = (cycle_t)ULONG_MAX;
+#endif
+
+unsigned long preempt_thresh;
+
+/*
+ * Should this new latency be reported/recorded?
+ */
+static int report_latency(cycle_t delta)
+{
+ if (latency_hist_flag && !trace_user_triggered)
+ return 1;
+
+ if (preempt_thresh) {
+ if (delta < preempt_thresh)
+ return 0;
+ } else {
+ if (delta <= preempt_max_latency)
+ return 0;
+ }
+ return 1;
+}
+
+#ifdef CONFIG_EVENT_TRACE
+
+/*
+ * Number of per-CPU trace entries:
+ */
+#define MAX_TRACE (65536UL*16UL)
+
+#define CMDLINE_BYTES 16
+
+/*
+ * 32 bytes on 32-bit platforms:
+ */
+struct trace_entry {
+ char type;
+ char cpu;
+ char flags;
+ char preempt_count; // assumes PREEMPT_MASK is 8 bits or less
+ int pid;
+ cycle_t timestamp;
+ union {
+ struct {
+ unsigned long eip;
+ unsigned long parent_eip;
+ } fn;
+ struct {
+ unsigned long eip;
+ unsigned long v1, v2, v3;
+ } special;
+ struct {
+ unsigned char str[CMDLINE_BYTES];
+ } cmdline;
+ struct {
+ unsigned long nr; // highest bit: compat call
+ unsigned long p1, p2, p3;
+ } syscall;
+ struct {
+ unsigned long ret;
+ } sysret;
+ struct {
+ unsigned long __pad3[4];
+ } pad;
+ } u;
+} __attribute__((packed));
+
+#endif
+
+struct cpu_trace {
+ atomic_t disabled;
+ unsigned long trace_idx;
+ cycle_t preempt_timestamp;
+ unsigned long critical_start, critical_end;
+ unsigned long critical_sequence;
+ atomic_t underrun;
+ atomic_t overrun;
+ int early_warning;
+ int latency_type;
+ int cpu;
+
+#ifdef CONFIG_EVENT_TRACE
+ struct trace_entry *trace;
+ char comm[CMDLINE_BYTES];
+ pid_t pid;
+ unsigned long uid;
+ unsigned long nice;
+ unsigned long policy;
+ unsigned long rt_priority;
+ unsigned long saved_latency;
+#endif
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+ unsigned long stack_check;
+#endif
+} ____cacheline_aligned_in_smp;
+
+static struct cpu_trace cpu_traces[NR_CPUS] ____cacheline_aligned_in_smp =
+{ [0 ... NR_CPUS-1] = {
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+ .stack_check = 1
+#endif
+ } };
+
+#ifdef CONFIG_EVENT_TRACE
+
+int trace_enabled = 0;
+int syscall_tracing = 1;
+int stackframe_tracing = 0;
+int mcount_enabled = 0;
+int trace_freerunning = 0;
+int trace_print_on_crash = 0;
+int trace_verbose = 0;
+int trace_all_cpus = 0;
+int print_functions = 0;
+int trace_all_runnable = 0;
+
+/*
+ * user-triggered via gettimeofday(0,1)/gettimeofday(0,0)
+ */
+int trace_user_triggered = 0;
+int trace_user_trigger_irq = -1;
+
+void trace_start_ht_debug(void)
+{
+ trace_all_cpus = 0;
+ trace_freerunning = 1;
+ trace_user_triggered = 1;
+ mcount_enabled = 1;
+ trace_enabled = 1;
+ user_trace_start();
+}
+
+struct saved_trace_struct {
+ int cpu;
+ cycle_t first_timestamp, last_timestamp;
+ struct cpu_trace traces[NR_CPUS];
+} ____cacheline_aligned_in_smp;
+
+/*
+ * The current worst-case trace:
+ */
+static struct saved_trace_struct max_tr;
+
+/*
+ * /proc/latency_trace atomicity:
+ */
+static DECLARE_MUTEX(out_mutex);
+
+static struct saved_trace_struct out_tr;
+
+static void notrace printk_name(unsigned long eip)
+{
+ char namebuf[KSYM_NAME_LEN+1];
+ unsigned long size, offset;
+ const char *sym_name;
+ char *modname;
+
+ sym_name = kallsyms_lookup(eip, &size, &offset, &modname, namebuf);
+ if (sym_name)
+ printk("%s+%#lx/%#lx", sym_name, offset, size);
+ else
+ printk("<%08lx>", eip);
+}
+
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+
+#ifndef STACK_WARN
+# define STACK_WARN (THREAD_SIZE/8)
+#endif
+
+#define MIN_STACK_NEEDED (sizeof(struct thread_info) + STACK_WARN)
+#define MAX_STACK (THREAD_SIZE - sizeof(struct thread_info))
+
+#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_FRAME_POINTER)
+# define PRINT_EXACT_STACKFRAME
+#endif
+
+#ifdef PRINT_EXACT_STACKFRAME
+static unsigned long *worst_stack_bp;
+#endif
+static DEFINE_RAW_SPINLOCK(worst_stack_lock);
+unsigned long worst_stack_left = THREAD_SIZE;
+static unsigned long worst_stack_printed = THREAD_SIZE;
+static char worst_stack_comm[TASK_COMM_LEN+1];
+static int worst_stack_pid;
+static unsigned long worst_stack_sp;
+static char worst_stack[THREAD_SIZE];
+
+static notrace void fill_worst_stack(unsigned long stack_left)
+{
+ unsigned long flags;
+
+ /*
+ * On x64, we must not read the PDA during early bootup:
+ */
+#ifdef CONFIG_X86_64
+ if (system_state == SYSTEM_BOOTING)
+ return;
+#endif
+ spin_lock_irqsave(&worst_stack_lock, flags);
+ if (likely(stack_left < worst_stack_left)) {
+ worst_stack_left = stack_left;
+ memcpy(worst_stack, current_thread_info(), THREAD_SIZE);
+ worst_stack_sp = (unsigned long)&stack_left;
+ memcpy(worst_stack_comm, current->comm, TASK_COMM_LEN);
+ worst_stack_pid = current->pid;
+#ifdef PRINT_EXACT_STACKFRAME
+# ifdef __i386__
+ asm ("mov %%ebp, %0\n" :"=g"(worst_stack_bp));
+# elif defined(__x86_64__)
+ asm ("mov %%rbp, %0\n" :"=g"(worst_stack_bp));
+# else
+# error Poke the author of above asm code lines !
+# endif
+#endif
+ }
+ spin_unlock_irqrestore(&worst_stack_lock, flags);
+}
+
+#ifdef PRINT_EXACT_STACKFRAME
+
+/*
+ * This takes a BP offset to point the BP back into the saved stack,
+ * the original stack might be long gone (but the stackframe within
+ * the saved copy still contains references to it).
+ */
+#define CONVERT_TO_SAVED_STACK(bp) \
+ ((void *)worst_stack + ((unsigned long)bp & (THREAD_SIZE-1)))
+
+static void show_stackframe(void)
+{
+ unsigned long addr, frame_size, *bp, *prev_bp, sum = 0;
+
+ bp = CONVERT_TO_SAVED_STACK(worst_stack_bp);
+
+ while (bp[0]) {
+ addr = bp[1];
+ if (!kernel_text_address(addr))
+ break;
+
+ prev_bp = bp;
+ bp = CONVERT_TO_SAVED_STACK((unsigned long *)bp[0]);
+
+ frame_size = (bp - prev_bp) * sizeof(long);
+
+ if (frame_size < THREAD_SIZE) {
+ printk("{ %4ld} ", frame_size);
+ sum += frame_size;
+ } else
+ printk("{=%4ld} ", sum);
+
+ printk("[<%08lx>] ", addr);
+ printk_name(addr);
+ printk("\n");
+ }
+}
+
+#else
+
+static inline int valid_stack_ptr(void *p)
+{
+ return p > (void *)worst_stack &&
+ p < (void *)worst_stack + THREAD_SIZE - 3;
+}
+
+static void show_stackframe(void)
+{
+ unsigned long prev_frame, addr;
+ unsigned long *stack;
+
+ prev_frame = (unsigned long)(worst_stack +
+ (worst_stack_sp & (THREAD_SIZE-1)));
+ stack = (unsigned long *)prev_frame;
+
+ while (valid_stack_ptr(stack)) {
+ addr = *stack++;
+ if (__kernel_text_address(addr)) {
+ printk("(%4ld) ", (unsigned long)stack - prev_frame);
+ printk("[<%08lx>] ", addr);
+ print_symbol("%s\n", addr);
+ prev_frame = (unsigned long)stack;
+ }
+ if ((char *)stack >= worst_stack + THREAD_SIZE)
+ break;
+ }
+}
+
+#endif
+
+static notrace void __print_worst_stack(void)
+{
+ unsigned long fill_ratio;
+ printk("----------------------------->\n");
+ printk("| new stack fill maximum: %s/%d, %ld bytes (out of %ld bytes).\n",
+ worst_stack_comm, worst_stack_pid,
+ MAX_STACK-worst_stack_left, (long)MAX_STACK);
+ fill_ratio = (MAX_STACK-worst_stack_left)*100/(long)MAX_STACK;
+ printk("| Stack fill ratio: %02ld%%", fill_ratio);
+ if (fill_ratio >= 90)
+ printk(" - BUG: that's quite high, please report this!\n");
+ else
+ printk(" - that's still OK, no need to report this.\n");
+ printk("------------|\n");
+
+ show_stackframe();
+ printk("<---------------------------\n\n");
+}
+
+static notrace void print_worst_stack(void)
+{
+ unsigned long flags;
+
+ if (irqs_disabled() || preempt_count())
+ return;
+
+ spin_lock_irqsave(&worst_stack_lock, flags);
+ if (worst_stack_printed == worst_stack_left) {
+ spin_unlock_irqrestore(&worst_stack_lock, flags);
+ return;
+ }
+ worst_stack_printed = worst_stack_left;
+ spin_unlock_irqrestore(&worst_stack_lock, flags);
+
+ __print_worst_stack();
+}
+
+static notrace void debug_stackoverflow(struct cpu_trace *tr)
+{
+ long stack_left;
+
+ if (unlikely(tr->stack_check <= 0))
+ return;
+ atomic_inc(&tr->disabled);
+
+ /* Debugging check for stack overflow: is there less than 1KB free? */
+#ifdef __i386__
+ __asm__ __volatile__("and %%esp,%0" :
+ "=r" (stack_left) : "0" (THREAD_SIZE - 1));
+#elif defined(__x86_64__)
+ __asm__ __volatile__("and %%rsp,%0" :
+ "=r" (stack_left) : "0" (THREAD_SIZE - 1));
+#else
+# error Poke the author of above asm code lines !
+#endif
+ if (unlikely(stack_left < MIN_STACK_NEEDED)) {
+ tr->stack_check = 0;
+ printk(KERN_ALERT "BUG: stack overflow: only %ld bytes left! [%08lx...(%08lx-%08lx)]\n",
+ stack_left - sizeof(struct thread_info),
+ (long)&stack_left,
+ (long)current_thread_info(),
+ (long)current_thread_info() + THREAD_SIZE);
+ fill_worst_stack(stack_left);
+ __print_worst_stack();
+ goto out;
+ }
+ if (unlikely(stack_left < worst_stack_left)) {
+ tr->stack_check--;
+ fill_worst_stack(stack_left);
+ print_worst_stack();
+ tr->stack_check++;
+ } else
+ if (worst_stack_printed != worst_stack_left) {
+ tr->stack_check--;
+ print_worst_stack();
+ tr->stack_check++;
+ }
+out:
+ atomic_dec(&tr->disabled);
+}
+
+#endif
+
+#ifdef CONFIG_EARLY_PRINTK
+static void notrace early_printk_name(unsigned long eip)
+{
+ char namebuf[KSYM_NAME_LEN+1];
+ unsigned long size, offset;
+ const char *sym_name;
+ char *modname;
+
+ sym_name = kallsyms_lookup(eip, &size, &offset, &modname, namebuf);
+ if (sym_name)
+ early_printk("%s <%08lx>", sym_name, eip);
+ else
+ early_printk("<%08lx>", eip);
+}
+
+static __raw_spinlock_t early_print_lock = __RAW_SPIN_LOCK_UNLOCKED;
+
+static void notrace early_print_entry(struct trace_entry *entry)
+{
+ int hardirq, softirq;
+
+ __raw_spin_lock(&early_print_lock);
+ early_printk("%-5d ", entry->pid);
+
+ early_printk("%d%c%c",
+ entry->cpu,
+ (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
+ (entry->flags & TRACE_FLAG_IRQS_HARD_OFF) ? 'D' : '.',
+ (entry->flags & TRACE_FLAG_NEED_RESCHED_DELAYED) ? 'n' :
+ ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
+
+ hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
+ softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
+ if (hardirq && softirq)
+ early_printk("H");
+ else {
+ if (hardirq)
+ early_printk("h");
+ else {
+ if (softirq)
+ early_printk("s");
+ else
+ early_printk(".");
+ }
+ }
+
+ early_printk(":%d: ", entry->preempt_count);
+
+ if (entry->type == TRACE_FN) {
+ early_printk_name(entry->u.fn.eip);
+ early_printk(" <= (");
+ early_printk_name(entry->u.fn.parent_eip);
+ early_printk(")\n");
+ } else {
+ /* special entries: */
+ early_printk_name(entry->u.special.eip);
+ early_printk(": <%08lx> <%08lx> <%08lx>\n",
+ entry->u.special.v1,
+ entry->u.special.v2,
+ entry->u.special.v3);
+ }
+ __raw_spin_unlock(&early_print_lock);
+}
+#else
+# define early_print_entry(x) do { } while(0)
+#endif
+
+static void notrace
+____trace(int cpu, enum trace_type type, struct cpu_trace *tr,
+ unsigned long eip, unsigned long parent_eip,
+ unsigned long v1, unsigned long v2, unsigned long v3,
+ unsigned long flags)
+{
+ struct trace_entry *entry;
+ unsigned long idx, idx_next;
+ cycle_t timestamp;
+ u32 pc;
+
+#ifdef CONFIG_DEBUG_PREEMPT
+// WARN_ON(!atomic_read(&tr->disabled));
+#endif
+ if (!tr->critical_start && !trace_user_triggered && !trace_all_cpus &&
+ !trace_print_on_crash && !print_functions)
+ goto out;
+ /*
+ * Allocate the next index. Make sure an NMI (or interrupt)
+ * has not taken it away. Potentially redo the timestamp as
+ * well to make sure the trace timestamps are in chronologic
+ * order.
+ */
+again:
+ idx = tr->trace_idx;
+ idx_next = idx + 1;
+ timestamp = now();
+
+ if (unlikely((trace_freerunning || print_functions || atomic_read(&tr->underrun)) &&
+ (idx_next >= MAX_TRACE) && !atomic_read(&tr->overrun))) {
+ atomic_inc(&tr->underrun);
+ idx_next = 0;
+ }
+ if (unlikely(idx >= MAX_TRACE)) {
+ atomic_inc(&tr->overrun);
+ goto out;
+ }
+#ifdef __HAVE_ARCH_CMPXCHG
+ if (unlikely(cmpxchg(&tr->trace_idx, idx, idx_next) != idx)) {
+ if (idx_next == 0)
+ atomic_dec(&tr->underrun);
+ goto again;
+ }
+#else
+# ifdef CONFIG_SMP
+# error CMPXCHG missing
+# else
+ /* No worry, we are protected by the atomic_incr(&tr->disabled)
+ * in __trace further down
+ */
+ tr->trace_idx = idx_next;
+# endif
+#endif
+ if (unlikely(idx_next != 0 && atomic_read(&tr->underrun)))
+ atomic_inc(&tr->underrun);
+
+ pc = preempt_count();
+
+ if (unlikely(!tr->trace))
+ goto out;
+ entry = tr->trace + idx;
+ entry->type = type;
+#ifdef CONFIG_SMP
+ entry->cpu = cpu;
+#endif
+ entry->flags = (irqs_off() ? TRACE_FLAG_IRQS_OFF : 0) |
+ (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_HARD_OFF : 0)|
+ ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) |
+ ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
+ (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0) |
+ (need_resched_delayed() ? TRACE_FLAG_NEED_RESCHED_DELAYED : 0);
+ entry->preempt_count = pc & 0xff;
+ entry->pid = current->pid;
+ entry->timestamp = timestamp;
+
+ switch (type) {
+ case TRACE_FN:
+ entry->u.fn.eip = eip;
+ entry->u.fn.parent_eip = parent_eip;
+ if (unlikely(print_functions && !in_interrupt()))
+ early_print_entry(entry);
+ break;
+ case TRACE_SPECIAL:
+ case TRACE_SPECIAL_PID:
+ case TRACE_SPECIAL_U64:
+ case TRACE_SPECIAL_SYM:
+ entry->u.special.eip = eip;
+ entry->u.special.v1 = v1;
+ entry->u.special.v2 = v2;
+ entry->u.special.v3 = v3;
+ if (unlikely(print_functions && !in_interrupt()))
+ early_print_entry(entry);
+ break;
+ case TRACE_SYSCALL:
+ entry->u.syscall.nr = eip;
+ entry->u.syscall.p1 = v1;
+ entry->u.syscall.p2 = v2;
+ entry->u.syscall.p3 = v3;
+ break;
+ case TRACE_SYSRET:
+ entry->u.sysret.ret = eip;
+ break;
+ case TRACE_CMDLINE:
+ memcpy(entry->u.cmdline.str, current->comm, CMDLINE_BYTES);
+ break;
+ default:
+ break;
+ }
+out:
+ ;
+}
+
+static inline void notrace
+___trace(enum trace_type type, unsigned long eip, unsigned long parent_eip,
+ unsigned long v1, unsigned long v2,
+ unsigned long v3)
+{
+ struct cpu_trace *tr;
+ unsigned long flags;
+ int cpu;
+
+ if (unlikely(trace_enabled <= 0))
+ return;
+
+#if defined(CONFIG_DEBUG_STACKOVERFLOW) && defined(CONFIG_X86)
+ debug_stackoverflow(cpu_traces + raw_smp_processor_id());
+#endif
+
+ raw_local_irq_save(flags);
+ cpu = raw_smp_processor_id();
+ /*
+ * Trace on the CPU where the current highest-prio task
+ * is waiting to become runnable:
+ */
+#ifdef CONFIG_WAKEUP_TIMING
+ if (wakeup_timing && !trace_all_cpus && !trace_print_on_crash &&
+ !print_functions) {
+ if (!sch.tr || cpu != sch.cpu)
+ goto out;
+ tr = sch.tr;
+ } else
+ tr = cpu_traces + cpu;
+#else
+ tr = cpu_traces + cpu;
+#endif
+ atomic_inc(&tr->disabled);
+ if (likely(atomic_read(&tr->disabled) == 1)) {
+//#define DEBUG_STACK_POISON
+#ifdef DEBUG_STACK_POISON
+ char stack;
+
+ memset(&stack - 128, 0x34, 128);
+#endif
+ ____trace(cpu, type, tr, eip, parent_eip, v1, v2, v3, flags);
+ }
+ atomic_dec(&tr->disabled);
+#ifdef CONFIG_WAKEUP_TIMING
+out:
+#endif
+ raw_local_irq_restore(flags);
+}
+
+/*
+ * Special, ad-hoc tracepoints:
+ */
+void notrace trace_special(unsigned long v1, unsigned long v2, unsigned long v3)
+{
+ ___trace(TRACE_SPECIAL, CALLER_ADDR0, 0, v1, v2, v3);
+}
+
+EXPORT_SYMBOL(trace_special);
+
+void notrace trace_special_pid(int pid, unsigned long v1, unsigned long v2)
+{
+ ___trace(TRACE_SPECIAL_PID, CALLER_ADDR0, 0, pid, v1, v2);
+}
+
+EXPORT_SYMBOL(trace_special_pid);
+
+void notrace trace_special_u64(unsigned long long v1, unsigned long v2)
+{
+ ___trace(TRACE_SPECIAL_U64, CALLER_ADDR0, 0,
+ (unsigned long) (v1 >> 32), (unsigned long) (v1 & 0xFFFFFFFF),
+ v2);
+}
+
+EXPORT_SYMBOL(trace_special_u64);
+
+void notrace trace_special_sym(void)
+{
+#define STACK_ENTRIES 8
+ unsigned long entries[STACK_ENTRIES];
+ struct stack_trace trace;
+
+ if (!trace_enabled)
+ return;
+
+ if (!stackframe_tracing)
+ return ___trace(TRACE_SPECIAL, CALLER_ADDR0, 0, CALLER_ADDR1, 0, 0);
+
+ trace.entries = entries;
+ trace.skip = 3;
+#if 0
+ trace.all_contexts = 1;
+#endif
+ trace.max_entries = STACK_ENTRIES;
+ trace.nr_entries = 0;
+
+#if 0
+ save_stack_trace(&trace, NULL);
+#else
+ save_stack_trace(&trace);
+#endif
+ /*
+ * clear out the rest:
+ */
+ while (trace.nr_entries < trace.max_entries)
+ entries[trace.nr_entries++] = 0;
+
+ ___trace(TRACE_SPECIAL_SYM, entries[0], 0,
+ entries[1], entries[2], entries[3]);
+ ___trace(TRACE_SPECIAL_SYM, entries[4], 0,
+ entries[5], entries[6], entries[7]);
+}
+
+EXPORT_SYMBOL(trace_special_sym);
+
+/*
+ * Non-inlined function:
+ */
+void notrace __trace(unsigned long eip, unsigned long parent_eip)
+{
+ ___trace(TRACE_FN, eip, parent_eip, 0, 0, 0);
+}
+
+#ifdef CONFIG_MCOUNT
+
+extern void mcount(void);
+
+EXPORT_SYMBOL(mcount);
+
+void notrace __mcount(void)
+{
+ ___trace(TRACE_FN, CALLER_ADDR1, CALLER_ADDR2, 0, 0, 0);
+}
+
+#endif
+
+void notrace
+sys_call(unsigned long nr, unsigned long p1, unsigned long p2, unsigned long p3)
+{
+ if (syscall_tracing)
+ ___trace(TRACE_SYSCALL, nr, 0, p1, p2, p3);
+}
+
+#if defined(CONFIG_COMPAT) && defined(CONFIG_X86)
+
+void notrace
+sys_ia32_call(unsigned long nr, unsigned long p1, unsigned long p2,
+ unsigned long p3)
+{
+ if (syscall_tracing)
+ ___trace(TRACE_SYSCALL, nr | 0x80000000, 0, p1, p2, p3);
+}
+
+#endif
+
+void notrace sys_ret(unsigned long ret)
+{
+ if (syscall_tracing)
+ ___trace(TRACE_SYSRET, ret, 0, 0, 0, 0);
+}
+
+static void notrace print_name(struct seq_file *m, unsigned long eip)
+{
+ char namebuf[KSYM_NAME_LEN+1];
+ unsigned long size, offset;
+ const char *sym_name;
+ char *modname;
+
+ /*
+ * Special trace values:
+ */
+ if (((long)eip < 10000L) && ((long)eip > -10000L)) {
+ seq_printf(m, "(%5ld)", eip);
+ return;
+ }
+ sym_name = kallsyms_lookup(eip, &size, &offset, &modname, namebuf);
+ if (sym_name)
+ seq_puts(m, sym_name);
+ else
+ seq_printf(m, "<%08lx>", eip);
+}
+
+static void notrace print_name_offset(struct seq_file *m, unsigned long eip)
+{
+ char namebuf[KSYM_NAME_LEN+1];
+ unsigned long size, offset;
+ const char *sym_name;
+ char *modname;
+
+ sym_name = kallsyms_lookup(eip, &size, &offset, &modname, namebuf);
+ if (sym_name)
+ seq_printf(m, "%s+%#lx/%#lx <%08lx>",
+ sym_name, offset, size, eip);
+ else
+ seq_printf(m, "<%08lx>", eip);
+}
+
+static unsigned long out_sequence = -1;
+
+static int pid_to_cmdline_array[PID_MAX_DEFAULT+1];
+
+static void notrace _trace_cmdline(int cpu, struct cpu_trace *tr)
+{
+ unsigned long flags;
+
+ local_save_flags(flags);
+ ____trace(cpu, TRACE_CMDLINE, tr, 0, 0, 0, 0, 0, flags);
+}
+
+void notrace trace_cmdline(void)
+{
+ ___trace(TRACE_CMDLINE, 0, 0, 0, 0, 0);
+}
+
+static void construct_pid_to_cmdline(struct cpu_trace *tr)
+{
+ unsigned int i, j, entries, pid;
+
+ if (tr->critical_sequence == out_sequence)
+ return;
+ out_sequence = tr->critical_sequence;
+
+ memset(pid_to_cmdline_array, -1, sizeof(int) * (PID_MAX_DEFAULT + 1));
+
+ if (!tr->trace)
+ return;
+
+ entries = min(tr->trace_idx, MAX_TRACE);
+
+ for (i = 0; i < entries; i++) {
+ struct trace_entry *entry = tr->trace + i;
+
+ if (entry->type != TRACE_CMDLINE)
+ continue;
+ pid = entry->pid;
+ if (pid < PID_MAX_DEFAULT) {
+ pid_to_cmdline_array[pid] = i;
+ /*
+ * Replace space with underline - makes it easier
+ * to process for tools:
+ */
+ for (j = 0; j < CMDLINE_BYTES; j++)
+ if (entry->u.cmdline.str[j] == ' ')
+ entry->u.cmdline.str[j] = '_';
+ }
+ }
+}
+
+char *pid_to_cmdline(unsigned long pid)
+{
+ struct cpu_trace *tr = out_tr.traces + 0;
+ char *cmdline = "<...>";
+ int idx;
+
+ pid = min(pid, (unsigned long)PID_MAX_DEFAULT);
+ if (!pid)
+ return "<idle>";
+
+ if (pid_to_cmdline_array[pid] != -1) {
+ idx = pid_to_cmdline_array[pid];
+ if (tr->trace[idx].type == TRACE_CMDLINE)
+ cmdline = tr->trace[idx].u.cmdline.str;
+ }
+ return cmdline;
+}
+
+static void copy_trace(struct cpu_trace *save, struct cpu_trace *tr, int reorder)
+{
+ if (!save->trace || !tr->trace)
+ return;
+ /* free-running needs reordering */
+ if (reorder && atomic_read(&tr->underrun)) {
+ int i, idx, idx0 = tr->trace_idx;
+
+ for (i = 0; i < MAX_TRACE; i++) {
+ idx = (idx0 + i) % MAX_TRACE;
+ save->trace[i] = tr->trace[idx];
+ }
+ save->trace_idx = MAX_TRACE;
+ } else {
+ save->trace_idx = tr->trace_idx;
+
+ memcpy(save->trace, tr->trace,
+ min(save->trace_idx, MAX_TRACE) *
+ sizeof(struct trace_entry));
+ }
+ save->underrun = tr->underrun;
+ save->overrun = tr->overrun;
+}
+
+
+struct block_idx {
+ int idx[NR_CPUS];
+};
+
+/*
+ * return the trace entry (position) of the smallest-timestamp
+ * one (that is still in the valid idx range):
+ */
+static int min_idx(struct block_idx *bidx)
+{
+ cycle_t min_stamp = (cycle_t) -1;
+ struct trace_entry *entry;
+ int cpu, min_cpu = -1, idx;
+
+ for_each_online_cpu(cpu) {
+ idx = bidx->idx[cpu];
+ if (idx >= min(max_tr.traces[cpu].trace_idx, MAX_TRACE))
+ continue;
+ if (idx > MAX_TRACE*NR_CPUS) {
+ printk("huh: idx (%d) > %ld*%d!\n", idx, MAX_TRACE,
+ NR_CPUS);
+ WARN_ON(1);
+ break;
+ }
+ entry = max_tr.traces[cpu].trace + bidx->idx[cpu];
+ if (entry->timestamp < min_stamp) {
+ min_cpu = cpu;
+ min_stamp = entry->timestamp;
+ }
+ }
+
+ return min_cpu;
+}
+
+/*
+ * This code is called to construct an output trace from
+ * the maximum trace. Having separate traces serves both
+ * atomicity (a new max might be saved while we are busy
+ * accessing /proc/latency_trace) and it is also used to
+ * delay the (expensive) sorting of the output trace by
+ * timestamps, in the trace_all_cpus case.
+ */
+static void update_out_trace(void)
+{
+ struct trace_entry *out_entry, *entry, *tmp;
+ cycle_t stamp, first_stamp, last_stamp;
+ struct block_idx bidx = { { 0, }, };
+ struct cpu_trace *tmp_max, *tmp_out;
+ int cpu, sum, entries, underrun_sum, overrun_sum;
+
+ /*
+ * For out_tr we only have the first array's trace entries
+ * allocated - and they have are larger on SMP to make room
+ * for all trace entries from all CPUs.
+ */
+ tmp_out = out_tr.traces + 0;
+ tmp_max = max_tr.traces + max_tr.cpu;
+ /*
+ * Easier to copy this way. Note: the trace buffer is private
+ * to the output buffer, so preserve it:
+ */
+ copy_trace(tmp_out, tmp_max, 0);
+ tmp = tmp_out->trace;
+ *tmp_out = *tmp_max;
+ tmp_out->trace = tmp;
+
+ out_tr.cpu = max_tr.cpu;
+
+ if (!tmp_out->trace)
+ return;
+
+ out_entry = tmp_out->trace + 0;
+
+ if (!trace_all_cpus) {
+ entries = min(tmp_out->trace_idx, MAX_TRACE);
+ if (!entries)
+ return;
+ out_tr.first_timestamp = tmp_out->trace[0].timestamp;
+ out_tr.last_timestamp = tmp_out->trace[entries-1].timestamp;
+ return;
+ }
+ /*
+ * Find the range of timestamps that are fully traced in
+ * all CPU traces. (since CPU traces can cover a variable
+ * range of time, we have to find the best range.)
+ */
+ first_stamp = 0;
+ for_each_online_cpu(cpu) {
+ tmp_max = max_tr.traces + cpu;
+ stamp = tmp_max->trace[0].timestamp;
+ if (stamp > first_stamp)
+ first_stamp = stamp;
+ }
+ /*
+ * Save the timestamp range:
+ */
+ tmp_max = max_tr.traces + max_tr.cpu;
+ entries = min(tmp_max->trace_idx, MAX_TRACE);
+ /*
+ * No saved trace yet?
+ */
+ if (!entries) {
+ out_tr.traces[0].trace_idx = 0;
+ return;
+ }
+
+ last_stamp = tmp_max->trace[entries-1].timestamp;
+
+ if (last_stamp < first_stamp) {
+ WARN_ON(1);
+
+ for_each_online_cpu(cpu) {
+ tmp_max = max_tr.traces + cpu;
+ entries = min(tmp_max->trace_idx, MAX_TRACE);
+ printk("CPU%d: %016Lx (%016Lx) ... #%d (%016Lx) %016Lx\n",
+ cpu,
+ tmp_max->trace[0].timestamp,
+ tmp_max->trace[1].timestamp,
+ entries,
+ tmp_max->trace[entries-2].timestamp,
+ tmp_max->trace[entries-1].timestamp);
+ }
+ tmp_max = max_tr.traces + max_tr.cpu;
+ entries = min(tmp_max->trace_idx, MAX_TRACE);
+
+ printk("CPU%d entries: %d\n", max_tr.cpu, entries);
+ printk("first stamp: %016Lx\n", first_stamp);
+ printk(" last stamp: %016Lx\n", first_stamp);
+ }
+
+#if 0
+ printk("first_stamp: %Ld [%016Lx]\n", first_stamp, first_stamp);
+ printk(" last_stamp: %Ld [%016Lx]\n", last_stamp, last_stamp);
+ printk(" +1 stamp: %Ld [%016Lx]\n",
+ tmp_max->trace[entries].timestamp,
+ tmp_max->trace[entries].timestamp);
+ printk(" +2 stamp: %Ld [%016Lx]\n",
+ tmp_max->trace[entries+1].timestamp,
+ tmp_max->trace[entries+1].timestamp);
+ printk(" delta: %Ld\n", last_stamp-first_stamp);
+ printk(" entries: %d\n", entries);
+#endif
+
+ out_tr.first_timestamp = first_stamp;
+ out_tr.last_timestamp = last_stamp;
+
+ /*
+ * Fetch trace entries one by one, in increasing timestamp
+ * order. Start at first_stamp, stop at last_stamp:
+ */
+ sum = 0;
+ for (;;) {
+ cpu = min_idx(&bidx);
+ if (cpu == -1)
+ break;
+ entry = max_tr.traces[cpu].trace + bidx.idx[cpu];
+ if (entry->timestamp > last_stamp)
+ break;
+
+ bidx.idx[cpu]++;
+ if (entry->timestamp < first_stamp)
+ continue;
+ *out_entry = *entry;
+ out_entry++;
+ sum++;
+ if (sum > MAX_TRACE*NR_CPUS) {
+ printk("huh: sum (%d) > %ld*%d!\n", sum, MAX_TRACE,
+ NR_CPUS);
+ WARN_ON(1);
+ break;
+ }
+ }
+
+ sum = 0;
+ underrun_sum = 0;
+ overrun_sum = 0;
+ for_each_online_cpu(cpu) {
+ sum += max_tr.traces[cpu].trace_idx;
+ underrun_sum += atomic_read(&max_tr.traces[cpu].underrun);
+ overrun_sum += atomic_read(&max_tr.traces[cpu].overrun);
+ }
+ tmp_out->trace_idx = sum;
+ atomic_set(&tmp_out->underrun, underrun_sum);
+ atomic_set(&tmp_out->overrun, overrun_sum);
+}
+
+static void notrace print_help_header(struct seq_file *m)
+{
+ seq_puts(m, " _------=> CPU# \n");
+ seq_puts(m, " / _-----=> irqs-off \n");
+ seq_puts(m, " | / _----=> need-resched \n");
+ seq_puts(m, " || / _---=> hardirq/softirq \n");
+ seq_puts(m, " ||| / _--=> preempt-depth \n");
+ seq_puts(m, " |||| / \n");
+ seq_puts(m, " ||||| delay \n");
+ seq_puts(m, " cmd pid ||||| time | caller \n");
+ seq_puts(m, " \\ / ||||| \\ | / \n");
+}
+
+static void * notrace l_start(struct seq_file *m, loff_t *pos)
+{
+ loff_t n = *pos;
+ unsigned long entries;
+ struct cpu_trace *tr = out_tr.traces + 0;
+
+ down(&out_mutex);
+ /*
+ * if the file is being read newly, update the output trace:
+ */
+ if (!n) {
+ // TODO: use the sequence counter here to optimize
+ down(&max_mutex);
+ update_out_trace();
+ up(&max_mutex);
+#if 0
+ if (!tr->trace_idx) {
+ up(&out_mutex);
+ return NULL;
+ }
+#endif
+ construct_pid_to_cmdline(tr);
+ }
+ entries = min(tr->trace_idx, MAX_TRACE);
+
+ if (!n) {
+ seq_printf(m, "preemption latency trace v1.1.5 on %s\n",
+ UTS_RELEASE);
+ seq_puts(m, "--------------------------------------------------------------------\n");
+ seq_printf(m, " latency: %lu us, #%lu/%lu, CPU#%d | (M:%s VP:%d, KP:%d, SP:%d HP:%d",
+ cycles_to_usecs(tr->saved_latency),
+ entries,
+ (entries + atomic_read(&tr->underrun) +
+ atomic_read(&tr->overrun)),
+ out_tr.cpu,
+#if defined(CONFIG_PREEMPT_NONE)
+ "server",
+#elif defined(CONFIG_PREEMPT_VOLUNTARY)
+ "desktop",
+#elif defined(CONFIG_PREEMPT_DESKTOP)
+ "preempt",
+#else
+ "rt",
+#endif
+ 0, 0,
+#ifdef CONFIG_PREEMPT_SOFTIRQS
+ softirq_preemption
+#else
+ 0
+#endif
+ ,
+#ifdef CONFIG_PREEMPT_HARDIRQS
+ hardirq_preemption
+#else
+ 0
+#endif
+ );
+#ifdef CONFIG_SMP
+ seq_printf(m, " #P:%d)\n", num_online_cpus());
+#else
+ seq_puts(m, ")\n");
+#endif
+ seq_puts(m, " -----------------\n");
+ seq_printf(m, " | task: %.16s-%d (uid:%ld nice:%ld policy:%ld rt_prio:%ld)\n",
+ tr->comm, tr->pid, tr->uid, tr->nice,
+ tr->policy, tr->rt_priority);
+ seq_puts(m, " -----------------\n");
+ if (trace_user_triggered) {
+ seq_puts(m, " => started at: ");
+ print_name_offset(m, tr->critical_start);
+ seq_puts(m, "\n => ended at: ");
+ print_name_offset(m, tr->critical_end);
+ seq_puts(m, "\n");
+ }
+ seq_puts(m, "\n");
+
+ if (!trace_verbose)
+ print_help_header(m);
+ }
+ if (n >= entries || !tr->trace)
+ return NULL;
+
+ return tr->trace + n;
+}
+
+static void * notrace l_next(struct seq_file *m, void *p, loff_t *pos)
+{
+ struct cpu_trace *tr = out_tr.traces;
+ unsigned long entries = min(tr->trace_idx, MAX_TRACE);
+
+ WARN_ON(!tr->trace);
+
+ if (++*pos >= entries) {
+ if (*pos == entries)
+ seq_puts(m, "\n\nvim:ft=help\n");
+ return NULL;
+ }
+ return tr->trace + *pos;
+}
+
+static void notrace l_stop(struct seq_file *m, void *p)
+{
+ up(&out_mutex);
+}
+
+static void print_timestamp(struct seq_file *m, unsigned long abs_usecs,
+ unsigned long rel_usecs)
+{
+ seq_printf(m, " %4ldus", abs_usecs);
+ if (rel_usecs > 100)
+ seq_puts(m, "!: ");
+ else if (rel_usecs > 1)
+ seq_puts(m, "+: ");
+ else
+ seq_puts(m, " : ");
+}
+
+static void
+print_timestamp_short(struct seq_file *m, unsigned long abs_usecs,
+ unsigned long rel_usecs)
+{
+ seq_printf(m, " %4ldus", abs_usecs);
+ if (rel_usecs > 100)
+ seq_putc(m, '!');
+ else if (rel_usecs > 1)
+ seq_putc(m, '+');
+ else
+ seq_putc(m, ' ');
+}
+
+static void
+print_generic(struct seq_file *m, struct trace_entry *entry)
+{
+ int hardirq, softirq;
+
+ seq_printf(m, "%8.8s-%-5d ", pid_to_cmdline(entry->pid), entry->pid);
+ seq_printf(m, "%d", entry->cpu);
+ seq_printf(m, "%c%c",
+ (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
+ (entry->flags & TRACE_FLAG_IRQS_HARD_OFF) ? 'D' : '.',
+ (entry->flags & TRACE_FLAG_NEED_RESCHED_DELAYED) ? 'n' :
+ ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
+
+ hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
+ softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
+ if (hardirq && softirq)
+ seq_putc(m, 'H');
+ else {
+ if (hardirq)
+ seq_putc(m, 'h');
+ else {
+ if (softirq)
+ seq_putc(m, 's');
+ else
+ seq_putc(m, '.');
+ }
+ }
+
+ if (entry->preempt_count)
+ seq_printf(m, "%x", entry->preempt_count);
+ else
+ seq_puts(m, ".");
+}
+
+
+static int notrace l_show_fn(struct seq_file *m, unsigned long trace_idx,
+ struct trace_entry *entry, struct trace_entry *entry0,
+ struct trace_entry *next_entry)
+{
+ unsigned long abs_usecs, rel_usecs;
+
+ abs_usecs = cycles_to_us(entry->timestamp - entry0->timestamp);
+ rel_usecs = cycles_to_us(next_entry->timestamp - entry->timestamp);
+
+ if (trace_verbose) {
+ seq_printf(m, "%16s %5d %d %d %08x %08lx [%016Lx] %ld.%03ldms (+%ld.%03ldms): ",
+ pid_to_cmdline(entry->pid),
+ entry->pid, entry->cpu, entry->flags,
+ entry->preempt_count, trace_idx,
+ entry->timestamp, abs_usecs/1000,
+ abs_usecs % 1000, rel_usecs/1000, rel_usecs % 1000);
+ print_name_offset(m, entry->u.fn.eip);
+ seq_puts(m, " (");
+ print_name_offset(m, entry->u.fn.parent_eip);
+ seq_puts(m, ")\n");
+ } else {
+ print_generic(m, entry);
+ print_timestamp(m, abs_usecs, rel_usecs);
+ print_name(m, entry->u.fn.eip);
+ seq_puts(m, " (");
+ print_name(m, entry->u.fn.parent_eip);
+ seq_puts(m, ")\n");
+ }
+ return 0;
+}
+
+static int notrace l_show_special(struct seq_file *m, unsigned long trace_idx,
+ struct trace_entry *entry, struct trace_entry *entry0,
+ struct trace_entry *next_entry, int mode64)
+{
+ unsigned long abs_usecs, rel_usecs;
+
+ abs_usecs = cycles_to_us(entry->timestamp - entry0->timestamp);
+ rel_usecs = cycles_to_us(next_entry->timestamp - entry->timestamp);
+
+ print_generic(m, entry);
+ print_timestamp(m, abs_usecs, rel_usecs);
+ if (trace_verbose)
+ print_name_offset(m, entry->u.special.eip);
+ else
+ print_name(m, entry->u.special.eip);
+
+ if (!mode64) {
+ /*
+ * For convenience, print small numbers in decimal:
+ */
+ if (abs((int)entry->u.special.v1) < 10000)
+ seq_printf(m, " (%5ld ", entry->u.special.v1);
+ else
+ seq_printf(m, " (%lx ", entry->u.special.v1);
+ if (abs((int)entry->u.special.v2) < 10000)
+ seq_printf(m, "%5ld ", entry->u.special.v2);
+ else
+ seq_printf(m, "%lx ", entry->u.special.v2);
+ if (abs((int)entry->u.special.v3) < 10000)
+ seq_printf(m, "%5ld)\n", entry->u.special.v3);
+ else
+ seq_printf(m, "%lx)\n", entry->u.special.v3);
+ } else {
+ seq_printf(m, " (%13Ld %ld)\n",
+ ((u64)entry->u.special.v1 << 32)
+ + (u64)entry->u.special.v2, entry->u.special.v3);
+ }
+ return 0;
+}
+
+static int notrace
+l_show_special_pid(struct seq_file *m, unsigned long trace_idx,
+ struct trace_entry *entry, struct trace_entry *entry0,
+ struct trace_entry *next_entry)
+{
+ unsigned long abs_usecs, rel_usecs;
+ unsigned int pid;
+
+ pid = entry->u.special.v1;
+
+ abs_usecs = cycles_to_us(entry->timestamp - entry0->timestamp);
+ rel_usecs = cycles_to_us(next_entry->timestamp - entry->timestamp);
+
+ print_generic(m, entry);
+ print_timestamp(m, abs_usecs, rel_usecs);
+ if (trace_verbose)
+ print_name_offset(m, entry->u.special.eip);
+ else
+ print_name(m, entry->u.special.eip);
+ seq_printf(m, " <%.8s-%d> (%ld %ld)\n",
+ pid_to_cmdline(pid), pid,
+ entry->u.special.v2, entry->u.special.v3);
+
+ return 0;
+}
+
+static int notrace
+l_show_special_sym(struct seq_file *m, unsigned long trace_idx,
+ struct trace_entry *entry, struct trace_entry *entry0,
+ struct trace_entry *next_entry, int mode64)
+{
+ unsigned long abs_usecs, rel_usecs;
+
+ abs_usecs = cycles_to_us(entry->timestamp - entry0->timestamp);
+ rel_usecs = cycles_to_us(next_entry->timestamp - entry->timestamp);
+
+ print_generic(m, entry);
+ print_timestamp(m, abs_usecs, rel_usecs);
+ if (trace_verbose)
+ print_name_offset(m, entry->u.special.eip);
+ else
+ print_name(m, entry->u.special.eip);
+
+ seq_puts(m, "()<-");
+ print_name(m, entry->u.special.v1);
+ seq_puts(m, "()<-");
+ print_name(m, entry->u.special.v2);
+ seq_puts(m, "()<-");
+ print_name(m, entry->u.special.v3);
+ seq_puts(m, "()\n");
+
+ return 0;
+}
+
+
+static int notrace l_show_cmdline(struct seq_file *m, unsigned long trace_idx,
+ struct trace_entry *entry, struct trace_entry *entry0,
+ struct trace_entry *next_entry)
+{
+ unsigned long abs_usecs, rel_usecs;
+
+ if (!trace_verbose)
+ return 0;
+
+ abs_usecs = cycles_to_us(entry->timestamp - entry0->timestamp);
+ rel_usecs = cycles_to_us(next_entry->timestamp - entry->timestamp);
+
+ seq_printf(m,
+ "[ => %16s ] %ld.%03ldms (+%ld.%03ldms)\n",
+ entry->u.cmdline.str,
+ abs_usecs/1000, abs_usecs % 1000,
+ rel_usecs/1000, rel_usecs % 1000);
+
+ return 0;
+}
+
+extern unsigned long sys_call_table[NR_syscalls];
+
+#if defined(CONFIG_COMPAT) && defined(CONFIG_X86)
+extern unsigned long ia32_sys_call_table[], ia32_syscall_end[];
+#define IA32_NR_syscalls (ia32_syscall_end - ia32_sys_call_table)
+#endif
+
+static int notrace l_show_syscall(struct seq_file *m, unsigned long trace_idx,
+ struct trace_entry *entry, struct trace_entry *entry0,
+ struct trace_entry *next_entry)
+{
+ unsigned long abs_usecs, rel_usecs;
+ unsigned long nr;
+
+ abs_usecs = cycles_to_us(entry->timestamp - entry0->timestamp);
+ rel_usecs = cycles_to_us(next_entry->timestamp - entry->timestamp);
+
+ print_generic(m, entry);
+ print_timestamp_short(m, abs_usecs, rel_usecs);
+
+ seq_puts(m, "> ");
+ nr = entry->u.syscall.nr;
+#if defined(CONFIG_COMPAT) && defined(CONFIG_X86)
+ if (nr & 0x80000000) {
+ nr &= ~0x80000000;
+ if (nr < IA32_NR_syscalls)
+ print_name(m, ia32_sys_call_table[nr]);
+ else
+ seq_printf(m, "<badsys(%lu)>", nr);
+ } else
+#endif
+ if (nr < NR_syscalls)
+ print_name(m, sys_call_table[nr]);
+ else
+ seq_printf(m, "<badsys(%lu)>", nr);
+
+#ifdef CONFIG_64BIT
+ seq_printf(m, " (%016lx %016lx %016lx)\n",
+ entry->u.syscall.p1, entry->u.syscall.p2, entry->u.syscall.p3);
+#else
+ seq_printf(m, " (%08lx %08lx %08lx)\n",
+ entry->u.syscall.p1, entry->u.syscall.p2, entry->u.syscall.p3);
+#endif
+
+ return 0;
+}
+
+static int notrace l_show_sysret(struct seq_file *m, unsigned long trace_idx,
+ struct trace_entry *entry, struct trace_entry *entry0,
+ struct trace_entry *next_entry)
+{
+ unsigned long abs_usecs, rel_usecs;
+
+ abs_usecs = cycles_to_us(entry->timestamp - entry0->timestamp);
+ rel_usecs = cycles_to_us(next_entry->timestamp - entry->timestamp);
+
+ print_generic(m, entry);
+ print_timestamp_short(m, abs_usecs, rel_usecs);
+
+ seq_printf(m, "< (%ld)\n", entry->u.sysret.ret);
+
+ return 0;
+}
+
+
+static int notrace l_show(struct seq_file *m, void *p)
+{
+ struct cpu_trace *tr = out_tr.traces;
+ struct trace_entry *entry, *entry0, *next_entry;
+ unsigned long trace_idx;
+
+ cond_resched();
+ entry = p;
+ if (entry->timestamp < out_tr.first_timestamp)
+ return 0;
+ if (entry->timestamp > out_tr.last_timestamp)
+ return 0;
+
+ entry0 = tr->trace;
+ trace_idx = entry - entry0;
+
+ if (trace_idx + 1 < tr->trace_idx)
+ next_entry = entry + 1;
+ else
+ next_entry = entry;
+
+ if (trace_verbose)
+ seq_printf(m, "(T%d/#%ld) ", entry->type, trace_idx);
+
+ switch (entry->type) {
+ case TRACE_FN:
+ l_show_fn(m, trace_idx, entry, entry0, next_entry);
+ break;
+ case TRACE_SPECIAL:
+ l_show_special(m, trace_idx, entry, entry0, next_entry, 0);
+ break;
+ case TRACE_SPECIAL_PID:
+ l_show_special_pid(m, trace_idx, entry, entry0, next_entry);
+ break;
+ case TRACE_SPECIAL_U64:
+ l_show_special(m, trace_idx, entry, entry0, next_entry, 1);
+ break;
+ case TRACE_SPECIAL_SYM:
+ l_show_special_sym(m, trace_idx, entry, entry0,
+ next_entry, 1);
+ break;
+ case TRACE_CMDLINE:
+ l_show_cmdline(m, trace_idx, entry, entry0, next_entry);
+ break;
+ case TRACE_SYSCALL:
+ l_show_syscall(m, trace_idx, entry, entry0, next_entry);
+ break;
+ case TRACE_SYSRET:
+ l_show_sysret(m, trace_idx, entry, entry0, next_entry);
+ break;
+ default:
+ seq_printf(m, "unknown trace type %d\n", entry->type);
+ }
+ return 0;
+}
+
+struct seq_operations latency_trace_op = {
+ .start = l_start,
+ .next = l_next,
+ .stop = l_stop,
+ .show = l_show
+};
+
+/*
+ * Copy the new maximum trace into the separate maximum-trace
+ * structure. (this way the maximum trace is permanently saved,
+ * for later retrieval via /proc/latency_trace)
+ */
+static void update_max_tr(struct cpu_trace *tr)
+{
+ struct cpu_trace *save;
+ int cpu, all_cpus = 0;
+
+#ifdef CONFIG_PREEMPT
+ WARN_ON(!preempt_count() && !irqs_disabled());
+#endif
+
+ max_tr.cpu = tr->cpu;
+ save = max_tr.traces + tr->cpu;
+
+ if ((wakeup_timing || trace_user_triggered || trace_print_on_crash ||
+ print_functions) && trace_all_cpus) {
+ all_cpus = 1;
+ for_each_online_cpu(cpu)
+ atomic_inc(&cpu_traces[cpu].disabled);
+ }
+
+ save->saved_latency = preempt_max_latency;
+ save->preempt_timestamp = tr->preempt_timestamp;
+ save->critical_start = tr->critical_start;
+ save->critical_end = tr->critical_end;
+ save->critical_sequence = tr->critical_sequence;
+
+ memcpy(save->comm, current->comm, CMDLINE_BYTES);
+ save->pid = current->pid;
+ save->uid = current->uid;
+ save->nice = current->static_prio - 20 - MAX_RT_PRIO;
+ save->policy = current->policy;
+ save->rt_priority = current->rt_priority;
+
+ if (all_cpus) {
+ for_each_online_cpu(cpu) {
+ copy_trace(max_tr.traces + cpu, cpu_traces + cpu, 1);
+ atomic_dec(&cpu_traces[cpu].disabled);
+ }
+ } else
+ copy_trace(save, tr, 1);
+}
+
+#else /* !EVENT_TRACE */
+
+static inline void notrace
+____trace(int cpu, enum trace_type type, struct cpu_trace *tr,
+ unsigned long eip, unsigned long parent_eip,
+ unsigned long v1, unsigned long v2, unsigned long v3,
+ unsigned long flags)
+{
+}
+
+static inline void notrace
+___trace(enum trace_type type, unsigned long eip, unsigned long parent_eip,
+ unsigned long v1, unsigned long v2,
+ unsigned long v3)
+{
+}
+
+static inline void notrace __trace(unsigned long eip, unsigned long parent_eip)
+{
+}
+
+static inline void update_max_tr(struct cpu_trace *tr)
+{
+}
+
+static inline void notrace _trace_cmdline(int cpu, struct cpu_trace *tr)
+{
+}
+
+#endif
+
+static int setup_preempt_thresh(char *s)
+{
+ int thresh;
+
+ get_option(&s, &thresh);
+ if (thresh > 0) {
+ preempt_thresh = usecs_to_cycles(thresh);
+ printk("Preemption threshold = %u us\n", thresh);
+ }
+ return 1;
+}
+__setup("preempt_thresh=", setup_preempt_thresh);
+
+static inline void notrace reset_trace_idx(int cpu, struct cpu_trace *tr)
+{
+ if (trace_all_cpus)
+ for_each_online_cpu(cpu) {
+ tr = cpu_traces + cpu;
+ tr->trace_idx = 0;
+ atomic_set(&tr->underrun, 0);
+ atomic_set(&tr->overrun, 0);
+ }
+ else{
+ tr->trace_idx = 0;
+ atomic_set(&tr->underrun, 0);
+ atomic_set(&tr->overrun, 0);
+ }
+}
+
+#ifdef CONFIG_CRITICAL_TIMING
+
+static void notrace
+check_critical_timing(int cpu, struct cpu_trace *tr, unsigned long parent_eip)
+{
+ unsigned long latency, t0, t1;
+ cycle_t T0, T1, T2, delta;
+ unsigned long flags;
+
+ if (trace_user_triggered)
+ return;
+ /*
+ * usecs conversion is slow so we try to delay the conversion
+ * as long as possible:
+ */
+ T0 = tr->preempt_timestamp;
+ T1 = get_monotonic_cycles();
+ delta = T1-T0;
+
+ local_save_flags(flags);
+
+ if (!report_latency(delta))
+ goto out;
+
+ ____trace(cpu, TRACE_FN, tr, CALLER_ADDR0, parent_eip, 0, 0, 0, flags);
+ /*
+ * Update the timestamp, because the trace entry above
+ * might change it (it can only get larger so the latency
+ * is fair to be reported):
+ */
+ T2 = get_monotonic_cycles();
+
+ delta = T2-T0;
+
+ latency = cycles_to_usecs(delta);
+ latency_hist(tr->latency_type, cpu, latency);
+
+ if (latency_hist_flag) {
+ if (preempt_max_latency >= delta)
+ goto out;
+ }
+
+ if (tr->critical_sequence != max_sequence || down_trylock(&max_mutex))
+ goto out;
+
+#ifndef CONFIG_CRITICAL_LATENCY_HIST
+ if (!preempt_thresh && preempt_max_latency > delta) {
+ printk("bug: updating %016Lx > %016Lx?\n",
+ preempt_max_latency, delta);
+ printk(" [%016Lx %016Lx %016Lx]\n", T0, T1, T2);
+ }
+#endif
+
+ preempt_max_latency = delta;
+ t0 = cycles_to_usecs(T0);
+ t1 = cycles_to_usecs(T1);
+
+ tr->critical_end = parent_eip;
+
+ update_max_tr(tr);
+
+#ifndef CONFIG_CRITICAL_LATENCY_HIST
+ if (preempt_thresh)
+ printk("(%16s-%-5d|#%d): %lu us critical section "
+ "violates %lu us threshold.\n"
+ " => started at timestamp %lu: ",
+ current->comm, current->pid,
+ raw_smp_processor_id(),
+ latency, cycles_to_usecs(preempt_thresh), t0);
+ else
+ printk("(%16s-%-5d|#%d): new %lu us maximum-latency "
+ "critical section.\n => started at timestamp %lu: ",
+ current->comm, current->pid,
+ raw_smp_processor_id(),
+ latency, t0);
+
+ print_symbol("<%s>\n", tr->critical_start);
+ printk(" => ended at timestamp %lu: ", t1);
+ print_symbol("<%s>\n", tr->critical_end);
+ dump_stack();
+ t1 = cycles_to_usecs(get_monotonic_cycles());
+ printk(" => dump-end timestamp %lu\n\n", t1);
+#endif
+
+ max_sequence++;
+
+ up(&max_mutex);
+
+out:
+ tr->critical_sequence = max_sequence;
+ tr->preempt_timestamp = get_monotonic_cycles();
+ tr->early_warning = 0;
+ reset_trace_idx(cpu, tr);
+ _trace_cmdline(cpu, tr);
+ ____trace(cpu, TRACE_FN, tr, CALLER_ADDR0, parent_eip, 0, 0, 0, flags);
+}
+
+void notrace touch_critical_timing(void)
+{
+ int cpu = raw_smp_processor_id();
+ struct cpu_trace *tr = cpu_traces + cpu;
+
+ if (!tr->critical_start || atomic_read(&tr->disabled) ||
+ trace_user_triggered || wakeup_timing)
+ return;
+
+ if (preempt_count() > 0 && tr->critical_start) {
+ atomic_inc(&tr->disabled);
+ check_critical_timing(cpu, tr, CALLER_ADDR0);
+ tr->critical_start = CALLER_ADDR0;
+ tr->critical_sequence = max_sequence;
+ atomic_dec(&tr->disabled);
+ }
+}
+EXPORT_SYMBOL(touch_critical_timing);
+
+void notrace stop_critical_timing(void)
+{
+ struct cpu_trace *tr = cpu_traces + raw_smp_processor_id();
+
+ tr->critical_start = 0;
+}
+EXPORT_SYMBOL(stop_critical_timing);
+
+static inline void notrace
+__start_critical_timing(unsigned long eip, unsigned long parent_eip,
+ int latency_type)
+{
+ int cpu = raw_smp_processor_id();
+ struct cpu_trace *tr = cpu_traces + cpu;
+ unsigned long flags;
+
+ if (tr->critical_start || atomic_read(&tr->disabled) ||
+ trace_user_triggered || wakeup_timing)
+ return;
+
+ atomic_inc(&tr->disabled);
+
+ tr->critical_sequence = max_sequence;
+ tr->preempt_timestamp = get_monotonic_cycles();
+ tr->critical_start = eip;
+ reset_trace_idx(cpu, tr);
+ tr->latency_type = latency_type;
+ _trace_cmdline(cpu, tr);
+
+ local_save_flags(flags);
+ ____trace(cpu, TRACE_FN, tr, eip, parent_eip, 0, 0, 0, flags);
+
+ atomic_dec(&tr->disabled);
+}
+
+static inline void notrace
+__stop_critical_timing(unsigned long eip, unsigned long parent_eip)
+{
+ int cpu = raw_smp_processor_id();
+ struct cpu_trace *tr = cpu_traces + cpu;
+ unsigned long flags;
+
+ if (!tr->critical_start || atomic_read(&tr->disabled) ||
+ trace_user_triggered || wakeup_timing)
+ return;
+
+ atomic_inc(&tr->disabled);
+ local_save_flags(flags);
+ ____trace(cpu, TRACE_FN, tr, eip, parent_eip, 0, 0, 0, flags);
+ check_critical_timing(cpu, tr, eip);
+ tr->critical_start = 0;
+ atomic_dec(&tr->disabled);
+}
+
+#endif
+
+#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING
+
+#ifdef CONFIG_LOCKDEP
+
+void notrace time_hardirqs_on(unsigned long a0, unsigned long a1)
+{
+ unsigned long flags;
+
+ local_save_flags(flags);
+
+ if (!irqs_off_preempt_count() && irqs_disabled_flags(flags))
+ __stop_critical_timing(a0, a1);
+}
+
+void notrace time_hardirqs_off(unsigned long a0, unsigned long a1)
+{
+ unsigned long flags;
+
+ local_save_flags(flags);
+
+ if (!irqs_off_preempt_count() && irqs_disabled_flags(flags))
+ __start_critical_timing(a0, a1, INTERRUPT_LATENCY);
+}
+
+#else /* !CONFIG_LOCKDEP */
+
+/*
+ * Dummy:
+ */
+
+void early_boot_irqs_off(void)
+{
+}
+
+void early_boot_irqs_on(void)
+{
+}
+
+void trace_softirqs_on(unsigned long ip)
+{
+}
+
+void trace_softirqs_off(unsigned long ip)
+{
+}
+
+inline void print_irqtrace_events(struct task_struct *curr)
+{
+}
+
+/*
+ * We are only interested in hardirq on/off events:
+ */
+void notrace trace_hardirqs_on(void)
+{
+ unsigned long flags;
+
+ local_save_flags(flags);
+
+ if (!irqs_off_preempt_count() && irqs_disabled_flags(flags))
+ __stop_critical_timing(CALLER_ADDR0, 0 /* CALLER_ADDR1 */);
+}
+
+EXPORT_SYMBOL(trace_hardirqs_on);
+
+void notrace trace_hardirqs_off(void)
+{
+ unsigned long flags;
+
+ local_save_flags(flags);
+
+ if (!irqs_off_preempt_count() && irqs_disabled_flags(flags))
+ __start_critical_timing(CALLER_ADDR0, 0 /* CALLER_ADDR1 */,
+ INTERRUPT_LATENCY);
+}
+
+EXPORT_SYMBOL(trace_hardirqs_off);
+
+#endif /* !CONFIG_LOCKDEP */
+
+#endif /* CONFIG_CRITICAL_IRQSOFF_TIMING */
+
+#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_CRITICAL_TIMING)
+
+static inline unsigned long get_parent_eip(void)
+{
+ unsigned long parent_eip = CALLER_ADDR1;
+
+ if (in_lock_functions(parent_eip)) {
+ parent_eip = CALLER_ADDR2;
+ if (in_lock_functions(parent_eip))
+ parent_eip = CALLER_ADDR3;
+ }
+
+ return parent_eip;
+}
+
+void notrace add_preempt_count(unsigned int val)
+{
+ unsigned long eip = CALLER_ADDR0;
+ unsigned long parent_eip = get_parent_eip();
+
+#ifdef CONFIG_DEBUG_PREEMPT
+ /*
+ * Underflow?
+ */
+ if (DEBUG_WARN_ON(((int)preempt_count() < 0)))
+ return;
+ /*
+ * Spinlock count overflowing soon?
+ */
+ if (DEBUG_WARN_ON((preempt_count() & PREEMPT_MASK) >= PREEMPT_MASK-10))
+ return;
+#endif
+
+ preempt_count() += val;
+#ifdef CONFIG_PREEMPT_TRACE
+ if (val <= 10) {
+ unsigned int idx = preempt_count() & PREEMPT_MASK;
+ if (idx < MAX_PREEMPT_TRACE) {
+ current->preempt_trace_eip[idx] = eip;
+ current->preempt_trace_parent_eip[idx] = parent_eip;
+ }
+ }
+#endif
+#ifdef CONFIG_CRITICAL_PREEMPT_TIMING
+ {
+#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING
+ unsigned long flags;
+
+ local_save_flags(flags);
+
+ if (!irqs_disabled_flags(flags))
+#endif
+ if (preempt_count() == val)
+ __start_critical_timing(eip, parent_eip,
+ PREEMPT_LATENCY);
+ }
+#endif
+ (void)eip, (void)parent_eip;
+}
+EXPORT_SYMBOL(add_preempt_count);
+
+void notrace sub_preempt_count(unsigned int val)
+{
+#ifdef CONFIG_DEBUG_PREEMPT
+ /*
+ * Underflow?
+ */
+ if (DEBUG_WARN_ON(unlikely(val > preempt_count())))
+ return;
+ /*
+ * Is the spinlock portion underflowing?
+ */
+ if (DEBUG_WARN_ON((val < PREEMPT_MASK) &&
+ !(preempt_count() & PREEMPT_MASK)))
+ return;
+#endif
+
+#ifdef CONFIG_CRITICAL_PREEMPT_TIMING
+ {
+#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING
+ unsigned long flags;
+
+ local_save_flags(flags);
+
+ if (!irqs_disabled_flags(flags))
+#endif
+ if (preempt_count() == val)
+ __stop_critical_timing(CALLER_ADDR0,
+ CALLER_ADDR1);
+ }
+#endif
+ preempt_count() -= val;
+}
+
+EXPORT_SYMBOL(sub_preempt_count);
+
+void notrace mask_preempt_count(unsigned int mask)
+{
+ unsigned long eip = CALLER_ADDR0;
+ unsigned long parent_eip = get_parent_eip();
+
+ preempt_count() |= mask;
+
+#ifdef CONFIG_CRITICAL_PREEMPT_TIMING
+ {
+#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING
+ unsigned long flags;
+
+ local_save_flags(flags);
+
+ if (!irqs_disabled_flags(flags))
+#endif
+ if (preempt_count() == mask)
+ __start_critical_timing(eip, parent_eip,
+ PREEMPT_LATENCY);
+ }
+#endif
+ (void) eip, (void) parent_eip;
+}
+EXPORT_SYMBOL(mask_preempt_count);
+
+void notrace unmask_preempt_count(unsigned int mask)
+{
+#ifdef CONFIG_CRITICAL_PREEMPT_TIMING
+ {
+#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING
+ unsigned long flags;
+
+ local_save_flags(flags);
+
+ if (!irqs_disabled_flags(flags))
+#endif
+ if (preempt_count() == mask)
+ __stop_critical_timing(CALLER_ADDR0,
+ CALLER_ADDR1);
+ }
+#endif
+ preempt_count() &= ~mask;
+}
+EXPORT_SYMBOL(unmask_preempt_count);
+
+
+#endif
+
+/*
+ * Wakeup latency timing/tracing. We get upcalls from the scheduler
+ * when a task is being woken up and we time/trace it until it gets
+ * to a CPU - or an even-higher-prio task supercedes it. (in that
+ * case we throw away the currently traced task - we dont try to
+ * handle nesting, that simplifies things significantly)
+ */
+#ifdef CONFIG_WAKEUP_TIMING
+
+static void notrace
+check_wakeup_timing(struct cpu_trace *tr, unsigned long parent_eip,
+ unsigned long *flags)
+{
+ int cpu = raw_smp_processor_id();
+ unsigned long latency, t0, t1;
+ cycle_t T0, T1, delta;
+
+ if (trace_user_triggered)
+ return;
+
+ atomic_inc(&tr->disabled);
+ if (atomic_read(&tr->disabled) != 1)
+ goto out;
+
+ T0 = tr->preempt_timestamp;
+ T1 = get_monotonic_cycles();
+ /*
+ * Any wraparound or time warp and we are out:
+ */
+ if (T0 > T1)
+ goto out;
+ delta = T1-T0;
+
+ if (!report_latency(delta))
+ goto out;
+
+ ____trace(smp_processor_id(), TRACE_FN, tr, CALLER_ADDR0, parent_eip,
+ 0, 0, 0, *flags);
+
+ latency = cycles_to_usecs(delta);
+ latency_hist(tr->latency_type, cpu, latency);
+
+ if (latency_hist_flag) {
+ if (preempt_max_latency >= delta)
+ goto out;
+ }
+
+ if (tr->critical_sequence != max_sequence || down_trylock(&max_mutex))
+ goto out;
+
+#ifndef CONFIG_WAKEUP_LATENCY_HIST
+ if (!preempt_thresh && preempt_max_latency > delta) {
+ printk("bug2: updating %016lx > %016Lx?\n",
+ preempt_max_latency, delta);
+ printk(" [%016Lx %016Lx]\n", T0, T1);
+ }
+#endif
+
+ preempt_max_latency = delta;
+ t0 = cycles_to_usecs(T0);
+ t1 = cycles_to_usecs(T1);
+ tr->critical_end = parent_eip;
+
+ update_max_tr(tr);
+
+ atomic_dec(&tr->disabled);
+ __raw_spin_unlock(&sch.trace_lock);
+ local_irq_restore(*flags);
+
+#ifndef CONFIG_WAKEUP_LATENCY_HIST
+ if (preempt_thresh)
+ printk("(%16s-%-5d|#%d): %lu us wakeup latency "
+ "violates %lu us threshold.\n",
+ current->comm, current->pid,
+ raw_smp_processor_id(), latency,
+ cycles_to_usecs(preempt_thresh));
+ else
+ printk("(%16s-%-5d|#%d): new %lu us maximum-latency "
+ "wakeup.\n", current->comm, current->pid,
+ raw_smp_processor_id(), latency);
+#endif
+
+ max_sequence++;
+
+ up(&max_mutex);
+
+ return;
+
+out:
+ atomic_dec(&tr->disabled);
+ __raw_spin_unlock(&sch.trace_lock);
+ local_irq_restore(*flags);
+}
+
+/*
+ * Start wakeup latency tracing - called with the runqueue held
+ * and interrupts disabled:
+ */
+void __trace_start_sched_wakeup(struct task_struct *p)
+{
+ struct cpu_trace *tr;
+ int cpu;
+
+ if (trace_user_triggered || !wakeup_timing) {
+ trace_special_pid(p->pid, p->prio, -1);
+ return;
+ }
+
+ __raw_spin_lock(&sch.trace_lock);
+ if (sch.task && (sch.task->prio <= p->prio))
+ goto out_unlock;
+
+ /*
+ * New highest-prio task just woke up - start tracing:
+ */
+ sch.task = p;
+ cpu = task_cpu(p);
+ sch.cpu = cpu;
+ /*
+ * We keep using this CPU's trace buffer even if the task
+ * gets migrated to another CPU. Tracing only happens on
+ * the CPU that 'owns' the highest-prio task so it's
+ * fundamentally single-threaded.
+ */
+ sch.tr = tr = cpu_traces + cpu;
+ reset_trace_idx(cpu, tr);
+
+// if (!atomic_read(&tr->disabled)) {
+ atomic_inc(&tr->disabled);
+ tr->critical_sequence = max_sequence;
+ tr->preempt_timestamp = get_monotonic_cycles();
+ tr->latency_type = WAKEUP_LATENCY;
+ tr->critical_start = CALLER_ADDR0;
+ _trace_cmdline(raw_smp_processor_id(), tr);
+ atomic_dec(&tr->disabled);
+// }
+
+ mcount();
+ trace_special_pid(p->pid, p->prio, cpu);
+ trace_special_sym();
+out_unlock:
+ __raw_spin_unlock(&sch.trace_lock);
+}
+
+void trace_stop_sched_switched(struct task_struct *p)
+{
+ struct cpu_trace *tr;
+ unsigned long flags;
+
+ if (trace_user_triggered || !wakeup_timing)
+ return;
+
+ local_irq_save(flags);
+ __raw_spin_lock(&sch.trace_lock);
+ if (p == sch.task) {
+ trace_special_pid(p->pid, p->prio, task_cpu(p));
+
+ sch.task = NULL;
+ tr = sch.tr;
+ sch.tr = NULL;
+ WARN_ON(!tr);
+ /* auto-unlocks the spinlock: */
+ check_wakeup_timing(tr, CALLER_ADDR0, &flags);
+ } else {
+ if (sch.task)
+ trace_special_pid(sch.task->pid, sch.task->prio,
+ p->prio);
+ if (sch.task && (sch.task->prio >= p->prio))
+ sch.task = NULL;
+ __raw_spin_unlock(&sch.trace_lock);
+ }
+ local_irq_restore(flags);
+}
+
+void trace_change_sched_cpu(struct task_struct *p, int new_cpu)
+{
+ unsigned long flags;
+
+ if (!wakeup_timing)
+ return;
+
+ trace_special_pid(p->pid, task_cpu(p), new_cpu);
+ trace_special_sym();
+ local_irq_save(flags);
+ __raw_spin_lock(&sch.trace_lock);
+ if (p == sch.task && task_cpu(p) != new_cpu) {
+ sch.cpu = new_cpu;
+ trace_special(task_cpu(p), new_cpu, 0);
+ }
+ __raw_spin_unlock(&sch.trace_lock);
+ local_irq_restore(flags);
+}
+
+#endif
+
+#ifdef CONFIG_EVENT_TRACE
+
+long user_trace_start(void)
+{
+ struct cpu_trace *tr;
+ unsigned long flags;
+ int cpu;
+
+ if (!trace_user_triggered || trace_print_on_crash || print_functions)
+ return -EINVAL;
+
+ /*
+ * If the user has not yet reset the max latency after
+ * bootup then we assume that this was the intention
+ * (we wont get any tracing done otherwise):
+ */
+ if (preempt_max_latency == (cycle_t)ULONG_MAX)
+ preempt_max_latency = 0;
+
+ /*
+ * user_trace_start() might be called from hardirq
+ * context, if trace_user_triggered_irq is set, so
+ * be careful about locking:
+ */
+ if (preempt_count() || irqs_disabled()) {
+ if (down_trylock(&max_mutex))
+ return -EAGAIN;
+ } else
+ down(&max_mutex);
+
+ local_irq_save(flags);
+ cpu = smp_processor_id();
+ tr = cpu_traces + cpu;
+
+#ifdef CONFIG_WAKEUP_TIMING
+ if (wakeup_timing) {
+ __raw_spin_lock(&sch.trace_lock);
+ sch.task = current;
+ sch.cpu = cpu;
+ sch.tr = tr;
+ __raw_spin_unlock(&sch.trace_lock);
+ }
+#endif
+ reset_trace_idx(cpu, tr);
+
+ tr->critical_sequence = max_sequence;
+ tr->preempt_timestamp = get_monotonic_cycles();
+ tr->critical_start = CALLER_ADDR0;
+ _trace_cmdline(cpu, tr);
+ mcount();
+
+ WARN_ON(!irqs_disabled());
+ local_irq_restore(flags);
+
+ up(&max_mutex);
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(user_trace_start);
+
+long user_trace_stop(void)
+{
+ unsigned long latency = 0, flags;
+ struct cpu_trace *tr;
+ cycle_t delta;
+
+ if (!trace_user_triggered || trace_print_on_crash || print_functions)
+ return -EINVAL;
+
+ local_irq_save(flags);
+ mcount();
+
+#ifdef CONFIG_WAKEUP_TIMING
+ if (wakeup_timing) {
+ struct task_struct *t;
+
+ __raw_spin_lock(&sch.trace_lock);
+#if 0
+ t = sch.task;
+ if (current != t) {
+ __raw_spin_unlock(&sch.trace_lock);
+ local_irq_restore(flags);
+ printk("wrong stop: curr: %s/%d[%d] => %p\n",
+ current->comm, current->pid,
+ task_thread_info(current)->cpu, t);
+ if (t)
+ printk("wrong stop: curr: %s/%d[%d]\n",
+ t->comm, t->pid, task_thread_info(t)->cpu);
+ return -EINVAL;
+ }
+#endif
+ sch.task = NULL;
+ tr = sch.tr;
+ sch.tr = NULL;
+ __raw_spin_unlock(&sch.trace_lock);
+ } else
+#endif
+ tr = cpu_traces + smp_processor_id();
+
+ atomic_inc(&tr->disabled);
+ if (tr->preempt_timestamp) {
+ cycle_t T0, T1;
+ unsigned long long tmp0;
+
+ T0 = tr->preempt_timestamp;
+ T1 = get_monotonic_cycles();
+ tmp0 = preempt_max_latency;
+ if (T1 < T0)
+ T0 = T1;
+ delta = T1 - T0;
+ if (!report_latency(delta))
+ goto out;
+ if (tr->critical_sequence != max_sequence ||
+ down_trylock(&max_mutex))
+ goto out;
+
+ WARN_ON(!preempt_thresh && preempt_max_latency > delta);
+
+ preempt_max_latency = delta;
+ update_max_tr(tr);
+
+ latency = cycles_to_usecs(delta);
+
+ max_sequence++;
+ up(&max_mutex);
+out:
+ tr->preempt_timestamp = 0;
+ }
+ atomic_dec(&tr->disabled);
+ local_irq_restore(flags);
+
+ if (latency) {
+ if (preempt_thresh)
+ printk("(%16s-%-5d|#%d): %lu us user-latency "
+ "violates %lu us threshold.\n",
+ current->comm, current->pid,
+ raw_smp_processor_id(), latency,
+ cycles_to_usecs(preempt_thresh));
+ else
+ printk("(%16s-%-5d|#%d): new %lu us user-latency.\n",
+ current->comm, current->pid,
+ raw_smp_processor_id(), latency);
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(user_trace_stop);
+
+static int trace_print_cpu = -1;
+
+void notrace stop_trace(void)
+{
+ if (trace_print_on_crash && trace_print_cpu == -1) {
+ trace_enabled = -1;
+ trace_print_cpu = raw_smp_processor_id();
+ }
+}
+
+EXPORT_SYMBOL(stop_trace);
+
+static void print_entry(struct trace_entry *entry, struct trace_entry *entry0)
+{
+ unsigned long abs_usecs;
+ int hardirq, softirq;
+
+ abs_usecs = cycles_to_us(entry->timestamp - entry0->timestamp);
+
+ printk("%-5d ", entry->pid);
+
+ printk("%d%c%c",
+ entry->cpu,
+ (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
+ (entry->flags & TRACE_FLAG_IRQS_HARD_OFF) ? 'D' : '.',
+ (entry->flags & TRACE_FLAG_NEED_RESCHED_DELAYED) ? 'n' :
+ ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
+
+ hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
+ softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
+ if (hardirq && softirq)
+ printk("H");
+ else {
+ if (hardirq)
+ printk("h");
+ else {
+ if (softirq)
+ printk("s");
+ else
+ printk(".");
+ }
+ }
+
+ if (entry->preempt_count)
+ printk(":%x ", entry->preempt_count);
+ else
+ printk(":. ");
+
+ printk("%ld.%03ldms: ", abs_usecs/1000, abs_usecs % 1000);
+
+ switch (entry->type) {
+ case TRACE_FN:
+ printk_name(entry->u.fn.eip);
+ printk(" <= (");
+ printk_name(entry->u.fn.parent_eip);
+ printk(")\n");
+ break;
+ case TRACE_SPECIAL:
+ printk(" special: %lx %lx %lx\n",
+ entry->u.special.v1, entry->u.special.v2,
+ entry->u.special.v3);
+ break;
+ case TRACE_SPECIAL_U64:
+ printk(" spec64: %lx%08lx %lx\n",
+ entry->u.special.v1, entry->u.special.v2,
+ entry->u.special.v3);
+ break;
+ }
+}
+
+/*
+ * Print the current trace at crash time.
+ *
+ * We print it backwards, so that the newest (most interesting) entries
+ * are printed first.
+ */
+void print_last_trace(void)
+{
+ unsigned int idx0, idx, i, cpu;
+ struct cpu_trace *tr;
+ struct trace_entry *entry0, *entry;
+
+ preempt_disable();
+ cpu = smp_processor_id();
+ if (trace_enabled != -1 || trace_print_cpu != cpu ||
+ !trace_print_on_crash) {
+ if (trace_print_on_crash)
+ printk("skipping trace printing on CPU#%d != %d\n",
+ cpu, trace_print_cpu);
+ preempt_enable();
+ return;
+ }
+
+ trace_print_on_crash = 0;
+
+ tr = cpu_traces + cpu;
+ if (!tr->trace)
+ goto out;
+
+ printk("Last %ld trace entries:\n", MAX_TRACE);
+ idx0 = tr->trace_idx;
+ printk("curr idx: %d\n", idx0);
+ if (idx0 >= MAX_TRACE)
+ idx0 = 0;
+ idx = idx0;
+ entry0 = tr->trace + idx0;
+
+ for (i = 0; i < MAX_TRACE; i++) {
+ if (idx == 0)
+ idx = MAX_TRACE-1;
+ else
+ idx--;
+ entry = tr->trace + idx;
+ switch (entry->type) {
+ case TRACE_FN:
+ case TRACE_SPECIAL:
+ case TRACE_SPECIAL_U64:
+ print_entry(entry, entry0);
+ break;
+ }
+ }
+ printk("printed %ld entries\n", MAX_TRACE);
+out:
+ preempt_enable();
+}
+
+#ifdef CONFIG_SMP
+/*
+ * On SMP, try to 'peek' on other CPU's traces and record them
+ * in this CPU's trace. This way we get a rough idea about what's
+ * going on there, without the overhead of global tracing.
+ *
+ * (no need to make this PER_CPU, we bounce it around anyway.)
+ */
+unsigned long nmi_eips[NR_CPUS];
+unsigned long nmi_flags[NR_CPUS];
+
+void notrace nmi_trace(unsigned long eip, unsigned long parent_eip,
+ unsigned long flags)
+{
+ int cpu, this_cpu = smp_processor_id();
+
+ __trace(eip, parent_eip);
+
+ nmi_eips[this_cpu] = parent_eip;
+ nmi_flags[this_cpu] = flags;
+ for (cpu = 0; cpu < NR_CPUS; cpu++)
+ if (cpu_online(cpu) && cpu != this_cpu) {
+ __trace(eip, nmi_eips[cpu]);
+ __trace(eip, nmi_flags[cpu]);
+ }
+}
+#else
+/*
+ * On UP, NMI tracing is quite simple:
+ */
+void notrace nmi_trace(unsigned long eip, unsigned long parent_eip,
+ unsigned long flags)
+{
+ __trace(eip, parent_eip);
+}
+#endif
+
+#endif
+
+#ifdef CONFIG_PREEMPT_TRACE
+
+static void print_preempt_trace(struct task_struct *task)
+{
+ unsigned int count = task_thread_info(task)->preempt_count;
+ unsigned int i, lim = count & PREEMPT_MASK;
+ if (lim >= MAX_PREEMPT_TRACE)
+ lim = MAX_PREEMPT_TRACE-1;
+ printk("---------------------------\n");
+ printk("| preempt count: %08x ]\n", count);
+ printk("| %d-level deep critical section nesting:\n", lim);
+ printk("----------------------------------------\n");
+ for (i = 1; i <= lim; i++) {
+ printk(".. [<%08lx>] .... ", task->preempt_trace_eip[i]);
+ print_symbol("%s\n", task->preempt_trace_eip[i]);
+ printk(".....[<%08lx>] .. ( <= ",
+ task->preempt_trace_parent_eip[i]);
+ print_symbol("%s)\n", task->preempt_trace_parent_eip[i]);
+ }
+ printk("\n");
+}
+
+#endif
+
+#if defined(CONFIG_PREEMPT_TRACE) || defined(CONFIG_EVENT_TRACE)
+void print_traces(struct task_struct *task)
+{
+ if (!task)
+ task = current;
+
+#ifdef CONFIG_PREEMPT_TRACE
+ print_preempt_trace(task);
+#endif
+#ifdef CONFIG_EVENT_TRACE
+ print_last_trace();
+#endif
+}
+#endif
+
+#ifdef CONFIG_EVENT_TRACE
+/*
+ * Allocate all the per-CPU trace buffers and the
+ * save-maximum/save-output staging buffers:
+ */
+void __init init_tracer(void)
+{
+ unsigned long size, total_size = 0;
+ struct trace_entry *array;
+ struct cpu_trace *tr;
+ int cpu;
+
+ printk("num_possible_cpus(): %d\n", num_possible_cpus());
+
+ size = sizeof(struct trace_entry)*MAX_TRACE;
+
+ for_each_possible_cpu(cpu) {
+ tr = cpu_traces + cpu;
+ array = alloc_bootmem(size);
+ if (!array) {
+ printk(KERN_ERR
+ "CPU#%d: failed to allocate %ld bytes trace buffer!\n",
+ cpu, size);
+ } else {
+ printk(KERN_INFO
+ "CPU#%d: allocated %ld bytes trace buffer.\n",
+ cpu, size);
+ total_size += size;
+ }
+ tr->cpu = cpu;
+ tr->trace = array;
+
+ array = alloc_bootmem(size);
+ if (!array) {
+ printk(KERN_ERR
+ "CPU#%d: failed to allocate %ld bytes max-trace buffer!\n",
+ cpu, size);
+ } else {
+ printk(KERN_INFO
+ "CPU#%d: allocated %ld bytes max-trace buffer.\n",
+ cpu, size);
+ total_size += size;
+ }
+ max_tr.traces[cpu].trace = array;
+ }
+
+ /*
+ * The output trace buffer is a special one that only has
+ * trace entries for the first cpu-trace structure:
+ */
+ size = sizeof(struct trace_entry)*MAX_TRACE*num_possible_cpus();
+ array = alloc_bootmem(size);
+ if (!array) {
+ printk(KERN_ERR
+ "failed to allocate %ld bytes out-trace buffer!\n",
+ size);
+ } else {
+ printk(KERN_INFO "allocated %ld bytes out-trace buffer.\n",
+ size);
+ total_size += size;
+ }
+ out_tr.traces[0].trace = array;
+ printk(KERN_INFO
+ "tracer: a total of %ld bytes allocated.\n",
+ total_size);
+}
+#endif
Index: linux-2.6.22-rc2/kernel/lockdep.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/lockdep.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/lockdep.c 2007-05-24 15:57:42.000000000 +0200
@@ -166,14 +166,14 @@ static struct list_head chainhash_table[
((key1) >> (64-MAX_LOCKDEP_KEYS_BITS)) ^ \
(key2))
-void lockdep_off(void)
+void notrace lockdep_off(void)
{
current->lockdep_recursion++;
}
EXPORT_SYMBOL(lockdep_off);
-void lockdep_on(void)
+void notrace lockdep_on(void)
{
current->lockdep_recursion--;
}
@@ -706,7 +706,7 @@ find_usage_forwards(struct lock_class *s
* Return 1 otherwise and keep <backwards_match> unchanged.
* Return 0 on error.
*/
-static noinline int
+static noinline notrace int
find_usage_backwards(struct lock_class *source, unsigned int depth)
{
struct lock_list *entry;
@@ -1386,7 +1386,7 @@ cache_hit:
* We are building curr_chain_key incrementally, so double-check
* it from scratch, to make sure that it's done correctly:
*/
-static void check_chain_key(struct task_struct *curr)
+static void notrace check_chain_key(struct task_struct *curr)
{
#ifdef CONFIG_DEBUG_LOCKDEP
struct held_lock *hlock, *prev_hlock = NULL;
@@ -1573,8 +1573,8 @@ valid_state(struct task_struct *curr, st
/*
* Mark a lock with a usage bit, and validate the state transition:
*/
-static int mark_lock(struct task_struct *curr, struct held_lock *this,
- enum lock_usage_bit new_bit)
+static int notrace mark_lock(struct task_struct *curr, struct held_lock *this,
+ enum lock_usage_bit new_bit)
{
unsigned int new_mask = 1 << new_bit, ret = 1;
@@ -1781,6 +1781,7 @@ static int mark_lock(struct task_struct
* We must printk outside of the graph_lock:
*/
if (ret == 2) {
+ user_trace_stop();
printk("\nmarked lock as {%s}:\n", usage_str[new_bit]);
print_lock(this);
print_irqtrace_events(curr);
@@ -1794,7 +1795,7 @@ static int mark_lock(struct task_struct
/*
* Mark all held locks with a usage bit:
*/
-static int
+static int notrace
mark_held_locks(struct task_struct *curr, int hardirq)
{
enum lock_usage_bit usage_bit;
@@ -1841,7 +1842,7 @@ void early_boot_irqs_on(void)
/*
* Hardirqs will be enabled:
*/
-void trace_hardirqs_on(void)
+void notrace trace_hardirqs_on(void)
{
struct task_struct *curr = current;
unsigned long ip;
@@ -1882,6 +1883,9 @@ void trace_hardirqs_on(void)
curr->hardirq_enable_ip = ip;
curr->hardirq_enable_event = ++curr->irq_events;
debug_atomic_inc(&hardirqs_on_events);
+#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING
+ time_hardirqs_on(CALLER_ADDR0, 0 /* CALLER_ADDR1 */);
+#endif
}
EXPORT_SYMBOL(trace_hardirqs_on);
@@ -1889,7 +1893,7 @@ EXPORT_SYMBOL(trace_hardirqs_on);
/*
* Hardirqs were disabled:
*/
-void trace_hardirqs_off(void)
+void notrace trace_hardirqs_off(void)
{
struct task_struct *curr = current;
@@ -1907,6 +1911,9 @@ void trace_hardirqs_off(void)
curr->hardirq_disable_ip = _RET_IP_;
curr->hardirq_disable_event = ++curr->irq_events;
debug_atomic_inc(&hardirqs_off_events);
+#ifdef CONFIG_CRITICAL_IRQSOFF_TIMING
+ time_hardirqs_off(CALLER_ADDR0, 0 /* CALLER_ADDR1 */);
+#endif
} else
debug_atomic_inc(&redundant_hardirqs_off);
}
@@ -2404,7 +2411,7 @@ __lock_release(struct lockdep_map *lock,
/*
* Check whether we follow the irq-flags state precisely:
*/
-static void check_flags(unsigned long flags)
+static notrace void check_flags(unsigned long flags)
{
#if defined(CONFIG_DEBUG_LOCKDEP) && defined(CONFIG_TRACE_IRQFLAGS)
if (!debug_locks)
@@ -2436,8 +2443,9 @@ static void check_flags(unsigned long fl
* We are not always called with irqs disabled - do that here,
* and also avoid lockdep recursion:
*/
-void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
- int trylock, int read, int check, unsigned long ip)
+void notrace
+lock_acquire(struct lockdep_map *lock, unsigned int subclass,
+ int trylock, int read, int check, unsigned long ip)
{
unsigned long flags;
@@ -2445,9 +2453,9 @@ void lock_acquire(struct lockdep_map *lo
return;
raw_local_irq_save(flags);
+ current->lockdep_recursion = 1;
check_flags(flags);
- current->lockdep_recursion = 1;
__lock_acquire(lock, subclass, trylock, read, check,
irqs_disabled_flags(flags), ip);
current->lockdep_recursion = 0;
@@ -2456,7 +2464,8 @@ void lock_acquire(struct lockdep_map *lo
EXPORT_SYMBOL_GPL(lock_acquire);
-void lock_release(struct lockdep_map *lock, int nested, unsigned long ip)
+void notrace
+lock_release(struct lockdep_map *lock, int nested, unsigned long ip)
{
unsigned long flags;
@@ -2464,8 +2473,8 @@ void lock_release(struct lockdep_map *lo
return;
raw_local_irq_save(flags);
- check_flags(flags);
current->lockdep_recursion = 1;
+ check_flags(flags);
__lock_release(lock, nested, ip);
current->lockdep_recursion = 0;
raw_local_irq_restore(flags);
Index: linux-2.6.22-rc2/kernel/panic.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/panic.c 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/kernel/panic.c 2007-05-24 15:57:42.000000000 +0200
@@ -66,6 +66,8 @@ NORET_TYPE void panic(const char * fmt,
unsigned long caller = (unsigned long) __builtin_return_address(0);
#endif
+ stop_trace();
+
/*
* It's possible to come here directly from a panic-assertion and not
* have preempt disabled. Some functions called from here want
Index: linux-2.6.22-rc2/kernel/printk.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/printk.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/printk.c 2007-05-24 15:57:42.000000000 +0200
@@ -324,12 +324,29 @@ static void __call_console_drivers(unsig
{
struct console *con;
+ touch_critical_timing();
for (con = console_drivers; con; con = con->next) {
if ((con->flags & CON_ENABLED) && con->write &&
(cpu_online(smp_processor_id()) ||
- (con->flags & CON_ANYTIME)))
+ (con->flags & CON_ANYTIME))) {
+ /*
+ * Disable tracing of printk details - it just
+ * clobbers the trace output with lots of
+ * repetitive lines (especially if console is
+ * on a serial line):
+ */
+#ifdef CONFIG_EVENT_TRACE
+ int trace_save = trace_enabled;
+
+ trace_enabled = 0;
+ con->write(con, &LOG_BUF(start), end - start);
+ trace_enabled = trace_save;
+#else
con->write(con, &LOG_BUF(start), end - start);
+#endif
+ }
}
+ touch_critical_timing();
}
static int __read_mostly ignore_loglevel;
Index: linux-2.6.22-rc2/kernel/sched.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/sched.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/sched.c 2007-05-24 15:57:42.000000000 +0200
@@ -76,6 +76,10 @@ unsigned long long __attribute__((weak))
#define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20)
#define TASK_NICE(p) PRIO_TO_NICE((p)->static_prio)
+#define __PRIO(prio) \
+ ((prio) <= 99 ? 199 - (prio) : (prio) - 120)
+
+#define PRIO(p) __PRIO((p)->prio)
/*
* 'User priority' is the nice value converted to something we
* can work with better when scaling various scheduler parameters,
@@ -1043,6 +1047,12 @@ static void deactivate_task(struct task_
p->array = NULL;
}
+static inline void trace_start_sched_wakeup(struct task_struct *p, struct rq *rq)
+{
+ if (p != rq->curr)
+ __trace_start_sched_wakeup(p);
+}
+
/*
* resched_task - mark a task 'to be rescheduled now'.
*
@@ -1060,6 +1070,8 @@ static void resched_task(struct task_str
{
int cpu;
+ trace_start_sched_wakeup(p, task_rq(p));
+
assert_spin_locked(&task_rq(p)->lock);
if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED)))
@@ -1090,6 +1102,8 @@ static void resched_cpu(int cpu)
#else
static inline void resched_task(struct task_struct *p)
{
+ trace_start_sched_wakeup(p, task_rq(p));
+
assert_spin_locked(&task_rq(p)->lock);
set_tsk_need_resched(p);
}
@@ -1615,14 +1629,19 @@ out:
int fastcall wake_up_process(struct task_struct *p)
{
- return try_to_wake_up(p, TASK_STOPPED | TASK_TRACED |
+ int ret = try_to_wake_up(p, TASK_STOPPED | TASK_TRACED |
TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
+ mcount();
+ return ret;
}
EXPORT_SYMBOL(wake_up_process);
int fastcall wake_up_state(struct task_struct *p, unsigned int state)
{
- return try_to_wake_up(p, state, 0);
+ int ret = try_to_wake_up(p, state, 0);
+
+ mcount();
+ return ret;
}
static void task_running_tick(struct rq *rq, struct task_struct *p);
@@ -1860,6 +1879,7 @@ static inline void finish_task_switch(st
prev_state = prev->state;
finish_arch_switch(prev);
finish_lock_switch(rq, prev);
+ trace_stop_sched_switched(current);
if (mm)
mmdrop(mm);
if (unlikely(prev_state == TASK_DEAD)) {
@@ -1930,6 +1950,8 @@ context_switch(struct rq *rq, struct tas
spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
#endif
+ trace_cmdline();
+
/* Here we just switch the register state and the stack. */
switch_to(prev, next, prev);
@@ -3461,41 +3483,39 @@ void scheduler_tick(void)
#endif
}
-#if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT)
+#if defined(CONFIG_EVENT_TRACE) && defined(CONFIG_DEBUG_RT_MUTEXES)
-void fastcall add_preempt_count(int val)
+static void trace_array(struct prio_array *array)
{
- /*
- * Underflow?
- */
- if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0)))
- return;
- preempt_count() += val;
- /*
- * Spinlock count overflowing soon?
- */
- DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >=
- PREEMPT_MASK - 10);
+ int i;
+ struct task_struct *p;
+ struct list_head *head, *tmp;
+
+ for (i = 0; i < MAX_RT_PRIO; i++) {
+ head = array->queue + i;
+ if (list_empty(head)) {
+ WARN_ON(test_bit(i, array->bitmap));
+ continue;
+ }
+ WARN_ON(!test_bit(i, array->bitmap));
+ list_for_each(tmp, head) {
+ p = list_entry(tmp, struct task_struct, run_list);
+ trace_special_pid(p->pid, p->prio, PRIO(p));
+ }
+ }
}
-EXPORT_SYMBOL(add_preempt_count);
-void fastcall sub_preempt_count(int val)
+static inline void trace_all_runnable_tasks(struct rq *rq)
{
- /*
- * Underflow?
- */
- if (DEBUG_LOCKS_WARN_ON(val > preempt_count()))
- return;
- /*
- * Is the spinlock portion underflowing?
- */
- if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) &&
- !(preempt_count() & PREEMPT_MASK)))
- return;
+ if (trace_enabled)
+ trace_array(rq->active);
+}
+
+#else
- preempt_count() -= val;
+static inline void trace_all_runnable_tasks(struct rq *rq)
+{
}
-EXPORT_SYMBOL(sub_preempt_count);
#endif
@@ -3641,6 +3661,8 @@ switch_tasks:
prev->sleep_avg = 0;
prev->timestamp = prev->last_ran = now;
+ trace_all_runnable_tasks(rq);
+
sched_info_switch(prev, next);
if (likely(prev != next)) {
next->timestamp = next->last_ran = now;
@@ -3651,14 +3673,17 @@ switch_tasks:
prepare_task_switch(rq, next);
prev = context_switch(rq, prev, next);
barrier();
+ trace_special_pid(prev->pid, PRIO(prev), PRIO(current));
/*
* this_rq must be evaluated again because prev may have moved
* CPUs since it called schedule(), thus the 'rq' on its stack
* frame will be invalid.
*/
finish_task_switch(this_rq(), prev);
- } else
+ } else {
spin_unlock_irq(&rq->lock);
+ trace_stop_sched_switched(next);
+ }
prev = current;
if (unlikely(reacquire_kernel_lock(prev) < 0))
@@ -4108,6 +4133,7 @@ void rt_mutex_setprio(struct task_struct
} else if (TASK_PREEMPTS_CURR(p, rq))
resched_task(rq->curr);
}
+
task_rq_unlock(rq, &flags);
}
@@ -7055,6 +7081,7 @@ void __might_sleep(char *file, int line)
if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
return;
prev_jiffy = jiffies;
+ stop_trace();
printk(KERN_ERR "BUG: sleeping function called from invalid"
" context at %s:%d\n", file, line);
printk("in_atomic():%d, irqs_disabled():%d\n",
Index: linux-2.6.22-rc2/kernel/softlockup.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/softlockup.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/softlockup.c 2007-05-24 15:57:42.000000000 +0200
@@ -100,6 +100,7 @@ void softlockup_tick(void)
if (now > (touch_timestamp + 10)) {
per_cpu(print_timestamp, this_cpu) = touch_timestamp;
+ stop_trace();
spin_lock(&print_lock);
printk(KERN_ERR "BUG: soft lockup detected on CPU#%d!\n",
this_cpu);
Index: linux-2.6.22-rc2/kernel/sysctl.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/sysctl.c 2007-05-22 16:59:43.000000000 +0200
+++ linux-2.6.22-rc2/kernel/sysctl.c 2007-05-24 15:57:42.000000000 +0200
@@ -29,6 +29,7 @@
#include <linux/utsname.h>
#include <linux/capability.h>
#include <linux/smp_lock.h>
+#include <linux/clocksource.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
@@ -43,6 +44,7 @@
#include <linux/limits.h>
#include <linux/dcache.h>
#include <linux/syscalls.h>
+#include <linux/profile.h>
#include <linux/nfs_fs.h>
#include <linux/acpi.h>
@@ -215,6 +217,132 @@ static ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
+#ifdef CONFIG_WAKEUP_TIMING
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "wakeup_timing",
+ .data = &wakeup_timing,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
+#if defined(CONFIG_WAKEUP_TIMING) || defined(CONFIG_EVENT_TRACE)
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "preempt_max_latency",
+ .data = &preempt_max_latency,
+ .maxlen = sizeof(preempt_max_latency),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "preempt_thresh",
+ .data = &preempt_thresh,
+ .maxlen = sizeof(preempt_thresh),
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax,
+ },
+#endif
+#ifdef CONFIG_EVENT_TRACE
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "trace_enabled",
+ .data = &trace_enabled,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "syscall_tracing",
+ .data = &syscall_tracing,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "stackframe_tracing",
+ .data = &stackframe_tracing,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "mcount_enabled",
+ .data = &mcount_enabled,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "trace_user_triggered",
+ .data = &trace_user_triggered,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "trace_user_trigger_irq",
+ .data = &trace_user_trigger_irq,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "trace_freerunning",
+ .data = &trace_freerunning,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "trace_print_on_crash",
+ .data = &trace_print_on_crash,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "trace_verbose",
+ .data = &trace_verbose,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "trace_all_cpus",
+ .data = &trace_all_cpus,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "trace_use_raw_cycles",
+ .data = &trace_use_raw_cycles,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "trace_all_runnable",
+ .data = &trace_all_runnable,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
{
.ctl_name = KERN_CORE_USES_PID,
.procname = "core_uses_pid",
Index: linux-2.6.22-rc2/lib/Kconfig.debug
===================================================================
--- linux-2.6.22-rc2.orig/lib/Kconfig.debug 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/lib/Kconfig.debug 2007-05-24 15:57:43.000000000 +0200
@@ -296,6 +296,192 @@ config STACKTRACE
depends on DEBUG_KERNEL
depends on STACKTRACE_SUPPORT
+config PREEMPT_TRACE
+ bool
+ default y
+ depends on DEBUG_PREEMPT
+
+config EVENT_TRACE
+ bool "Kernel event tracing"
+ default n
+ depends on GENERIC_TIME
+ select FRAME_POINTER
+ select STACKTRACE
+ help
+ This option enables a kernel tracing mechanism that will track
+ certain kernel events such as system call entry and return,
+ IRQ entry, context-switching, etc.
+
+ Run the scripts/trace-it utility on a kernel with this option
+ enabled for sample output.
+
+config FUNCTION_TRACE
+ bool "Kernel function call tracing"
+ default n
+ depends on !REORDER
+ select EVENT_TRACE
+ help
+ This option enables a kernel tracing mechanism that will track
+ precise function-call granularity kernel execution. Sample
+ output:
+
+ pcscd-1772 0D..2 6867us : deactivate_task <pcscd-1772> (-2 1)
+ pcscd-1772 0D..2 6867us : dequeue_task (deactivate_task)
+ <idle>-0 0D..2 6870us : __switch_to (__schedule)
+ <idle>-0 0D..2 6871us : __schedule <pcscd-1772> (-2 20)
+ <idle>-0 0D..2 6871us : __lock_acquire (lock_acquire)
+ <idle>-0 0D..2 6872us : __spin_unlock_irq (__schedule)
+
+ Run the scripts/trace-it sample utility on a kernel with this
+ option enabled to capture 1 second worth of events.
+
+ (Note that kernel size and overhead increases noticeably
+ with this option enabled.)
+
+config WAKEUP_TIMING
+ bool "Wakeup latency timing"
+ depends on GENERIC_TIME
+ help
+ This option measures the time spent from a highprio thread being
+ woken up to it getting scheduled on a CPU, with microsecond
+ accuracy.
+
+ The default measurement method is a maximum search, which is
+ disabled by default and can be runtime (re-)started via:
+
+ echo 0 > /proc/sys/kernel/preempt_max_latency
+
+config LATENCY_TRACE
+ bool "Latency tracing"
+ default n
+ depends on LATENCY_TIMING && !REORDER && GENERIC_TIME
+ select FRAME_POINTER
+ select FUNCTION_TRACE
+ help
+ When this option is enabled then the last maximum latency timing
+ event's full trace can be found in /proc/latency_trace, in a
+ human-readable (or rather as some would say, in a
+ kernel-developer-readable) form.
+
+ (Note that kernel size and overhead increases noticeably
+ with this option enabled.)
+
+config CRITICAL_PREEMPT_TIMING
+ bool "Non-preemptible critical section latency timing"
+ default n
+ depends on PREEMPT
+ depends on GENERIC_TIME
+ help
+ This option measures the time spent in preempt-off critical
+ sections, with microsecond accuracy.
+
+ The default measurement method is a maximum search, which is
+ disabled by default and can be runtime (re-)started via:
+
+ echo 0 > /proc/sys/kernel/preempt_max_latency
+
+ (Note that kernel size and overhead increases with this option
+ enabled. This option and the irqs-off timing option can be
+ used together or separately.)
+
+config CRITICAL_IRQSOFF_TIMING
+ bool "Interrupts-off critical section latency timing"
+ default n
+ depends on GENERIC_TIME
+ select TRACE_IRQFLAGS
+ help
+ This option measures the time spent in irqs-off critical
+ sections, with microsecond accuracy.
+
+ The default measurement method is a maximum search, which is
+ disabled by default and can be runtime (re-)started via:
+
+ echo 0 > /proc/sys/kernel/preempt_max_latency
+
+ (Note that kernel size and overhead increases with this option
+ enabled. This option and the preempt-off timing option can be
+ used together or separately.)
+
+config WAKEUP_LATENCY_HIST
+ bool "wakeup latency histogram"
+ default n
+ depends on WAKEUP_TIMING
+ help
+ This option logs all the wakeup latency timing to a big histogram
+ bucket, in the meanwhile, it also dummies up printk produced by
+ wakeup latency timing.
+
+ The wakeup latency timing histogram can be viewed via:
+
+ cat /proc/latency_hist/wakeup_latency/CPU*
+
+ (Note: * presents CPU ID.)
+
+config PREEMPT_OFF_HIST
+ bool "non-preemptible critical section latency histogram"
+ default n
+ depends on CRITICAL_PREEMPT_TIMING
+ help
+ This option logs all the non-preemptible critical section latency
+ timing to a big histogram bucket, in the meanwhile, it also
+ dummies up printk produced by non-preemptible critical section
+ latency timing.
+
+ The non-preemptible critical section latency timing histogram can
+ be viewed via:
+
+ cat /proc/latency_hist/preempt_off_latency/CPU*
+
+ (Note: * presents CPU ID.)
+
+config INTERRUPT_OFF_HIST
+ bool "interrupts-off critical section latency histogram"
+ default n
+ depends on CRITICAL_IRQSOFF_TIMING
+ help
+ This option logs all the interrupts-off critical section latency
+ timing to a big histogram bucket, in the meanwhile, it also
+ dummies up printk produced by interrupts-off critical section
+ latency timing.
+
+ The interrupts-off critical section latency timing histogram can
+ be viewed via:
+
+ cat /proc/latency_hist/interrupt_off_latency/CPU*
+
+ (Note: * presents CPU ID.)
+
+config CRITICAL_TIMING
+ bool
+ default y
+ depends on CRITICAL_PREEMPT_TIMING || CRITICAL_IRQSOFF_TIMING
+
+config DEBUG_TRACE_IRQFLAGS
+ bool
+ default y
+ depends on CRITICAL_IRQSOFF_TIMING
+
+config LATENCY_TIMING
+ bool
+ default y
+ depends on WAKEUP_TIMING || CRITICAL_TIMING
+ select SYSCTL
+
+config CRITICAL_LATENCY_HIST
+ bool
+ default y
+ depends on PREEMPT_OFF_HIST || INTERRUPT_OFF_HIST
+
+config LATENCY_HIST
+ bool
+ default y
+ depends on WAKEUP_LATENCY_HIST || CRITICAL_LATENCY_HIST
+
+config MCOUNT
+ bool
+ depends on FUNCTION_TRACE
+ default y
+
config DEBUG_KOBJECT
bool "kobject debugging"
depends on DEBUG_KERNEL
Index: linux-2.6.22-rc2/lib/debug_locks.c
===================================================================
--- linux-2.6.22-rc2.orig/lib/debug_locks.c 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/lib/debug_locks.c 2007-05-24 15:57:43.000000000 +0200
@@ -36,7 +36,16 @@ int debug_locks_silent;
int debug_locks_off(void)
{
if (xchg(&debug_locks, 0)) {
+#if 0
+#ifdef CONFIG_DEBUG_RT_MUTEXES
+ if (spin_is_locked(¤t->pi_lock))
+ spin_unlock(¤t->pi_lock);
+#endif
+#endif
if (!debug_locks_silent) {
+ stop_trace();
+ user_trace_stop();
+ printk("stopped custom tracer.\n");
console_verbose();
return 1;
}
Index: linux-2.6.22-rc2/scripts/Makefile
===================================================================
--- linux-2.6.22-rc2.orig/scripts/Makefile 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/scripts/Makefile 2007-05-24 15:57:43.000000000 +0200
@@ -7,6 +7,7 @@
# conmakehash: Create chartable
# conmakehash: Create arrays for initializing the kernel console tables
+hostprogs-$(CONFIG_EVENT_TRACE) += trace-it
hostprogs-$(CONFIG_KALLSYMS) += kallsyms
hostprogs-$(CONFIG_LOGO) += pnmtologo
hostprogs-$(CONFIG_VT) += conmakehash
Index: linux-2.6.22-rc2/scripts/trace-it.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.22-rc2/scripts/trace-it.c 2007-05-24 15:57:43.000000000 +0200
@@ -0,0 +1,79 @@
+
+/*
+ * Copyright (C) 2005, Ingo Molnar <mingo@redhat.com>
+ *
+ * user-triggered tracing.
+ *
+ * The -rt kernel has a built-in kernel tracer, which will trace
+ * all kernel function calls (and a couple of special events as well),
+ * by using a build-time gcc feature that instruments all kernel
+ * functions.
+ *
+ * The tracer is highly automated for a number of latency tracing purposes,
+ * but it can also be switched into 'user-triggered' mode, which is a
+ * half-automatic tracing mode where userspace apps start and stop the
+ * tracer. This file shows a dumb example how to turn user-triggered
+ * tracing on, and how to start/stop tracing. Note that if you do
+ * multiple start/stop sequences, the kernel will do a maximum search
+ * over their latencies, and will keep the trace of the largest latency
+ * in /proc/latency_trace. The maximums are also reported to the kernel
+ * log. (but can also be read from /proc/sys/kernel/preempt_max_latency)
+ *
+ * For the tracer to be activated, turn on CONFIG_EVENT_TRACING
+ * in the .config, rebuild the kernel and boot into it. The trace will
+ * get _alot_ more verbose if you also turn on CONFIG_FUNCTION_TRACING,
+ * every kernel function call will be put into the trace. Note that
+ * CONFIG_FUNCTION_TRACING has significant runtime overhead, so you dont
+ * want to use it for performance testing :)
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/prctl.h>
+#include <linux/unistd.h>
+
+int main (int argc, char **argv)
+{
+ int ret;
+
+ if (getuid() != 0) {
+ fprintf(stderr, "needs to run as root.\n");
+ exit(1);
+ }
+ ret = system("cat /proc/sys/kernel/mcount_enabled >/dev/null 2>/dev/null");
+ if (ret) {
+ fprintf(stderr, "CONFIG_LATENCY_TRACING not enabled?\n");
+ exit(1);
+ }
+ system("echo 1 > /proc/sys/kernel/trace_user_triggered");
+ system("[ -e /proc/sys/kernel/wakeup_timing ] && echo 0 > /proc/sys/kernel/wakeup_timing");
+ system("echo 1 > /proc/sys/kernel/trace_enabled");
+ system("echo 1 > /proc/sys/kernel/mcount_enabled");
+ system("echo 0 > /proc/sys/kernel/trace_freerunning");
+ system("echo 0 > /proc/sys/kernel/trace_print_on_crash");
+ system("echo 0 > /proc/sys/kernel/trace_verbose");
+ system("echo 0 > /proc/sys/kernel/preempt_thresh 2>/dev/null");
+ system("echo 0 > /proc/sys/kernel/preempt_max_latency 2>/dev/null");
+
+ // start tracing
+ if (prctl(0, 1)) {
+ fprintf(stderr, "trace-it: couldnt start tracing!\n");
+ return 1;
+ }
+ usleep(10000000);
+ if (prctl(0, 0)) {
+ fprintf(stderr, "trace-it: couldnt stop tracing!\n");
+ return 1;
+ }
+
+ system("echo 0 > /proc/sys/kernel/trace_user_triggered");
+ system("echo 0 > /proc/sys/kernel/trace_enabled");
+ system("cat /proc/latency_trace");
+
+ return 0;
+}
+
+
Index: linux-2.6.22-rc2/arch/i386/boot/compressed/Makefile
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/boot/compressed/Makefile 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/boot/compressed/Makefile 2007-05-24 15:57:42.000000000 +0200
@@ -9,6 +9,7 @@ targets := vmlinux vmlinux.bin vmlinux.
EXTRA_AFLAGS := -traditional
LDFLAGS_vmlinux := -T
+CFLAGS := -m32 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing
CFLAGS_misc.o += -fPIC
hostprogs-y := relocs
Index: linux-2.6.22-rc2/arch/i386/kernel/Makefile
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/kernel/Makefile 2007-05-22 16:25:05.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/kernel/Makefile 2007-05-24 15:57:42.000000000 +0200
@@ -21,6 +21,7 @@ obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_X86_SMP) += smp.o smpboot.o tsc_sync.o
obj-$(CONFIG_SMP) += smpcommon.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
+obj-$(CONFIG_MCOUNT) += mcount-wrapper.o
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
Index: linux-2.6.22-rc2/arch/i386/kernel/apic.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/kernel/apic.c 2007-05-22 16:25:05.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/kernel/apic.c 2007-05-24 15:57:43.000000000 +0200
@@ -577,6 +577,8 @@ void fastcall smp_apic_timer_interrupt(s
{
struct pt_regs *old_regs = set_irq_regs(regs);
+ trace_special(regs->eip, 1, 0);
+
/*
* NOTE! We'd better ACK the irq immediately,
* because timer handling can be slow.
Index: linux-2.6.22-rc2/arch/i386/kernel/entry.S
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/kernel/entry.S 2007-05-22 16:25:05.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/kernel/entry.S 2007-05-24 15:57:42.000000000 +0200
@@ -329,6 +329,11 @@ sysenter_past_esp:
pushl %eax
CFI_ADJUST_CFA_OFFSET 4
SAVE_ALL
+#ifdef CONFIG_EVENT_TRACE
+ pushl %edx; pushl %ecx; pushl %ebx; pushl %eax
+ call sys_call
+ popl %eax; popl %ebx; popl %ecx; popl %edx
+#endif
GET_THREAD_INFO(%ebp)
/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
@@ -343,6 +348,11 @@ sysenter_past_esp:
movl TI_flags(%ebp), %ecx
testw $_TIF_ALLWORK_MASK, %cx
jne syscall_exit_work
+#ifdef CONFIG_EVENT_TRACE
+ pushl %eax
+ call sys_ret
+ popl %eax
+#endif
/* if something modifies registers it must also disable sysexit */
movl PT_EIP(%esp), %edx
movl PT_OLDESP(%esp), %ecx
@@ -366,6 +376,11 @@ ENTRY(system_call)
pushl %eax # save orig_eax
CFI_ADJUST_CFA_OFFSET 4
SAVE_ALL
+#ifdef CONFIG_EVENT_TRACE
+ pushl %edx; pushl %ecx; pushl %ebx; pushl %eax
+ call sys_call
+ popl %eax; popl %ebx; popl %ecx; popl %edx
+#endif
GET_THREAD_INFO(%ebp)
testl $TF_MASK,PT_EFLAGS(%esp)
jz no_singlestep
Index: linux-2.6.22-rc2/arch/i386/kernel/hpet.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/kernel/hpet.c 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/kernel/hpet.c 2007-05-24 15:57:42.000000000 +0200
@@ -205,7 +205,7 @@ static int hpet_next_event(unsigned long
/*
* Clock source related code
*/
-static cycle_t read_hpet(void)
+static cycle_t notrace read_hpet(void)
{
return (cycle_t)hpet_readl(HPET_COUNTER);
}
Index: linux-2.6.22-rc2/arch/i386/kernel/irq.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/kernel/irq.c 2007-05-22 16:25:05.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/kernel/irq.c 2007-05-24 15:57:42.000000000 +0200
@@ -68,7 +68,7 @@ static union irq_ctx *softirq_ctx[NR_CPU
* SMP cross-CPU interrupts have their own specific
* handlers).
*/
-fastcall unsigned int do_IRQ(struct pt_regs *regs)
+fastcall notrace unsigned int do_IRQ(struct pt_regs *regs)
{
struct pt_regs *old_regs;
/* high bit used in ret_from_ code */
@@ -87,6 +87,11 @@ fastcall unsigned int do_IRQ(struct pt_r
old_regs = set_irq_regs(regs);
irq_enter();
+#ifdef CONFIG_EVENT_TRACE
+ if (irq == trace_user_trigger_irq)
+ user_trace_start();
+#endif
+ trace_special(regs->eip, irq, 0);
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 1KB free? */
{
Index: linux-2.6.22-rc2/arch/i386/kernel/mcount-wrapper.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.22-rc2/arch/i386/kernel/mcount-wrapper.S 2007-05-24 15:57:42.000000000 +0200
@@ -0,0 +1,27 @@
+/*
+ * linux/arch/i386/mcount-wrapper.S
+ *
+ * Copyright (C) 2004 Ingo Molnar
+ */
+
+.globl mcount
+mcount:
+
+ cmpl $0, mcount_enabled
+ jz out
+
+ push %ebp
+ mov %esp, %ebp
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+
+ call __mcount
+
+ popl %edx
+ popl %ecx
+ popl %eax
+ popl %ebp
+out:
+ ret
+
Index: linux-2.6.22-rc2/arch/i386/kernel/traps.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/kernel/traps.c 2007-05-22 16:25:05.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/kernel/traps.c 2007-05-24 15:57:42.000000000 +0200
@@ -136,7 +136,7 @@ static inline unsigned long print_contex
#define MSG(msg) ops->warning(data, msg)
-void dump_trace(struct task_struct *task, struct pt_regs *regs,
+void notrace dump_trace(struct task_struct *task, struct pt_regs *regs,
unsigned long *stack,
struct stacktrace_ops *ops, void *data)
{
@@ -222,6 +222,7 @@ show_trace_log_lvl(struct task_struct *t
{
dump_trace(task, regs, stack, &print_trace_ops, log_lvl);
printk("%s =======================\n", log_lvl);
+ print_traces(task);
}
void show_trace(struct task_struct *task, struct pt_regs *regs,
Index: linux-2.6.22-rc2/arch/i386/kernel/tsc.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/kernel/tsc.c 2007-05-22 16:25:05.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/kernel/tsc.c 2007-05-24 15:57:42.000000000 +0200
@@ -255,7 +255,7 @@ core_initcall(cpufreq_tsc);
static unsigned long current_tsc_khz = 0;
-static cycle_t read_tsc(void)
+static notrace cycle_t read_tsc(void)
{
cycle_t ret;
Index: linux-2.6.22-rc2/arch/i386/mm/fault.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/mm/fault.c 2007-05-22 16:25:05.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/mm/fault.c 2007-05-24 15:57:42.000000000 +0200
@@ -483,6 +483,7 @@ bad_area_nosemaphore:
nr = (address - idt_descr.address) >> 3;
if (nr == 6) {
+ stop_trace();
do_invalid_op(regs, 0);
return;
}
Index: linux-2.6.22-rc2/arch/i386/mm/init.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/i386/mm/init.c 2007-05-22 16:25:05.000000000 +0200
+++ linux-2.6.22-rc2/arch/i386/mm/init.c 2007-05-24 15:57:42.000000000 +0200
@@ -193,7 +193,7 @@ static inline int page_kills_ppro(unsign
return 0;
}
-int page_is_ram(unsigned long pagenr)
+int notrace page_is_ram(unsigned long pagenr)
{
int i;
unsigned long addr, end;
Index: linux-2.6.22-rc2/include/asm-i386/processor.h
===================================================================
--- linux-2.6.22-rc2.orig/include/asm-i386/processor.h 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/include/asm-i386/processor.h 2007-05-24 15:57:43.000000000 +0200
@@ -602,7 +602,9 @@ static inline void load_esp0(struct tss_
* clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
* resulting in stale register contents being returned.
*/
-static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
+static inline void
+cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
{
*eax = op;
*ecx = 0;
@@ -610,8 +612,9 @@ static inline void cpuid(unsigned int op
}
/* Some CPUID calls want 'count' to be placed in ecx */
-static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
- int *edx)
+static inline void
+cpuid_count(int op, int count, unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
{
*eax = op;
*ecx = count;
Index: linux-2.6.22-rc2/arch/x86_64/ia32/ia32entry.S
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/ia32/ia32entry.S 2007-05-22 16:25:09.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/ia32/ia32entry.S 2007-05-24 15:57:42.000000000 +0200
@@ -120,7 +120,9 @@ sysenter_do_call:
cmpl $(IA32_NR_syscalls-1),%eax
ja ia32_badsys
IA32_ARG_FIXUP 1
+ TRACE_SYS_IA32_CALL
call *ia32_sys_call_table(,%rax,8)
+ TRACE_SYS_RET
movq %rax,RAX-ARGOFFSET(%rsp)
GET_THREAD_INFO(%r10)
cli
@@ -229,7 +231,9 @@ cstar_do_call:
cmpl $IA32_NR_syscalls-1,%eax
ja ia32_badsys
IA32_ARG_FIXUP 1
+ TRACE_SYS_IA32_CALL
call *ia32_sys_call_table(,%rax,8)
+ TRACE_SYS_RET
movq %rax,RAX-ARGOFFSET(%rsp)
GET_THREAD_INFO(%r10)
cli
@@ -323,8 +327,10 @@ ia32_do_syscall:
cmpl $(IA32_NR_syscalls-1),%eax
ja ia32_badsys
IA32_ARG_FIXUP
+ TRACE_SYS_IA32_CALL
call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
ia32_sysret:
+ TRACE_SYS_RET
movq %rax,RAX-ARGOFFSET(%rsp)
jmp int_ret_from_sys_call
@@ -394,7 +400,7 @@ END(ia32_ptregs_common)
.section .rodata,"a"
.align 8
-ia32_sys_call_table:
+ENTRY(ia32_sys_call_table)
.quad sys_restart_syscall
.quad sys_exit
.quad stub32_fork
@@ -719,4 +725,7 @@ ia32_sys_call_table:
.quad compat_sys_signalfd
.quad compat_sys_timerfd
.quad sys_eventfd
+#ifdef CONFIG_EVENT_TRACE
+ .globl ia32_syscall_end
+#endif
ia32_syscall_end:
Index: linux-2.6.22-rc2/arch/x86_64/kernel/entry.S
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/kernel/entry.S 2007-05-22 16:25:10.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/kernel/entry.S 2007-05-24 15:57:42.000000000 +0200
@@ -53,6 +53,47 @@
.code64
+#ifdef CONFIG_EVENT_TRACE
+
+ENTRY(mcount)
+ cmpl $0, mcount_enabled
+ jz out
+
+ push %rbp
+ mov %rsp,%rbp
+
+ push %r11
+ push %r10
+ push %r9
+ push %r8
+ push %rdi
+ push %rsi
+ push %rdx
+ push %rcx
+ push %rax
+
+ mov 0x0(%rbp),%rax
+ mov 0x8(%rbp),%rdi
+ mov 0x8(%rax),%rsi
+
+ call __trace
+
+ pop %rax
+ pop %rcx
+ pop %rdx
+ pop %rsi
+ pop %rdi
+ pop %r8
+ pop %r9
+ pop %r10
+ pop %r11
+
+ pop %rbp
+out:
+ ret
+
+#endif
+
#ifndef CONFIG_PREEMPT
#define retint_kernel retint_restore_args
#endif
@@ -234,7 +275,9 @@ ENTRY(system_call)
cmpq $__NR_syscall_max,%rax
ja badsys
movq %r10,%rcx
+ TRACE_SYS_CALL
call *sys_call_table(,%rax,8) # XXX: rip relative
+ TRACE_SYS_RET
movq %rax,RAX-ARGOFFSET(%rsp)
/*
* Syscall return path ending with SYSRET (fast path)
@@ -316,7 +359,9 @@ tracesys:
cmova %rcx,%rax
ja 1f
movq %r10,%rcx /* fixup for C */
+ TRACE_SYS_CALL
call *sys_call_table(,%rax,8)
+ TRACE_SYS_RET
1: movq %rax,RAX-ARGOFFSET(%rsp)
/* Use IRET because user could have changed frame */
Index: linux-2.6.22-rc2/arch/x86_64/kernel/head64.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/kernel/head64.c 2007-05-22 16:25:10.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/kernel/head64.c 2007-05-24 15:57:42.000000000 +0200
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/percpu.h>
+#include <linux/sched.h>
#include <asm/processor.h>
#include <asm/proto.h>
@@ -58,7 +59,7 @@ static void __init copy_bootdata(char *r
memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
}
-void __init x86_64_start_kernel(char * real_mode_data)
+void __init notrace x86_64_start_kernel(char * real_mode_data)
{
int i;
Index: linux-2.6.22-rc2/arch/x86_64/kernel/irq.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/kernel/irq.c 2007-05-22 16:25:10.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/kernel/irq.c 2007-05-24 15:57:42.000000000 +0200
@@ -115,6 +115,12 @@ asmlinkage unsigned int do_IRQ(struct pt
irq_enter();
irq = __get_cpu_var(vector_irq)[vector];
+#ifdef CONFIG_EVENT_TRACE
+ if (irq == trace_user_trigger_irq)
+ user_trace_start();
+#endif
+ trace_special(regs->rip, irq, 0);
+
#ifdef CONFIG_DEBUG_STACKOVERFLOW
stack_overflow_check(regs);
#endif
Index: linux-2.6.22-rc2/arch/x86_64/kernel/setup64.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/kernel/setup64.c 2007-05-22 16:25:10.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/kernel/setup64.c 2007-05-24 15:57:42.000000000 +0200
@@ -114,7 +114,7 @@ void __init setup_per_cpu_areas(void)
}
}
-void pda_init(int cpu)
+void notrace pda_init(int cpu)
{
struct x8664_pda *pda = cpu_pda(cpu);
@@ -188,7 +188,7 @@ unsigned long kernel_eflags;
* 'CPU state barrier', nothing should get across.
* A lot of state is already set up in PDA init.
*/
-void __cpuinit cpu_init (void)
+void __cpuinit notrace cpu_init (void)
{
int cpu = stack_smp_processor_id();
struct tss_struct *t = &per_cpu(init_tss, cpu);
Index: linux-2.6.22-rc2/arch/x86_64/kernel/smpboot.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/kernel/smpboot.c 2007-05-22 16:25:10.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/kernel/smpboot.c 2007-05-24 15:57:42.000000000 +0200
@@ -318,7 +318,7 @@ static inline void set_cpu_sibling_map(i
/*
* Setup code on secondary processor (after comming out of the trampoline)
*/
-void __cpuinit start_secondary(void)
+void __cpuinit notrace start_secondary(void)
{
/*
* Dont put anything before smp_callin(), SMP
Index: linux-2.6.22-rc2/arch/x86_64/kernel/traps.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/kernel/traps.c 2007-05-22 16:25:10.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/kernel/traps.c 2007-05-24 15:57:42.000000000 +0200
@@ -346,6 +346,7 @@ show_trace(struct task_struct *tsk, stru
printk("\nCall Trace:\n");
dump_trace(tsk, regs, stack, &print_trace_ops, NULL);
printk("\n");
+ print_traces(tsk);
}
static void
Index: linux-2.6.22-rc2/arch/x86_64/kernel/vsyscall.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/kernel/vsyscall.c 2007-05-22 16:25:10.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/kernel/vsyscall.c 2007-05-24 15:57:42.000000000 +0200
@@ -43,7 +43,7 @@
#include <asm/desc.h>
#include <asm/topology.h>
-#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
+#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) notrace
#define __syscall_clobber "r11","rcx","memory"
#define __pa_vsymbol(x) \
({unsigned long v; \
Index: linux-2.6.22-rc2/include/asm-x86_64/calling.h
===================================================================
--- linux-2.6.22-rc2.orig/include/asm-x86_64/calling.h 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/include/asm-x86_64/calling.h 2007-05-24 15:57:43.000000000 +0200
@@ -160,3 +160,53 @@
.macro icebp
.byte 0xf1
.endm
+
+/*
+ * latency-tracing helpers:
+ */
+
+ .macro TRACE_SYS_CALL
+
+#ifdef CONFIG_EVENT_TRACE
+ SAVE_ARGS
+
+ mov %rdx, %rcx
+ mov %rsi, %rdx
+ mov %rdi, %rsi
+ mov %rax, %rdi
+
+ call sys_call
+
+ RESTORE_ARGS
+#endif
+ .endm
+
+
+ .macro TRACE_SYS_IA32_CALL
+
+#ifdef CONFIG_EVENT_TRACE
+ SAVE_ARGS
+
+ mov %rdx, %rcx
+ mov %rsi, %rdx
+ mov %rdi, %rsi
+ mov %rax, %rdi
+
+ call sys_ia32_call
+
+ RESTORE_ARGS
+#endif
+ .endm
+
+ .macro TRACE_SYS_RET
+
+#ifdef CONFIG_EVENT_TRACE
+ SAVE_ARGS
+
+ mov %rax, %rdi
+
+ call sys_ret
+
+ RESTORE_ARGS
+#endif
+ .endm
Index: linux-2.6.22-rc2/include/asm-x86_64/unistd.h
===================================================================
--- linux-2.6.22-rc2.orig/include/asm-x86_64/unistd.h 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/include/asm-x86_64/unistd.h 2007-05-24 15:57:43.000000000 +0200
@@ -11,6 +11,8 @@
* Note: holes are not allowed.
*/
+#define NR_syscalls (__NR_syscall_max+1)
+
/* at least 8 syscall per cacheline */
#define __NR_read 0
__SYSCALL(__NR_read, sys_read)
Index: linux-2.6.22-rc2/include/linux/prctl.h
===================================================================
--- linux-2.6.22-rc2.orig/include/linux/prctl.h 2007-04-26 05:08:32.000000000 +0200
+++ linux-2.6.22-rc2/include/linux/prctl.h 2007-05-24 15:57:43.000000000 +0200
@@ -3,6 +3,7 @@
/* Values to pass as first argument to prctl() */
+#define PR_SET_TRACING 0 /* Second arg is tracing on/off */
#define PR_SET_PDEATHSIG 1 /* Second arg is a signal */
#define PR_GET_PDEATHSIG 2 /* Second arg is a ptr to return the signal */
Index: linux-2.6.22-rc2/kernel/sys.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/sys.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/sys.c 2007-05-24 15:57:42.000000000 +0200
@@ -2149,6 +2149,14 @@ asmlinkage long sys_prctl(int option, un
{
long error;
+#ifdef CONFIG_EVENT_TRACE
+ if (option == PR_SET_TRACING) {
+ if (arg2)
+ return user_trace_start();
+ return user_trace_stop();
+ }
+#endif
+
error = security_task_prctl(option, arg2, arg3, arg4, arg5);
if (error)
return error;
Index: linux-2.6.22-rc2/kernel/time/timekeeping.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/time/timekeeping.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/time/timekeeping.c 2007-05-24 15:57:42.000000000 +0200
@@ -195,6 +195,34 @@ static void change_clocksource(void)
printk(KERN_INFO "Time: %s clocksource has been installed.\n",
clock->name);
}
+
+cycle_t notrace get_monotonic_cycles(void)
+{
+ cycle_t cycle_now, cycle_delta;
+
+ /* read clocksource: */
+ cycle_now = clocksource_read(clock);
+
+ /* calculate the delta since the last update_wall_time: */
+ cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+ return clock->cycle_last + cycle_delta;
+}
+
+unsigned long notrace cycles_to_usecs(cycle_t cycles)
+{
+ u64 ret = cyc2ns(clock, cycles);
+
+ do_div(ret, 1000);
+
+ return ret;
+}
+
+cycle_t notrace usecs_to_cycles(unsigned long usecs)
+{
+ return ns2cyc(clock, (u64)usecs * 1000);
+}
+
#else
static inline void change_clocksource(void) { }
#endif
Index: linux-2.6.22-rc2/arch/x86_64/kernel/stacktrace.c
===================================================================
--- linux-2.6.22-rc2.orig/arch/x86_64/kernel/stacktrace.c 2007-05-22 16:25:10.000000000 +0200
+++ linux-2.6.22-rc2/arch/x86_64/kernel/stacktrace.c 2007-05-24 15:57:42.000000000 +0200
@@ -24,7 +24,7 @@ static int save_stack_stack(void *data,
return -1;
}
-static void save_stack_address(void *data, unsigned long addr)
+static void notrace save_stack_address(void *data, unsigned long addr)
{
struct stack_trace *trace = (struct stack_trace *)data;
if (trace->skip > 0) {
Index: linux-2.6.22-rc2/kernel/hrtimer.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/hrtimer.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/hrtimer.c 2007-05-24 15:57:42.000000000 +0200
@@ -553,6 +553,8 @@ static inline int hrtimer_enqueue_reprog
return 0;
}
+void trace_start_ht_debug(void);
+
/*
* Switch to high resolution mode
*/
@@ -576,6 +578,9 @@ static int hrtimer_switch_to_hres(void)
tick_setup_sched_timer();
+ if (!cpu)
+ trace_start_ht_debug();
+
/* "Retrigger" the interrupt to get things going */
retrigger_next_event(NULL);
local_irq_restore(flags);
Index: linux-2.6.22-rc2/kernel/time/tick-sched.c
===================================================================
--- linux-2.6.22-rc2.orig/kernel/time/tick-sched.c 2007-05-22 16:25:19.000000000 +0200
+++ linux-2.6.22-rc2/kernel/time/tick-sched.c 2007-05-24 15:57:42.000000000 +0200
@@ -167,9 +167,21 @@ void tick_nohz_stop_sched_tick(void)
goto end;
cpu = smp_processor_id();
- if (unlikely(local_softirq_pending()))
- printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
- local_softirq_pending());
+ if (unlikely(local_softirq_pending())) {
+ static int ratelimit;
+
+ if (ratelimit < 10) {
+ if (!cpu) {
+ trace_special(0, 0, 0);
+ user_trace_stop();
+ ratelimit = 10;
+ }
+ printk(KERN_ERR
+ "NOHZ: local_softirq_pending %02x on CPU %d\n",
+ local_softirq_pending(), cpu);
+ ratelimit++;
+ }
+ }
now = ktime_get();
/*
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 14:03 ` Miklos Szeredi
@ 2007-05-24 14:10 ` Ingo Molnar
2007-05-24 14:28 ` Miklos Szeredi
0 siblings, 1 reply; 13+ messages in thread
From: Ingo Molnar @ 2007-05-24 14:10 UTC (permalink / raw)
To: Miklos Szeredi; +Cc: linux-kernel, linux-acpi, tglx
* Miklos Szeredi <miklos@szeredi.hu> wrote:
> > how reproducable are these lockups - could you possibly trace it? If
> > yes then please apply:
> >
> > http://www.tglx.de/private/tglx/ht-debug/tracer.diff
>
> With this patch boot stops at segfaulting fsck. I enabled all the new
> config options, is that not a good idea? Which one exactly do I need?
hm, you should only need these:
CONFIG_EVENT_TRACE=y
CONFIG_FUNCTION_TRACE=y
# CONFIG_WAKEUP_TIMING is not set
# CONFIG_CRITICAL_IRQSOFF_TIMING is not set
CONFIG_MCOUNT=y
does it boot with these?
Ingo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 14:10 ` Ingo Molnar
@ 2007-05-24 14:28 ` Miklos Szeredi
2007-05-24 14:42 ` Ingo Molnar
2007-05-24 14:44 ` Ingo Molnar
0 siblings, 2 replies; 13+ messages in thread
From: Miklos Szeredi @ 2007-05-24 14:28 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, linux-acpi, tglx
> > > how reproducable are these lockups - could you possibly trace it? If
> > > yes then please apply:
> > >
> > > http://www.tglx.de/private/tglx/ht-debug/tracer.diff
> >
> > With this patch boot stops at segfaulting fsck. I enabled all the new
> > config options, is that not a good idea? Which one exactly do I need?
>
> hm, you should only need these:
>
> CONFIG_EVENT_TRACE=y
> CONFIG_FUNCTION_TRACE=y
> # CONFIG_WAKEUP_TIMING is not set
> # CONFIG_CRITICAL_IRQSOFF_TIMING is not set
> CONFIG_MCOUNT=y
>
> does it boot with these?
Nope. Same segfault. If I try to continue manually with 'init 5',
then init segfaults as well :(
Miklos
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 14:28 ` Miklos Szeredi
@ 2007-05-24 14:42 ` Ingo Molnar
2007-05-24 14:44 ` Ingo Molnar
1 sibling, 0 replies; 13+ messages in thread
From: Ingo Molnar @ 2007-05-24 14:42 UTC (permalink / raw)
To: Miklos Szeredi; +Cc: linux-kernel, linux-acpi, tglx
* Miklos Szeredi <miklos@szeredi.hu> wrote:
> > hm, you should only need these:
> >
> > CONFIG_EVENT_TRACE=y
> > CONFIG_FUNCTION_TRACE=y
> > # CONFIG_WAKEUP_TIMING is not set
> > # CONFIG_CRITICAL_IRQSOFF_TIMING is not set
> > CONFIG_MCOUNT=y
> >
> > does it boot with these?
>
> Nope. Same segfault. If I try to continue manually with 'init 5',
> then init segfaults as well :(
does it go away if you turn off CONFIG_FUNCTION_TRACE? (that will make
the trace a lot less verbose, but still informative)
Ingo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 14:28 ` Miklos Szeredi
2007-05-24 14:42 ` Ingo Molnar
@ 2007-05-24 14:44 ` Ingo Molnar
2007-05-24 17:09 ` Miklos Szeredi
1 sibling, 1 reply; 13+ messages in thread
From: Ingo Molnar @ 2007-05-24 14:44 UTC (permalink / raw)
To: Miklos Szeredi; +Cc: linux-kernel, linux-acpi, tglx
* Miklos Szeredi <miklos@szeredi.hu> wrote:
> > CONFIG_EVENT_TRACE=y
> > CONFIG_FUNCTION_TRACE=y
> > # CONFIG_WAKEUP_TIMING is not set
> > # CONFIG_CRITICAL_IRQSOFF_TIMING is not set
> > CONFIG_MCOUNT=y
> >
> > does it boot with these?
>
> Nope. Same segfault. If I try to continue manually with 'init 5',
> then init segfaults as well :(
could you just try v2.6.21 plus the -rt patch, which has the tracer
built-in? That's a combination that should work well. You can pick it up
from:
http://people.redhat.com/mingo/realtime-preempt/
same config options as above. If you dont turn on PREEMPT_RT you'll get
an almost-vanilla kernel.
Ingo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 14:44 ` Ingo Molnar
@ 2007-05-24 17:09 ` Miklos Szeredi
2007-05-24 21:01 ` Ingo Molnar
0 siblings, 1 reply; 13+ messages in thread
From: Miklos Szeredi @ 2007-05-24 17:09 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel, linux-acpi, tglx
> could you just try v2.6.21 plus the -rt patch, which has the tracer
> built-in? That's a combination that should work well. You can pick it up
> from:
>
> http://people.redhat.com/mingo/realtime-preempt/
>
> same config options as above. If you dont turn on PREEMPT_RT you'll get
> an almost-vanilla kernel.
2.6.22-rc2, only EVENT_TRACE - boots, can't rerpoduce
2.6.21-vanila - can reproduce
2.6.21-rt7, trace options off - can reproduce
2.6.21-rt7, trace options on - can't reproduce
Possibly something timing related, that's altered by the trace code.
I tried the trace kernel without starting the trace app, but still no
bug.
Any other ideas?
Thanks,
Miklos
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 17:09 ` Miklos Szeredi
@ 2007-05-24 21:01 ` Ingo Molnar
2007-05-25 9:51 ` Miklos Szeredi
0 siblings, 1 reply; 13+ messages in thread
From: Ingo Molnar @ 2007-05-24 21:01 UTC (permalink / raw)
To: Miklos Szeredi; +Cc: linux-kernel, linux-acpi, tglx
* Miklos Szeredi <miklos@szeredi.hu> wrote:
> 2.6.22-rc2, only EVENT_TRACE - boots, can't rerpoduce
> 2.6.21-vanila - can reproduce
> 2.6.21-rt7, trace options off - can reproduce
> 2.6.21-rt7, trace options on - can't reproduce
>
> Possibly something timing related, that's altered by the trace code. I
> tried the trace kernel without starting the trace app, but still no
> bug.
>
> Any other ideas?
perhaps try 2.6.21-rt7 with EVENT_TRACE on (the other trace options off)
- does that hide the bug too?
Ingo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 12:04 [BUG] long freezes on thinkpad t60 Miklos Szeredi
2007-05-24 12:54 ` Ingo Molnar
@ 2007-05-24 22:08 ` Henrique de Moraes Holschuh
2007-05-24 22:13 ` Kok, Auke
1 sibling, 1 reply; 13+ messages in thread
From: Henrique de Moraes Holschuh @ 2007-05-24 22:08 UTC (permalink / raw)
To: Miklos Szeredi; +Cc: linux-kernel, mingo, linux-acpi
On Thu, 24 May 2007, Miklos Szeredi wrote:
> Tried nmi_watchdog=1, but then the machine locks up hard shortly after
> boot.
NMIs in some thinkpads are bad trouble, they lock up the blasted IBM/Lenovo
SMBIOS if they happen to hit it while it is servicing a SMI, and thinkpads
do SMIs like crazy.
--
"One disk to rule them all, One disk to find them. One disk to bring
them all and in the darkness grind them. In the Land of Redmond
where the shadows lie." -- The Silicon Valley Tarot
Henrique Holschuh
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 22:08 ` Henrique de Moraes Holschuh
@ 2007-05-24 22:13 ` Kok, Auke
2007-05-25 6:58 ` Ingo Molnar
0 siblings, 1 reply; 13+ messages in thread
From: Kok, Auke @ 2007-05-24 22:13 UTC (permalink / raw)
To: Henrique de Moraes Holschuh
Cc: Miklos Szeredi, linux-kernel, mingo, linux-acpi
Henrique de Moraes Holschuh wrote:
> On Thu, 24 May 2007, Miklos Szeredi wrote:
>> Tried nmi_watchdog=1, but then the machine locks up hard shortly after
>> boot.
>
> NMIs in some thinkpads are bad trouble, they lock up the blasted IBM/Lenovo
> SMBIOS if they happen to hit it while it is servicing a SMI, and thinkpads
> do SMIs like crazy.
there's also a L1 ASPM issue with the e1000 chipset in the way (for T60/X60
only). Make sure you are using 2.6.21 or newer. See netdev archives for more on
that.
Auke
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 22:13 ` Kok, Auke
@ 2007-05-25 6:58 ` Ingo Molnar
0 siblings, 0 replies; 13+ messages in thread
From: Ingo Molnar @ 2007-05-25 6:58 UTC (permalink / raw)
To: Kok, Auke
Cc: Henrique de Moraes Holschuh, Miklos Szeredi, linux-kernel,
linux-acpi
* Kok, Auke <auke-jan.h.kok@intel.com> wrote:
> Henrique de Moraes Holschuh wrote:
> >On Thu, 24 May 2007, Miklos Szeredi wrote:
> >>Tried nmi_watchdog=1, but then the machine locks up hard shortly after
> >>boot.
> >
> >NMIs in some thinkpads are bad trouble, they lock up the blasted IBM/Lenovo
> >SMBIOS if they happen to hit it while it is servicing a SMI, and thinkpads
> >do SMIs like crazy.
>
> there's also a L1 ASPM issue with the e1000 chipset in the way (for
> T60/X60 only). Make sure you are using 2.6.21 or newer. See netdev
> archives for more on that.
Miklos is using latest -git and he has nmi_watchdog disabled - still the
long pauses persist. (i've never seen that on my t60)
Ingo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [BUG] long freezes on thinkpad t60
2007-05-24 21:01 ` Ingo Molnar
@ 2007-05-25 9:51 ` Miklos Szeredi
0 siblings, 0 replies; 13+ messages in thread
From: Miklos Szeredi @ 2007-05-25 9:51 UTC (permalink / raw)
To: mingo; +Cc: chris, linux-kernel, linux-acpi, tglx
> > 2.6.22-rc2, only EVENT_TRACE - boots, can't rerpoduce
> > 2.6.21-vanila - can reproduce
> > 2.6.21-rt7, trace options off - can reproduce
> > 2.6.21-rt7, trace options on - can't reproduce
> >
> > Possibly something timing related, that's altered by the trace code. I
> > tried the trace kernel without starting the trace app, but still no
> > bug.
> >
> > Any other ideas?
>
> perhaps try 2.6.21-rt7 with EVENT_TRACE on (the other trace options off)
> - does that hide the bug too?
The option itself doesn't hide the bug this time, I got one freeze
pretty quickly. But after starting the trace-it-1sec loop, I couldn't
get it any more.
Normally I get a freeze after 3-5 minutes of testing, but with
trace-it-1sec there's still nothing after 30 minutes.
If I stop trace-it, and do "echo 0 > /proc/sys/kernel/trace_enabled",
I get the freeze again. It's a perfect heisenbug.
This issue came up when I was testing a userspace fuse bug, and now
the reporter of that bug (added to CC) says that he also sometimes
experienced a hard lockup during testing but ignored it up to now. So
we may yet get some info from him.
It could be something fuse related, but it's very hard to imagine how
fuse could trigger such a low-level problem.
Miklos
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2007-05-25 9:52 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-24 12:04 [BUG] long freezes on thinkpad t60 Miklos Szeredi
2007-05-24 12:54 ` Ingo Molnar
2007-05-24 14:03 ` Miklos Szeredi
2007-05-24 14:10 ` Ingo Molnar
2007-05-24 14:28 ` Miklos Szeredi
2007-05-24 14:42 ` Ingo Molnar
2007-05-24 14:44 ` Ingo Molnar
2007-05-24 17:09 ` Miklos Szeredi
2007-05-24 21:01 ` Ingo Molnar
2007-05-25 9:51 ` Miklos Szeredi
2007-05-24 22:08 ` Henrique de Moraes Holschuh
2007-05-24 22:13 ` Kok, Auke
2007-05-25 6:58 ` Ingo Molnar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox