[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Geforce FX 5900XT



Hi Daniel,

given that a go now... unfortunately failed build.

Here is the bits I think are relevant to it failing:

 CC      kernel/rt.o
 CC      kernel/latency.o
kernel/latency.c: In function `__trace_start_sched_wakeup':
kernel/latency.c:1421: warning: implicit declaration of function `_trace_cmdline'
.
. (carried on building...)
.
.
.
 LD      init/built-in.o
 LD      .tmp_vmlinux1
ld: BFD 2.15 assertion fail ../../bfd/linker.c:619
kernel/built-in.o(.text+0x1f259): In function `__trace_start_sched_wakeup':
: undefined reference to `_trace_cmdline'
make: *** [.tmp_vmlinux1] Error 1


Attatched is the full log file to see if you can make anything of it :) Also attatched is latency.c

Thanks,
James

Daniel James wrote:

Hi James,

I have run the RP-patch-script...

What do I do now? I've not actually made a kernel before :(

Did the script download and patch a kernel source package for you? If so, unpack it in /usr/src/linux/ and run:

make menuconfig

as root. See:
http://www.digitalhermit.com/linux/Kernel-Build-HOWTO.html#CONFIGURATION-2-6

Be warned, it's not easy to do the first time!

I sent this off-list to you, and your MTA rejected it...)
550     81.154.99.172 is listed at combined.njabl.org

I have spam filtering on mondodesigno.com, so your ISP probably has spamming customers. See:

http://www.njabl.org/

Use daniel at linux audio dot org if you still have problems.

Cheers

Daniel



bathory4:/usr/src/linux# make bzImage
  CHK     include/linux/version.h
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/basic/split-include
  HOSTCC  scripts/basic/docproc
  CC      scripts/mod/empty.o
  HOSTCC  scripts/mod/mk_elfconfig
  MKELF   scripts/mod/elfconfig.h
  HOSTCC  scripts/mod/file2alias.o
  HOSTCC  scripts/mod/modpost.o
  HOSTCC  scripts/mod/sumversion.o
  HOSTLD  scripts/mod/modpost
  HOSTCC  scripts/kallsyms
  HOSTCC  scripts/conmakehash
  HOSTCC  scripts/bin2c
  CC      arch/x86_64/kernel/asm-offsets.s
  CHK     include/asm-x86_64/offset.h
  UPD     include/asm-x86_64/offset.h
  CC      init/main.o
  CHK     include/linux/compile.h
  UPD     include/linux/compile.h
  CC      init/version.o
  CC      init/do_mounts.o
  CC      init/do_mounts_rd.o
  CC      init/do_mounts_initrd.o
  LD      init/mounts.o
  CC      init/initramfs.o
  CC      init/calibrate.o
  LD      init/built-in.o
  HOSTCC  usr/gen_init_cpio
  CHK     usr/initramfs_list
  UPD     usr/initramfs_list
  CPIO    usr/initramfs_data.cpio
  GZIP    usr/initramfs_data.cpio.gz
  AS      usr/initramfs_data.o
  LD      usr/built-in.o
  CC      arch/x86_64/kernel/process.o
  CC      arch/x86_64/kernel/signal.o
  AS      arch/x86_64/kernel/entry.o
  CC      arch/x86_64/kernel/traps.o
  CC      arch/x86_64/kernel/irq.o
  CC      arch/x86_64/kernel/ptrace.o
  CC      arch/x86_64/kernel/time.o
  CC      arch/x86_64/kernel/ioport.o
  CC      arch/x86_64/kernel/ldt.o
  CC      arch/x86_64/kernel/setup.o
  CC      arch/x86_64/kernel/i8259.o
  CC      arch/x86_64/kernel/sys_x86_64.o
  CC      arch/x86_64/kernel/x8664_ksyms.o
  CC      arch/x86_64/kernel/i387.o
  CC      arch/x86_64/kernel/syscall.o
  CC      arch/x86_64/kernel/vsyscall.o
  CC      arch/x86_64/kernel/setup64.o
  CC      arch/x86_64/kernel/../../i386/kernel/bootflag.o
  CC      arch/x86_64/kernel/../../i386/kernel/cpu/intel_cacheinfo.o
  CC      arch/x86_64/kernel/../../i386/kernel/quirks.o
  CC      arch/x86_64/kernel/../../ia64/lib/swiotlb.o
  CC      arch/x86_64/kernel/../../i386/mach-default/topology.o
  LD      arch/x86_64/kernel/bootflag.o
  CC      arch/x86_64/kernel/e820.o
  CC      arch/x86_64/kernel/reboot.o
  LD      arch/x86_64/kernel/quirks.o
  CC      arch/x86_64/kernel/mce.o
  CC      arch/x86_64/kernel/mce_intel.o
  CC      arch/x86_64/kernel/../../i386/kernel/cpu/mtrr/main.o
  CC      arch/x86_64/kernel/../../i386/kernel/cpu/mtrr/if.o
  CC      arch/x86_64/kernel/../../i386/kernel/cpu/mtrr/generic.o
  CC      arch/x86_64/kernel/../../i386/kernel/cpu/mtrr/state.o
  CC      arch/x86_64/kernel/../../i386/kernel/cpu/mtrr/amd.o
  CC      arch/x86_64/kernel/../../i386/kernel/cpu/mtrr/cyrix.o
  CC      arch/x86_64/kernel/../../i386/kernel/cpu/mtrr/centaur.o
  LD      arch/x86_64/kernel/../../i386/kernel/cpu/mtrr/built-in.o
  CC      arch/x86_64/kernel/acpi/../../../i386/kernel/acpi/boot.o
  LD      arch/x86_64/kernel/acpi/boot.o
  LD      arch/x86_64/kernel/acpi/built-in.o
  LD      arch/x86_64/kernel/cpufreq/built-in.o
  CC      arch/x86_64/kernel/apic.o
  CC      arch/x86_64/kernel/nmi.o
  CC      arch/x86_64/kernel/io_apic.o
  CC      arch/x86_64/kernel/mpparse.o
  CC      arch/x86_64/kernel/genapic.o
  CC      arch/x86_64/kernel/genapic_cluster.o
  CC      arch/x86_64/kernel/genapic_flat.o
  CC      arch/x86_64/kernel/suspend.o
  CC      arch/x86_64/kernel/early_printk.o
  CC      arch/x86_64/kernel/pci-gart.o
  CC      arch/x86_64/kernel/aperture.o
  LD      arch/x86_64/kernel/swiotlb.o
  CC      arch/x86_64/kernel/module.o
  LD      arch/x86_64/kernel/topology.o
  LD      arch/x86_64/kernel/intel_cacheinfo.o
  LD      arch/x86_64/kernel/built-in.o
  AS      arch/x86_64/kernel/head.o
  CC      arch/x86_64/kernel/head64.o
  CC      arch/x86_64/kernel/init_task.o
  LDS     arch/x86_64/kernel/vmlinux.lds
  CC      arch/x86_64/mm/init.o
  CC      arch/x86_64/mm/fault.o
  CC      arch/x86_64/mm/ioremap.o
  CC      arch/x86_64/mm/extable.o
  CC      arch/x86_64/mm/pageattr.o
  LD      arch/x86_64/mm/built-in.o
  AS      arch/x86_64/ia32/ia32entry.o
  CC      arch/x86_64/ia32/sys_ia32.o
  CC      arch/x86_64/ia32/ia32_ioctl.o
  CC      arch/x86_64/ia32/ia32_signal.o
  CC      arch/x86_64/ia32/tls32.o
  CC      arch/x86_64/ia32/ia32_binfmt.o
  CC      arch/x86_64/ia32/fpu32.o
  CC      arch/x86_64/ia32/ptrace32.o
  AS      arch/x86_64/ia32/vsyscall-sysenter.o
  SYSCALL arch/x86_64/ia32/vsyscall-sysenter.so
  AS      arch/x86_64/ia32/vsyscall-syscall.o
  SYSCALL arch/x86_64/ia32/vsyscall-syscall.so
  CC      arch/x86_64/ia32/syscall32.o
  CC      arch/x86_64/ia32/ipc32.o
  CC      arch/x86_64/ia32/ia32_aout.o
  LD      arch/x86_64/ia32/built-in.o
  CC      kernel/sched.o
  CC      kernel/fork.o
  CC      kernel/exec_domain.o
  CC      kernel/panic.o
  CC      kernel/printk.o
  CC      kernel/profile.o
  CC      kernel/exit.o
  CC      kernel/itimer.o
  CC      kernel/time.o
  CC      kernel/softirq.o
  CC      kernel/resource.o
  CC      kernel/sysctl.o
  CC      kernel/capability.o
  CC      kernel/ptrace.o
  CC      kernel/timer.o
  CC      kernel/user.o
  CC      kernel/signal.o
  CC      kernel/sys.o
  CC      kernel/kmod.o
  CC      kernel/workqueue.o
  CC      kernel/pid.o
  CC      kernel/rcupdate.o
  CC      kernel/intermodule.o
kernel/intermodule.c:179: warning: `inter_module_register' is deprecated (declared at kernel/intermodule.c:38)
kernel/intermodule.c:180: warning: `inter_module_unregister' is deprecated (declared at kernel/intermodule.c:79)kernel/intermodule.c:183: warning: `inter_module_put' is deprecated (declared at kernel/intermodule.c:160)
  CC      kernel/extable.o
  CC      kernel/params.o
  CC      kernel/posix-timers.o
  CC      kernel/kthread.o
  CC      kernel/wait.o
  CC      kernel/kfifo.o
  CC      kernel/sys_ni.o
  CC      kernel/rt.o
  CC      kernel/latency.o
kernel/latency.c: In function `__trace_start_sched_wakeup':
kernel/latency.c:1421: warning: implicit declaration of function `_trace_cmdline'
  CC      kernel/futex.o
  CC      kernel/dma.o
  CC      kernel/uid16.o
  CC      kernel/module.o
  CC      kernel/kallsyms.o
  CC      kernel/irq/handle.o
  CC      kernel/irq/manage.o
  CC      kernel/irq/spurious.o
  CC      kernel/irq/autoprobe.o
  CC      kernel/irq/proc.o
  LD      kernel/irq/built-in.o
  CC      kernel/power/main.o
  CC      kernel/power/process.o
  CC      kernel/power/console.o
  CC      kernel/power/pm.o
kernel/power/pm.c: In function `pm_undo_all':
kernel/power/pm.c:201: warning: `pm_send' is deprecated (declared at kernel/power/pm.c:155)
kernel/power/pm.c: In function `pm_send_all':
kernel/power/pm.c:242: warning: `pm_send' is deprecated (declared at kernel/power/pm.c:155)
kernel/power/pm.c: At top level:
kernel/power/pm.c:259: warning: `pm_register' is deprecated (declared at kernel/power/pm.c:62)
kernel/power/pm.c:260: warning: `pm_unregister' is deprecated (declared at kernel/power/pm.c:86)
kernel/power/pm.c:261: warning: `pm_unregister_all' is deprecated (declared at kernel/power/pm.c:115)
kernel/power/pm.c:262: warning: `pm_send_all' is deprecated (declared at kernel/power/pm.c:234)
  CC      kernel/power/poweroff.o
  LD      kernel/power/built-in.o
  CC      kernel/acct.o
  CC      kernel/compat.o
  GZIP    kernel/config_data.gz
  IKCFG   kernel/config_data.h
  CC      kernel/configs.o
  CC      kernel/audit.o
  CC      kernel/ksysfs.o
  LD      kernel/built-in.o
  CC      mm/bootmem.o
  CC      mm/filemap.o
  CC      mm/mempool.o
  CC      mm/oom_kill.o
  CC      mm/fadvise.o
  CC      mm/page_alloc.o
  CC      mm/page-writeback.o
  CC      mm/pdflush.o
  CC      mm/readahead.o
  CC      mm/slab.o
  CC      mm/swap.o
  CC      mm/truncate.o
  CC      mm/vmscan.o
  CC      mm/prio_tree.o
  CC      mm/fremap.o
  CC      mm/highmem.o
  CC      mm/madvise.o
  CC      mm/memory.o
  CC      mm/mincore.o
  CC      mm/mlock.o
  CC      mm/mmap.o
  CC      mm/mprotect.o
  CC      mm/mremap.o
  CC      mm/msync.o
  CC      mm/rmap.o
  CC      mm/vmalloc.o
  CC      mm/page_io.o
  CC      mm/swap_state.o
  CC      mm/swapfile.o
  CC      mm/thrash.o
  CC      mm/shmem.o
  LD      mm/built-in.o
  CC      fs/open.o
  CC      fs/read_write.o
  CC      fs/file_table.o
  CC      fs/buffer.o
  CC      fs/bio.o
  CC      fs/super.o
  CC      fs/block_dev.o
  CC      fs/char_dev.o
  CC      fs/stat.o
  CC      fs/exec.o
  CC      fs/pipe.o
  CC      fs/namei.o
  CC      fs/fcntl.o
  CC      fs/ioctl.o
  CC      fs/readdir.o
  CC      fs/select.o
  CC      fs/fifo.o
  CC      fs/locks.o
  CC      fs/dcache.o
  CC      fs/inode.o
  CC      fs/attr.o
  CC      fs/bad_inode.o
  CC      fs/file.o
  CC      fs/filesystems.o
  CC      fs/namespace.o
  CC      fs/aio.o
  CC      fs/seq_file.o
  CC      fs/xattr.o
  CC      fs/libfs.o
  CC      fs/fs-writeback.o
  CC      fs/mpage.o
  CC      fs/direct-io.o
  CC      fs/eventpoll.o
  CC      fs/compat.o
  CC      fs/nfsctl.o
  CC      fs/binfmt_script.o
  CC      fs/binfmt_elf.o
  CC      fs/posix_acl.o
  CC      fs/xattr_acl.o
  CC      fs/dquot.o
  CC      fs/quota.o
  CC      fs/dnotify.o
  LD      fs/autofs/built-in.o
  LD      fs/autofs4/built-in.o
  LD      fs/cifs/built-in.o
  LD      fs/coda/built-in.o
  CC      fs/cramfs/inode.o
  CC      fs/cramfs/uncompress.o
  LD      fs/cramfs/cramfs.o
  LD      fs/cramfs/built-in.o
  CC      fs/devpts/inode.o
  CC      fs/devpts/xattr_security.o
  LD      fs/devpts/devpts.o
  LD      fs/devpts/built-in.o
  LD      fs/exportfs/built-in.o
  LD      fs/ext2/built-in.o
  LD      fs/ext3/built-in.o
  LD      fs/fat/built-in.o
  LD      fs/freevxfs/built-in.o
  LD      fs/hfsplus/built-in.o
  LD      fs/hpfs/built-in.o
  LD      fs/isofs/built-in.o
  LD      fs/jbd/built-in.o
  LD      fs/jffs/built-in.o
  LD      fs/jffs2/built-in.o
  LD      fs/jfs/built-in.o
  LD      fs/lockd/built-in.o
  LD      fs/minix/built-in.o
  LD      fs/msdos/built-in.o
  LD      fs/ncpfs/built-in.o
  LD      fs/nfs/built-in.o
  LD      fs/nfsd/built-in.o
  CC      fs/nls/nls_base.o
  LD      fs/nls/built-in.o
  LD      fs/ntfs/built-in.o
  CC      fs/partitions/check.o
  CC      fs/partitions/acorn.o
  CC      fs/partitions/amiga.o
  CC      fs/partitions/atari.o
  CC      fs/partitions/mac.o
  CC      fs/partitions/ldm.o
  CC      fs/partitions/msdos.o
  CC      fs/partitions/osf.o
  CC      fs/partitions/sgi.o
  CC      fs/partitions/sun.o
  CC      fs/partitions/ultrix.o
  CC      fs/partitions/efi.o
  LD      fs/partitions/built-in.o
  CC      fs/proc/mmu.o
  CC      fs/proc/task_mmu.o
  CC      fs/proc/inode.o
  CC      fs/proc/root.o
  CC      fs/proc/base.o
  CC      fs/proc/generic.o
  CC      fs/proc/array.o
  CC      fs/proc/kmsg.o
  CC      fs/proc/proc_tty.o
  CC      fs/proc/proc_misc.o
  CC      fs/proc/kcore.o
  LD      fs/proc/proc.o
  LD      fs/proc/built-in.o
  LD      fs/qnx4/built-in.o
  CC      fs/ramfs/inode.o
  LD      fs/ramfs/ramfs.o
  LD      fs/ramfs/built-in.o
  LD      fs/reiserfs/built-in.o
  LD      fs/romfs/built-in.o
  LD      fs/smbfs/built-in.o
  CC      fs/sysfs/inode.o
  CC      fs/sysfs/file.o
  CC      fs/sysfs/dir.o
  CC      fs/sysfs/symlink.o
  CC      fs/sysfs/mount.o
  CC      fs/sysfs/bin.o
  CC      fs/sysfs/group.o
  LD      fs/sysfs/built-in.o
  LD      fs/sysv/built-in.o
  LD      fs/udf/built-in.o
  LD      fs/ufs/built-in.o
  LD      fs/vfat/built-in.o
  LD      fs/xfs/built-in.o
  LD      fs/built-in.o
  CC      ipc/compat.o
  CC      ipc/util.o
  CC      ipc/msgutil.o
  CC      ipc/msg.o
  CC      ipc/sem.o
  CC      ipc/shm.o
  LD      ipc/built-in.o
  CC      security/security.o
  CC      security/dummy.o
  CC      security/selinux/avc.o
  CC      security/selinux/hooks.o
  CC      security/selinux/selinuxfs.o
  CC      security/selinux/netlink.o
  CC      security/selinux/nlmsgtab.o
  CC      security/selinux/netif.o
  LD      security/selinux/selinux.o
  CC      security/selinux/ss/ebitmap.o
  CC      security/selinux/ss/hashtab.o
  CC      security/selinux/ss/symtab.o
  CC      security/selinux/ss/sidtab.o
  CC      security/selinux/ss/avtab.o
  CC      security/selinux/ss/policydb.o
  CC      security/selinux/ss/services.o
  CC      security/selinux/ss/conditional.o
  LD      security/selinux/ss/ss.o
  LD      security/selinux/ss/built-in.o
  LD      security/selinux/built-in.o
  CC      security/commoncap.o
  CC      security/capability.o
  LD      security/built-in.o
  CC      crypto/api.o
  CC      crypto/scatterwalk.o
  CC      crypto/cipher.o
  CC      crypto/digest.o
  CC      crypto/compress.o
  CC      crypto/proc.o
  CC      crypto/hmac.o
  CC      crypto/md5.o
  LD      crypto/built-in.o
  CC      drivers/acpi/tables.o
  CC      drivers/acpi/blacklist.o
  CC      drivers/acpi/osl.o
  CC      drivers/acpi/utils.o
  CC      drivers/acpi/dispatcher/dsfield.o
  CC      drivers/acpi/dispatcher/dsmthdat.o
  CC      drivers/acpi/dispatcher/dsopcode.o
  CC      drivers/acpi/dispatcher/dswexec.o
  CC      drivers/acpi/dispatcher/dswscope.o
  CC      drivers/acpi/dispatcher/dsmethod.o
  CC      drivers/acpi/dispatcher/dsobject.o
  CC      drivers/acpi/dispatcher/dsutils.o
  CC      drivers/acpi/dispatcher/dswload.o
  CC      drivers/acpi/dispatcher/dswstate.o
  CC      drivers/acpi/dispatcher/dsinit.o
  LD      drivers/acpi/dispatcher/built-in.o
  CC      drivers/acpi/events/evevent.o
  CC      drivers/acpi/events/evregion.o
  CC      drivers/acpi/events/evsci.o
  CC      drivers/acpi/events/evxfevnt.o
  CC      drivers/acpi/events/evmisc.o
  CC      drivers/acpi/events/evrgnini.o
  CC      drivers/acpi/events/evxface.o
  CC      drivers/acpi/events/evxfregn.o
  CC      drivers/acpi/events/evgpe.o
  CC      drivers/acpi/events/evgpeblk.o
  LD      drivers/acpi/events/built-in.o
  CC      drivers/acpi/executer/exconfig.o
  CC      drivers/acpi/executer/exfield.o
  CC      drivers/acpi/executer/exnames.o
  CC      drivers/acpi/executer/exoparg6.o
  CC      drivers/acpi/executer/exresolv.o
  CC      drivers/acpi/executer/exstorob.o
  CC      drivers/acpi/executer/exconvrt.o
  CC      drivers/acpi/executer/exfldio.o
  CC      drivers/acpi/executer/exoparg1.o
  CC      drivers/acpi/executer/exprep.o
  CC      drivers/acpi/executer/exresop.o
  CC      drivers/acpi/executer/exsystem.o
  CC      drivers/acpi/executer/excreate.o
  CC      drivers/acpi/executer/exmisc.o
  CC      drivers/acpi/executer/exoparg2.o
  CC      drivers/acpi/executer/exregion.o
  CC      drivers/acpi/executer/exstore.o
  CC      drivers/acpi/executer/exutils.o
  CC      drivers/acpi/executer/exdump.o
  CC      drivers/acpi/executer/exmutex.o
  CC      drivers/acpi/executer/exoparg3.o
  CC      drivers/acpi/executer/exresnte.o
  CC      drivers/acpi/executer/exstoren.o
  LD      drivers/acpi/executer/built-in.o
  CC      drivers/acpi/hardware/hwacpi.o
  CC      drivers/acpi/hardware/hwgpe.o
  CC      drivers/acpi/hardware/hwregs.o
  CC      drivers/acpi/hardware/hwsleep.o
  LD      drivers/acpi/hardware/built-in.o
  CC      drivers/acpi/namespace/nsaccess.o
  CC      drivers/acpi/namespace/nsload.o
  CC      drivers/acpi/namespace/nssearch.o
  CC      drivers/acpi/namespace/nsxfeval.o
  CC      drivers/acpi/namespace/nsalloc.o
  CC      drivers/acpi/namespace/nseval.o
  CC      drivers/acpi/namespace/nsnames.o
  CC      drivers/acpi/namespace/nsutils.o
  CC      drivers/acpi/namespace/nsxfname.o
  CC      drivers/acpi/namespace/nsdump.o
  CC      drivers/acpi/namespace/nsinit.o
  CC      drivers/acpi/namespace/nsobject.o
  CC      drivers/acpi/namespace/nswalk.o
  CC      drivers/acpi/namespace/nsxfobj.o
  CC      drivers/acpi/namespace/nsparse.o
  LD      drivers/acpi/namespace/built-in.o
  CC      drivers/acpi/parser/psargs.o
  CC      drivers/acpi/parser/psparse.o
  CC      drivers/acpi/parser/pstree.o
  CC      drivers/acpi/parser/pswalk.o
  CC      drivers/acpi/parser/psopcode.o
  CC      drivers/acpi/parser/psscope.o
  CC      drivers/acpi/parser/psutils.o
  CC      drivers/acpi/parser/psxface.o
  LD      drivers/acpi/parser/built-in.o
  CC      drivers/acpi/resources/rsaddr.o
  CC      drivers/acpi/resources/rscreate.o
  CC      drivers/acpi/resources/rsio.o
  CC      drivers/acpi/resources/rslist.o
  CC      drivers/acpi/resources/rsmisc.o
  CC      drivers/acpi/resources/rsxface.o
  CC      drivers/acpi/resources/rscalc.o
  CC      drivers/acpi/resources/rsirq.o
  CC      drivers/acpi/resources/rsmemory.o
  CC      drivers/acpi/resources/rsutils.o
  LD      drivers/acpi/resources/built-in.o
  CC      drivers/acpi/sleep/poweroff.o
  CC      drivers/acpi/sleep/wakeup.o
  LD      drivers/acpi/sleep/built-in.o
  CC      drivers/acpi/tables/tbconvrt.o
  CC      drivers/acpi/tables/tbget.o
  CC      drivers/acpi/tables/tbrsdt.o
  CC      drivers/acpi/tables/tbxface.o
  CC      drivers/acpi/tables/tbgetall.o
  CC      drivers/acpi/tables/tbinstal.o
  CC      drivers/acpi/tables/tbutils.o
  CC      drivers/acpi/tables/tbxfroot.o
  LD      drivers/acpi/tables/built-in.o
  CC      drivers/acpi/utilities/utalloc.o
  CC      drivers/acpi/utilities/utdebug.o
  CC      drivers/acpi/utilities/uteval.o
  CC      drivers/acpi/utilities/utinit.o
  CC      drivers/acpi/utilities/utmisc.o
  CC      drivers/acpi/utilities/utxface.o
  CC      drivers/acpi/utilities/utcopy.o
  CC      drivers/acpi/utilities/utdelete.o
  CC      drivers/acpi/utilities/utglobal.o
  CC      drivers/acpi/utilities/utmath.o
  CC      drivers/acpi/utilities/utobject.o
  LD      drivers/acpi/utilities/built-in.o
  CC      drivers/acpi/bus.o
  CC      drivers/acpi/ec.o
  CC      drivers/acpi/pci_root.o
  CC      drivers/acpi/pci_link.o
  CC      drivers/acpi/pci_irq.o
  CC      drivers/acpi/pci_bind.o
  CC      drivers/acpi/power.o
  CC      drivers/acpi/system.o
  CC      drivers/acpi/event.o
  CC      drivers/acpi/scan.o
  CC      drivers/acpi/motherboard.o
  LD      drivers/acpi/built-in.o
  CC      drivers/base/core.o
  CC      drivers/base/sys.o
  CC      drivers/base/interface.o
  CC      drivers/base/bus.o
  CC      drivers/base/driver.o
  CC      drivers/base/class.o
  CC      drivers/base/class_simple.o
  CC      drivers/base/platform.o
  CC      drivers/base/cpu.o
  CC      drivers/base/firmware.o
  CC      drivers/base/init.o
  CC      drivers/base/map.o
  CC      drivers/base/dmapool.o
  CC      drivers/base/attribute_container.o
  CC      drivers/base/transport_class.o
  CC      drivers/base/power/shutdown.o
  CC      drivers/base/power/main.o
  CC      drivers/base/power/suspend.o
  CC      drivers/base/power/resume.o
  CC      drivers/base/power/runtime.o
  CC      drivers/base/power/sysfs.o
  LD      drivers/base/power/built-in.o
  LD      drivers/base/built-in.o
  CC      drivers/block/elevator.o
  CC      drivers/block/ll_rw_blk.o
  CC      drivers/block/ioctl.o
  CC      drivers/block/genhd.o
  CC      drivers/block/scsi_ioctl.o
  CC      drivers/block/noop-iosched.o
  CC      drivers/block/as-iosched.o
  CC      drivers/block/deadline-iosched.o
  CC      drivers/block/cfq-iosched.o
  CC      drivers/block/rd.o
  LD      drivers/block/built-in.o
  LD      drivers/block/paride/built-in.o
  LD      drivers/bluetooth/built-in.o
  LD      drivers/cdrom/built-in.o
  CC      drivers/char/mem.o
  CC      drivers/char/random.o
  CC      drivers/char/tty_io.o
  CC      drivers/char/n_tty.o
  CC      drivers/char/tty_ioctl.o
  CC      drivers/char/pty.o
  CC      drivers/char/misc.o
  CC      drivers/char/vt_ioctl.o
  CC      drivers/char/vc_screen.o
  CC      drivers/char/consolemap.o
  CONMK   drivers/char/consolemap_deftbl.c
  CC      drivers/char/consolemap_deftbl.o
  CC      drivers/char/selection.o
  CC      drivers/char/keyboard.o
  CC      drivers/char/vt.o
drivers/char/vt.c: In function `vc_allocate':
drivers/char/vt.c:747: warning: `pm_register' is deprecated (declared at include/linux/pm.h:106)
  SHIPPED drivers/char/defkeymap.c
  CC      drivers/char/defkeymap.o
  CC      drivers/char/sysrq.o
  CC      drivers/char/blocker.o
  CC      drivers/char/hpet.o
  CC      drivers/char/agp/backend.o
  CC      drivers/char/agp/frontend.o
  CC      drivers/char/agp/generic.o
  CC      drivers/char/agp/isoch.o
  LD      drivers/char/agp/agpgart.o
  CC      drivers/char/agp/amd64-agp.o
  LD      drivers/char/agp/built-in.o
  CC      drivers/char/drm/drm_auth.o
  CC      drivers/char/drm/drm_bufs.o
  CC      drivers/char/drm/drm_context.o
  CC      drivers/char/drm/drm_dma.o
  CC      drivers/char/drm/drm_drawable.o
  CC      drivers/char/drm/drm_drv.o
  CC      drivers/char/drm/drm_fops.o
  CC      drivers/char/drm/drm_init.o
  CC      drivers/char/drm/drm_ioctl.o
  CC      drivers/char/drm/drm_irq.o
  CC      drivers/char/drm/drm_lock.o
  CC      drivers/char/drm/drm_memory.o
  CC      drivers/char/drm/drm_proc.o
  CC      drivers/char/drm/drm_stub.o
  CC      drivers/char/drm/drm_vm.o
  CC      drivers/char/drm/drm_agpsupport.o
  CC      drivers/char/drm/drm_scatter.o
  CC      drivers/char/drm/ati_pcigart.o
  CC      drivers/char/drm/drm_pci.o
  CC      drivers/char/drm/drm_sysfs.o
  LD      drivers/char/drm/drm.o
  LD      drivers/char/drm/built-in.o
  LD      drivers/char/ftape/compressor/built-in.o
  LD      drivers/char/ftape/lowlevel/built-in.o
  LD      drivers/char/ftape/zftape/built-in.o
  LD      drivers/char/ipmi/built-in.o
  LD      drivers/char/mwave/built-in.o
  LD      drivers/char/pcmcia/built-in.o
  LD      drivers/char/watchdog/built-in.o
  LD      drivers/char/built-in.o
  CC      drivers/cpufreq/cpufreq.o
  CC      drivers/cpufreq/cpufreq_performance.o
  LD      drivers/cpufreq/built-in.o
  LD      drivers/crypto/built-in.o
  LD      drivers/firmware/built-in.o
  LD      drivers/i2c/algos/built-in.o
  LD      drivers/i2c/busses/built-in.o
  LD      drivers/i2c/chips/built-in.o
  LD      drivers/i2c/built-in.o
  LD      drivers/ide/built-in.o
  LD      drivers/ide/arm/built-in.o
  LD      drivers/ide/legacy/built-in.o
  LD      drivers/ide/pci/built-in.o
  LD      drivers/ieee1394/built-in.o
  CC      drivers/input/input.o
  LD      drivers/input/joystick/built-in.o
  LD      drivers/input/joystick/iforce/built-in.o
  CC      drivers/input/keyboard/atkbd.o
  LD      drivers/input/keyboard/built-in.o
  LD      drivers/input/misc/built-in.o
  LD      drivers/input/mouse/built-in.o
  LD      drivers/input/touchscreen/built-in.o
  LD      drivers/input/built-in.o
  LD      drivers/input/gameport/built-in.o
  CC      drivers/input/serio/serio.o
  CC      drivers/input/serio/i8042.o
  CC      drivers/input/serio/libps2.o
  LD      drivers/input/serio/built-in.o
  LD      drivers/isdn/built-in.o
  LD      drivers/isdn/capi/built-in.o
  LD      drivers/isdn/divert/built-in.o
  LD      drivers/isdn/hardware/avm/built-in.o
  LD      drivers/isdn/hardware/eicon/built-in.o
  LD      drivers/isdn/hardware/built-in.o
  LD      drivers/isdn/hisax/built-in.o
  LD      drivers/isdn/hysdn/built-in.o
  LD      drivers/isdn/i4l/built-in.o
  LD      drivers/isdn/isdnloop/built-in.o
  LD      drivers/md/built-in.o
  LD      drivers/media/common/built-in.o
  LD      drivers/media/dvb/b2c2/built-in.o
  LD      drivers/media/dvb/bt8xx/built-in.o
  LD      drivers/media/dvb/cinergyT2/built-in.o
  LD      drivers/media/dvb/dibusb/built-in.o
  LD      drivers/media/dvb/dvb-core/built-in.o
  LD      drivers/media/dvb/frontends/built-in.o
  LD      drivers/media/dvb/ttpci/built-in.o
  LD      drivers/media/dvb/ttusb-budget/built-in.o
  LD      drivers/media/dvb/ttusb-dec/built-in.o
  LD      drivers/media/dvb/built-in.o
  LD      drivers/media/radio/built-in.o
  LD      drivers/media/video/built-in.o
  LD      drivers/media/video/ovcamchip/built-in.o
  LD      drivers/media/video/saa7134/built-in.o
  LD      drivers/media/built-in.o
  LD      drivers/message/fusion/built-in.o
  LD      drivers/message/i2o/built-in.o
  LD      drivers/misc/built-in.o
  LD      drivers/mmc/built-in.o
  LD      drivers/mtd/chips/built-in.o
  LD      drivers/mtd/devices/built-in.o
  LD      drivers/mtd/maps/built-in.o
  LD      drivers/mtd/nand/built-in.o
  LD      drivers/mtd/built-in.o
  CC      drivers/net/Space.o
  CC      drivers/net/loopback.o
  LD      drivers/net/appletalk/built-in.o
  LD      drivers/net/arcnet/built-in.o
  LD      drivers/net/bonding/built-in.o
  LD      drivers/net/e1000/built-in.o
  LD      drivers/net/fc/built-in.o
  LD      drivers/net/hamradio/built-in.o
  LD      drivers/net/irda/built-in.o
  LD      drivers/net/ixgb/built-in.o
  LD      drivers/net/pcmcia/built-in.o
  LD      drivers/net/sk98lin/built-in.o
  LD      drivers/net/skfp/built-in.o
  LD      drivers/net/tokenring/built-in.o
  LD      drivers/net/tulip/built-in.o
  LD      drivers/net/wan/built-in.o
  LD      drivers/net/wan/lmc/built-in.o
  LD      drivers/net/wireless/built-in.o
  LD      drivers/net/built-in.o
  LD      drivers/parport/built-in.o
  CC      drivers/pci/access.o
  CC      drivers/pci/bus.o
  CC      drivers/pci/probe.o
  CC      drivers/pci/remove.o
  CC      drivers/pci/pci.o
  CC      drivers/pci/quirks.o
  HOSTCC  drivers/pci/gen-devlist
  DEVLIST drivers/pci/devlist.h
  CC      drivers/pci/names.o
  CC      drivers/pci/pci-driver.o
  CC      drivers/pci/search.o
  CC      drivers/pci/pci-sysfs.o
  CC      drivers/pci/rom.o
  CC      drivers/pci/proc.o
  CC      drivers/pci/setup-res.o
  CC      drivers/pci/hotplug.o
  CC      drivers/pci/pci-acpi.o
  CC      drivers/pci/setup-bus.o
  LD      drivers/pci/built-in.o
  LD      drivers/pcmcia/built-in.o
  LD      drivers/scsi/aacraid/built-in.o
  LD      drivers/scsi/aic7xxx/built-in.o
  LD      drivers/scsi/megaraid/built-in.o
  LD      drivers/scsi/pcmcia/built-in.o
  LD      drivers/scsi/qla2xxx/built-in.o
  LD      drivers/scsi/sym53c8xx_2/built-in.o
  LD      drivers/scsi/built-in.o
  CC      drivers/serial/serial_core.o
  CC      drivers/serial/8250.o
  CC      drivers/serial/8250_pci.o
  CC      drivers/serial/8250_early.o
  LD      drivers/serial/built-in.o
  LD      drivers/telephony/built-in.o
  LD      drivers/usb/class/built-in.o
  CC      drivers/usb/core/usb.o
  CC      drivers/usb/core/hub.o
  CC      drivers/usb/core/hcd.o
  CC      drivers/usb/core/urb.o
  CC      drivers/usb/core/message.o
  CC      drivers/usb/core/config.o
  CC      drivers/usb/core/file.o
  CC      drivers/usb/core/buffer.o
  CC      drivers/usb/core/sysfs.o
  CC      drivers/usb/core/hcd-pci.o
  CC      drivers/usb/core/devio.o
  CC      drivers/usb/core/inode.o
  CC      drivers/usb/core/devices.o
  LD      drivers/usb/core/usbcore.o
  LD      drivers/usb/core/built-in.o
  LD      drivers/usb/host/built-in.o
  LD      drivers/usb/image/built-in.o
  LD      drivers/usb/input/built-in.o
  LD      drivers/usb/media/built-in.o
  LD      drivers/usb/misc/built-in.o
  LD      drivers/usb/net/built-in.o
  LD      drivers/usb/serial/built-in.o
  LD      drivers/usb/storage/built-in.o
  LD      drivers/usb/built-in.o
  LD      drivers/usb/gadget/built-in.o
  LD      drivers/video/aty/built-in.o
  LD      drivers/video/backlight/built-in.o
  CC      drivers/video/console/dummycon.o
  CC      drivers/video/console/vgacon.o
  CC      drivers/video/console/tileblit.o
  LD      drivers/video/console/built-in.o
  LD      drivers/video/kyro/built-in.o
  LD      drivers/video/matrox/built-in.o
  LD      drivers/video/riva/built-in.o
  LD      drivers/video/sis/built-in.o
  CC      drivers/video/fbmem.o
  CC      drivers/video/fbmon.o
  CC      drivers/video/fbcmap.o
  CC      drivers/video/fbsysfs.o
  CC      drivers/video/modedb.o
  CC      drivers/video/softcursor.o
  LD      drivers/video/built-in.o
  LD      drivers/w1/built-in.o
  LD      drivers/built-in.o
  LD      sound/built-in.o
  LD      sound/arm/built-in.o
  LD      sound/core/ioctl32/built-in.o
  LD      sound/core/oss/built-in.o
  LD      sound/core/seq/built-in.o
  LD      sound/core/seq/instr/built-in.o
  LD      sound/core/seq/oss/built-in.o
  LD      sound/core/built-in.o
  LD      sound/drivers/built-in.o
  LD      sound/drivers/mpu401/built-in.o
  LD      sound/drivers/opl3/built-in.o
  LD      sound/drivers/opl4/built-in.o
  LD      sound/drivers/vx/built-in.o
  LD      sound/i2c/built-in.o
  LD      sound/i2c/other/built-in.o
  LD      sound/isa/built-in.o
  LD      sound/isa/ad1816a/built-in.o
  LD      sound/isa/ad1848/built-in.o
  LD      sound/isa/cs423x/built-in.o
  LD      sound/isa/es1688/built-in.o
  LD      sound/isa/gus/built-in.o
  LD      sound/isa/opti9xx/built-in.o
  LD      sound/isa/sb/built-in.o
  LD      sound/isa/wavefront/built-in.o
  LD      sound/mips/built-in.o
  LD      sound/oss/built-in.o
  LD      sound/oss/cs4281/built-in.o
  LD      sound/oss/emu10k1/built-in.o
  LD      sound/parisc/built-in.o
  LD      sound/pci/built-in.o
  LD      sound/pci/ac97/built-in.o
  LD      sound/pci/ali5451/built-in.o
  LD      sound/pci/au88x0/built-in.o
  LD      sound/pci/ca0106/built-in.o
  LD      sound/pci/cs46xx/built-in.o
  LD      sound/pci/emu10k1/built-in.o
  LD      sound/pci/ice1712/built-in.o
  LD      sound/pci/korg1212/built-in.o
  LD      sound/pci/mixart/built-in.o
  LD      sound/pci/nm256/built-in.o
  LD      sound/pci/rme9652/built-in.o
  LD      sound/pci/trident/built-in.o
  LD      sound/pci/vx222/built-in.o
  LD      sound/pci/ymfpci/built-in.o
  LD      sound/pcmcia/pdaudiocf/built-in.o
  LD      sound/pcmcia/vx/built-in.o
  LD      sound/ppc/built-in.o
  LD      sound/sparc/built-in.o
  LD      sound/synth/built-in.o
  LD      sound/synth/emux/built-in.o
  LD      sound/usb/built-in.o
  LD      sound/usb/usx2y/built-in.o
  CC      arch/x86_64/pci/../../i386/pci/acpi.o
  CC      arch/x86_64/pci/../../i386/pci/common.o
  CC      arch/x86_64/pci/../../i386/pci/direct.o
  CC      arch/x86_64/pci/../../i386/pci/fixup.o
  CC      arch/x86_64/pci/../../i386/pci/i386.o
  CC      arch/x86_64/pci/../../i386/pci/irq.o
  CC      arch/x86_64/pci/../../i386/pci/legacy.o
  LD      arch/x86_64/pci/i386.o
  LD      arch/x86_64/pci/direct.o
  LD      arch/x86_64/pci/fixup.o
  LD      arch/x86_64/pci/acpi.o
  LD      arch/x86_64/pci/legacy.o
  LD      arch/x86_64/pci/irq.o
  LD      arch/x86_64/pci/common.o
  CC      arch/x86_64/pci/mmconfig.o
  LD      arch/x86_64/pci/built-in.o
  CC      net/socket.o
  CC      net/802/p8023.o
  CC      net/802/sysctl_net_802.o
  CC      net/802/p8022.o
  CC      net/802/psnap.o
  CC      net/802/tr.o
  CC      net/802/fc.o
  CC      net/802/fddi.o
  LD      net/802/built-in.o
  LD      net/8021q/built-in.o
  LD      net/appletalk/built-in.o
  LD      net/ax25/built-in.o
  LD      net/bluetooth/built-in.o
  LD      net/bluetooth/bnep/built-in.o
  LD      net/bluetooth/cmtp/built-in.o
  LD      net/bluetooth/hidp/built-in.o
  LD      net/bluetooth/rfcomm/built-in.o
  LD      net/bridge/built-in.o
  LD      net/bridge/netfilter/built-in.o
  CC      net/core/sock.o
  CC      net/core/skbuff.o
  CC      net/core/iovec.o
  CC      net/core/datagram.o
  CC      net/core/stream.o
  CC      net/core/scm.o
  CC      net/core/gen_stats.o
  CC      net/core/gen_estimator.o
  CC      net/core/sysctl_net_core.o
  CC      net/core/flow.o
  CC      net/core/dev.o
  CC      net/core/ethtool.o
  CC      net/core/dev_mcast.o
  CC      net/core/dst.o
  CC      net/core/neighbour.o
  CC      net/core/rtnetlink.o
  CC      net/core/utils.o
  CC      net/core/link_watch.o
  CC      net/core/filter.o
  CC      net/core/net-sysfs.o
  CC      net/core/netfilter.o
  CC      net/core/wireless.o
  LD      net/core/built-in.o
  LD      net/decnet/netfilter/built-in.o
  LD      net/decnet/built-in.o
  CC      net/ethernet/eth.o
  CC      net/ethernet/sysctl_net_ether.o
  CC      net/ethernet/pe2.o
  LD      net/ethernet/built-in.o
  CC      net/ipv4/utils.o
  CC      net/ipv4/route.o
  CC      net/ipv4/inetpeer.o
  CC      net/ipv4/protocol.o
  CC      net/ipv4/ip_input.o
  CC      net/ipv4/ip_fragment.o
  CC      net/ipv4/ip_forward.o
  CC      net/ipv4/ip_options.o
  CC      net/ipv4/ip_output.o
  CC      net/ipv4/ip_sockglue.o
  CC      net/ipv4/tcp.o
  CC      net/ipv4/tcp_input.o
  CC      net/ipv4/tcp_output.o
  CC      net/ipv4/tcp_timer.o
  CC      net/ipv4/tcp_ipv4.o
  CC      net/ipv4/tcp_minisocks.o
  CC      net/ipv4/datagram.o
  CC      net/ipv4/raw.o
  CC      net/ipv4/udp.o
  CC      net/ipv4/arp.o
  CC      net/ipv4/icmp.o
  CC      net/ipv4/devinet.o
  CC      net/ipv4/af_inet.o
  CC      net/ipv4/igmp.o
  CC      net/ipv4/sysctl_net_ipv4.o
  CC      net/ipv4/fib_frontend.o
  CC      net/ipv4/fib_semantics.o
  CC      net/ipv4/fib_hash.o
  CC      net/ipv4/proc.o
  CC      net/ipv4/fib_rules.o
  CC      net/ipv4/ipmr.o
  CC      net/ipv4/syncookies.o
  LD      net/ipv4/ipvs/built-in.o
  LD      net/ipv4/netfilter/built-in.o
  CC      net/ipv4/xfrm4_policy.o
  CC      net/ipv4/xfrm4_state.o
  CC      net/ipv4/xfrm4_input.o
  CC      net/ipv4/xfrm4_output.o
  LD      net/ipv4/built-in.o
  LD      net/ipx/built-in.o
  LD      net/irda/built-in.o
  LD      net/irda/ircomm/built-in.o
  LD      net/irda/irlan/built-in.o
  LD      net/irda/irnet/built-in.o
  LD      net/key/built-in.o
  CC      net/llc/llc_core.o
  CC      net/llc/llc_input.o
  CC      net/llc/llc_output.o
  LD      net/llc/llc.o
  LD      net/llc/built-in.o
  CC      net/netlink/af_netlink.o
  LD      net/netlink/built-in.o
  LD      net/netrom/built-in.o
  LD      net/packet/built-in.o
  LD      net/rose/built-in.o
  CC      net/sched/sch_generic.o
  CC      net/sched/sch_api.o
  CC      net/sched/sch_fifo.o
  CC      net/sched/cls_api.o
  CC      net/sched/police.o
  LD      net/sched/built-in.o
  LD      net/sunrpc/built-in.o
  LD      net/unix/built-in.o
  CC      net/xfrm/xfrm_policy.o
  CC      net/xfrm/xfrm_state.o
  CC      net/xfrm/xfrm_input.o
  CC      net/xfrm/xfrm_algo.o
  CC      net/xfrm/xfrm_export.o
  LD      net/xfrm/built-in.o
  CC      net/compat.o
  CC      net/sysctl_net.o
  LD      net/built-in.o
  CC      lib/kernel_lock.o
  HOSTCC  lib/gen_crc32table
  GEN     lib/crc32table.h
  CC      lib/crc32.o
  CC      lib/iomap.o
  LD      lib/zlib_deflate/built-in.o
  CC      lib/zlib_inflate/infblock.o
  CC      lib/zlib_inflate/infcodes.o
  CC      lib/zlib_inflate/inffast.o
  CC      lib/zlib_inflate/inflate.o
  CC      lib/zlib_inflate/inflate_sync.o
  CC      lib/zlib_inflate/inftrees.o
  CC      lib/zlib_inflate/infutil.o
  CC      lib/zlib_inflate/inflate_syms.o
  LD      lib/zlib_inflate/zlib_inflate.o
  LD      lib/zlib_inflate/built-in.o
  LD      lib/built-in.o
  CC      lib/bitmap.o
  CC      lib/bust_spinlocks.o
  CC      lib/cmdline.o
  CC      lib/ctype.o
  CC      lib/dec_and_lock.o
  CC      lib/div64.o
  CC      lib/dump_stack.o
  CC      lib/errno.o
  CC      lib/extable.o
  CC      lib/idr.o
  CC      lib/int_sqrt.o
  CC      lib/kobject.o
  CC      lib/kobject_uevent.o
  CC      lib/kref.o
  CC      lib/parser.o
  CC      lib/prio_tree.o
  CC      lib/radix-tree.o
  CC      lib/rbtree.o
  CC      lib/string.o
  CC      lib/vsprintf.o
  AR      lib/lib.a
  CC      arch/x86_64/lib/io.o
  LD      arch/x86_64/lib/built-in.o
  CC      arch/x86_64/lib/bitops.o
  CC      arch/x86_64/lib/bitstr.o
  AS      arch/x86_64/lib/clear_page.o
  AS      arch/x86_64/lib/copy_page.o
  AS      arch/x86_64/lib/copy_user.o
  AS      arch/x86_64/lib/csum-copy.o
  CC      arch/x86_64/lib/csum-partial.o
  CC      arch/x86_64/lib/csum-wrappers.o
  CC      arch/x86_64/lib/delay.o
  AS      arch/x86_64/lib/getuser.o
  AS      arch/x86_64/lib/memcpy.o
  CC      arch/x86_64/lib/memmove.o
  AS      arch/x86_64/lib/memset.o
  AS      arch/x86_64/lib/putuser.o
  AS      arch/x86_64/lib/thunk.o
  CC      arch/x86_64/lib/usercopy.o
  AR      arch/x86_64/lib/lib.a
  GEN     .version
  CHK     include/linux/compile.h
  UPD     include/linux/compile.h
  CC      init/version.o
  LD      init/built-in.o
  LD      .tmp_vmlinux1
ld: BFD 2.15 assertion fail ../../bfd/linker.c:619
kernel/built-in.o(.text+0x1f259): In function `__trace_start_sched_wakeup':
: undefined reference to `_trace_cmdline'
make: *** [.tmp_vmlinux1] Error 1
bathory4:/usr/src/linux#
/*
 *  kernel/latency.c
 *
 *  Copyright (C) 2004 Ingo Molnar
 *  Copyright (C) 2004 William Lee Irwin III
 */

#include <linux/mm.h>
#include <linux/nmi.h>
#include <linux/sched.h>
#include <linux/percpu.h>
#include <linux/config.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/proc_fs.h>
#include <asm/rtc.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>

#ifdef __i386__
static inline cycles_t cycles(void)
{
        unsigned long long ret;

        rdtscll(ret);

        return ret;
}
#else
# define cycles() get_cycles()
#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

#ifdef CONFIG_LATENCY_TIMING

/*
 * Maximum preemption latency measured. Initialize to maximum,
 * we clear it after bootup.
 */
static cycles_t preempt_max_latency = (cycles_t)ULONG_MAX;
static cycles_t preempt_thresh;

/*
 * Should this new latency be reported/recorded?
 */
static int report_latency(cycles_t delta)
{
	if (preempt_thresh) {
		if (delta < preempt_thresh)
			return 0;
	} else {
		if (delta <= preempt_max_latency)
			return 0;
	}
	return 1;
}

/*
 * Track maximum latencies and save the trace:
 */
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 int max_sequence;

enum trace_type
{
	__TRACE_FIRST_TYPE = 0,

	TRACE_FN,
	TRACE_SPECIAL,
	TRACE_SPECIAL_PID,
	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_HARDIRQ		= 0x04,
	TRACE_FLAG_SOFTIRQ		= 0x08,
};


#ifdef CONFIG_LATENCY_TRACE

#define MAX_TRACE (unsigned long)(4096-1)

#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;
	cycles_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 int nr;
			unsigned long p1, p2, p3;
		} syscall;
		struct {
			unsigned int ret;
		} sysret;
		struct {
			int __pad3[4];
		} pad;
	} u;
} __attribute__((packed));

#endif

struct cpu_trace {
	atomic_t disabled;
	unsigned long trace_idx;
	cycles_t preempt_timestamp;
	unsigned long critical_start, critical_end;
	int critical_sequence;
	int early_warning;

#ifdef CONFIG_LATENCY_TRACE
	struct trace_entry trace[MAX_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

} ____cacheline_aligned_in_smp;

static struct cpu_trace cpu_traces[NR_CPUS] ____cacheline_aligned_in_smp;

static unsigned long notrace cycles_to_usecs(cycles_t delta)
{
#ifdef CONFIG_X86
	do_div(delta, cpu_khz/1000+1);
#elif defined(CONFIG_PPC)
	delta = mulhwu(tb_to_us, delta);
#else
	#error Implement cycles_to_usecs.
#endif

	return (unsigned long) delta;
}

static cycles_t notrace usecs_to_cycles(unsigned long delta)
{
	return (cycles_t) delta * (cycles_t) (cpu_khz/1000+1);
}

#ifdef CONFIG_LATENCY_TRACE

int trace_enabled = 1;
int mcount_enabled = 1;
int trace_freerunning = 0;
int trace_print_at_crash = 0;
int trace_verbose = 0;
int trace_all_cpus = 0;

/*
 * user-triggered via gettimeofday(0,1)/gettimeofday(0,0)
 */
int trace_user_triggered = 0;

struct saved_trace_struct {
	int cpu;
	cycles_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
____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)
{
	struct trace_entry *entry;

#ifdef CONFIG_DEBUG_PREEMPT
//	WARN_ON(!atomic_read(&tr->disabled));
#endif
#ifdef CONFIG_DEBUG_STACKOVERFLOW
	/* Debugging check for stack overflow: is there less than 1KB free? */
	{
		long esp;

		__asm__ __volatile__("andl %%esp,%0" :
					"=r" (esp) : "0" (THREAD_SIZE - 1));
		if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) {
			printk("BUG: mcount: stack overflow: %ld [%08lx...%08lx...%08lx]\n",
				esp - sizeof(struct thread_info), (long)&esp, (long)current_thread_info(), (long)current_thread_info() + THREAD_SIZE);
			dump_stack();
		}
	}
#endif

	if (likely(tr->critical_start) || unlikely(trace_user_triggered || trace_all_cpus))
	if (tr->trace_idx < MAX_TRACE) {
		u32 pc = preempt_count();

		entry = tr->trace + tr->trace_idx;
		entry->type = type;
#ifdef CONFIG_SMP
		entry->cpu = cpu;
#endif
		entry->flags = (irqs_disabled() ? TRACE_FLAG_IRQS_OFF : 0) |
			((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) |
			((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
			(_need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
		entry->preempt_count = pc & 0xff;
		entry->pid = current->pid;
		entry->timestamp = cycles();

		switch (type) {
		case TRACE_FN:
			entry->u.fn.eip = eip;
			entry->u.fn.parent_eip = parent_eip;
			break;
		case TRACE_SPECIAL:
		case TRACE_SPECIAL_PID:
			entry->u.special.eip = eip;
			entry->u.special.v1 = v1;
			entry->u.special.v2 = v2;
			entry->u.special.v3 = v3;
			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;
		}
	}
	tr->trace_idx++;
	if (unlikely(trace_freerunning && (tr->trace_idx >= MAX_TRACE)))
		tr->trace_idx = 0;
}

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)
{
	int cpu = _smp_processor_id();
	struct cpu_trace *tr;

	if (unlikely(trace_enabled <= 0))
		return;

	/*
	 * 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) {
		if (!sch.tr || cpu != sch.cpu)
			return;
		tr = sch.tr;
	} else
		tr = cpu_traces + cpu;
#else
	tr = cpu_traces + cpu;
#endif
	if (likely(!atomic_read(&tr->disabled))) {
		atomic_inc(&tr->disabled);
		____trace(cpu, type, tr, eip, parent_eip, v1, v2, v3);
		atomic_dec(&tr->disabled);
	}
}

/*
 * 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);

/*
 * Non-inlined function:
 */
void notrace __trace(unsigned long eip, unsigned long parent_eip)
{
	___trace(TRACE_FN, eip, parent_eip, 0, 0, 0);
}

extern void mcount(void);

EXPORT_SYMBOL(mcount);

void notrace __mcount(void)
{
	___trace(TRACE_FN, CALLER_ADDR1, CALLER_ADDR2, 0, 0, 0);
}

void notrace
sys_call(int nr, unsigned long p1, unsigned long p2, unsigned long p3)
{
	___trace(TRACE_SYSCALL, nr, 0, p1, p2, p3);
}

void notrace sys_ret(int ret)
{
	___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, "(%ld)", 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 int out_sequence = -1;
static int pid_to_cmdline_array[PID_MAX_DEFAULT+1];

static void notrace _trace_cmdline(int cpu, struct cpu_trace *tr)
{
	____trace(cpu, TRACE_CMDLINE, tr, 0, 0, 0, 0, 0);
}

void notrace trace_cmdline(void)
{
	___trace(TRACE_CMDLINE, 0, 0, 0, 0, 0);
}

static void construct_pid_to_cmdline(void)
{
	struct cpu_trace *tr = out_tr.traces;
	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));

	entries = min(tr->trace_idx, MAX_TRACE-1);

	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;
	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;
}

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)
{
	cycles_t min_stamp = (cycles_t) -1;
	struct trace_entry *entry;
	int cpu, min_cpu = -1, idx;

	for_each_online_cpu(cpu) {
		idx = bidx->idx[cpu];
		entry = max_tr.traces[cpu].trace + bidx->idx[cpu];
		if (idx > max_tr.traces[cpu].trace_idx)
			continue;
		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)
{
	int cpu, sum, entries;
	struct cpu_trace *tmp_max, *tmp_out;
	struct trace_entry *out_entry, *entry;
	struct block_idx bidx = { { 0, } };
	cycles_t stamp, first_stamp = 0, last_stamp = (cycles_t)-1;

	/*
	 * Nasty trick. We might overflow the first array but
	 * there are NR_CPUS of them so we use it as a 'big'
	 * trace buffer.
	 */
	tmp_out = out_tr.traces + 0;
	*tmp_out = max_tr.traces[max_tr.cpu];
	out_tr.cpu = max_tr.cpu;
	out_entry = tmp_out->trace + 0;

	if (!trace_all_cpus) {
		entries = min(tmp_out->trace_idx, MAX_TRACE-1);
		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.)
	 */
	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-1);
	/*
	 * No saved trace yet?
	 */
	if (!entries) {
		out_tr.traces[0].trace_idx = 0;
		return;
	}

	last_stamp = tmp_max->trace[entries-1].timestamp;

	WARN_ON(last_stamp < first_stamp);

	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++;
	}
	
	WARN_ON(sum > MAX_TRACE*NR_CPUS);
	tmp_out->trace_idx = sum;
}

static void * notrace l_start(struct seq_file *m, loff_t *pos)
{
	loff_t n = *pos;
	unsigned long entries;
	struct cpu_trace *tr;

	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 (!out_tr.traces[0].trace_idx) {
			up(&out_mutex);
			return NULL;
		}
		construct_pid_to_cmdline();
	}
	tr = out_tr.traces;
	entries = min(tr->trace_idx, MAX_TRACE);

	if (!n) {
		seq_printf(m, "preemption latency trace v1.1.4 on %s\n", UTS_RELEASE);
		seq_puts(m, "--------------------------------------------------------------------\n");
		seq_printf(m, " latency: %lu µs, #%lu/%lu, CPU#%d | (M:%s VP:%d, KP:%d, SP:%d HP:%d #P:%d)\n",
			cycles_to_usecs(tr->saved_latency),
			entries, tr->trace_idx, out_tr.cpu,
#if defined(CONFIG_PREEMPT_NONE)
			"server",
#elif defined(CONFIG_PREEMPT_VOLUNTARY)
			"desktop",
#elif defined(CONFIG_PREEMPT_DESKTOP)
			"preempt",
#else
			"rt",
#endif
			voluntary_preemption, kernel_preemption,
			softirq_preemption, hardirq_preemption,
			num_online_cpus());
		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");

		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");

	}
	if (n >= entries)
		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);

	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, " %4ldµs", 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, " %4ldµs", 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_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_usecs(entry->timestamp - entry0->timestamp);
	rel_usecs = cycles_to_usecs(next_entry->timestamp - entry->timestamp);

	if (trace_verbose) {
		seq_printf(m, "%16s %5d %d %d %08x %08lx [%016Lu] %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)
{
	unsigned long abs_usecs, rel_usecs;

	abs_usecs = cycles_to_usecs(entry->timestamp - entry0->timestamp);
	rel_usecs = cycles_to_usecs(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, " (%lx %lx %lx)\n",
		entry->u.special.v1, 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_usecs(entry->timestamp - entry0->timestamp);
	rel_usecs = cycles_to_usecs(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> (%lx %lx): ",
		pid_to_cmdline(pid), pid,
		entry->u.special.v2, 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_usecs(entry->timestamp - entry0->timestamp);
	rel_usecs = cycles_to_usecs(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];

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 int nr;

	abs_usecs = cycles_to_usecs(entry->timestamp - entry0->timestamp);
	rel_usecs = cycles_to_usecs(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 (nr < NR_syscalls)
		print_name(m, sys_call_table[entry->u.syscall.nr]);
	else
		seq_puts(m, "<badsys>");

	seq_printf(m, " (%08lx %08lx %08lx)\n",
		entry->u.syscall.p1, entry->u.syscall.p2, entry->u.syscall.p3);

	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_usecs(entry->timestamp - entry0->timestamp);
	rel_usecs = cycles_to_usecs(next_entry->timestamp - entry->timestamp);

	print_generic(m, entry);
	print_timestamp_short(m, abs_usecs, rel_usecs);

	seq_printf(m, "< (%d)\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;

	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);
			break;
		case TRACE_SPECIAL_PID:
			l_show_special_pid(m, trace_idx, entry, entry0, next_entry);
			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
};

static void copy_trace(struct cpu_trace *save, struct cpu_trace *tr)
{
	/* free-running needs reordering */
	if (trace_freerunning) {
		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-1;
	} else {
		save->trace_idx = tr->trace_idx;

		memcpy(save->trace, tr->trace,
			min(save->trace_idx + 1, MAX_TRACE) *
					sizeof(struct trace_entry));
	}
}

static void update_max_tr(struct cpu_trace *tr)
{
	struct cpu_trace *save;
	int this_cpu = smp_processor_id(), cpu, all_cpus = 0;

	WARN_ON(!preempt_count() && !irqs_disabled());

	max_tr.cpu = this_cpu;
	save = max_tr.traces + this_cpu;

	if ((wakeup_timing || trace_user_triggered) && 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);
			atomic_dec(&cpu_traces[cpu].disabled);
		}
	} else
		copy_trace(save, tr);
}

#else /* !LATENCY_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)
{
}

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)
{
}

#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 µs\n", thresh);
	}
	return 1;
}
__setup("preempt_thresh=", setup_preempt_thresh);

#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;
	cycles_t T1, T0, delta;

	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 = cycles();
	delta = T1-T0;

	if (!report_latency(delta))
		goto out;
	____trace(cpu, TRACE_FN, tr, CALLER_ADDR0, parent_eip, 0, 0, 0);
	/*
	 * Update the timestamp, because the trace entry above
	 * might change it (it can only get larger so the latency
	 * is fair to be reported):
	 */
	T1 = cycles();
	delta = T1-T0;

	if (tr->critical_sequence != max_sequence || down_trylock(&max_mutex))
		goto out;

	preempt_max_latency = delta;
	t0 = cycles_to_usecs(T0);
	t1 = cycles_to_usecs(T1);
	latency = cycles_to_usecs(delta);

	tr->critical_end = parent_eip;

	update_max_tr(tr);

	if (preempt_thresh)
		printk("(%16s-%-5d|#%d): %lu µs critical section "
			"violates %lu µs threshold.\n"
			" => started at timestamp %lu: ",
				current->comm, current->pid,
				_smp_processor_id(),
				latency, cycles_to_usecs(preempt_thresh), t0);
	else
		printk("(%16s-%-5d|#%d): new %lu µs maximum-latency "
			"critical section.\n => started at timestamp %lu: ",
				current->comm, current->pid,
				_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(cycles());
	printk(" =>   dump-end timestamp %lu\n\n", t1);

	max_sequence++;

	up(&max_mutex);
out:
	tr->critical_sequence = max_sequence;
	tr->preempt_timestamp = cycles();
	tr->early_warning = 0;
	tr->trace_idx = 0;
	_trace_cmdline(cpu, tr);
	____trace(cpu, TRACE_FN, tr, CALLER_ADDR0, parent_eip, 0, 0, 0);
}

void notrace touch_critical_timing(void)
{
	int cpu = _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 + _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 cpu = _smp_processor_id();
	struct cpu_trace *tr = cpu_traces + cpu;

	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 = cycles();
	tr->critical_start = eip;
	tr->trace_idx = 0;
	_trace_cmdline(cpu, tr);
	____trace(cpu, TRACE_FN, tr, eip, parent_eip, 0, 0, 0);

	atomic_dec(&tr->disabled);
}

static inline void notrace
__stop_critical_timing(unsigned long eip, unsigned long parent_eip)
{
	int cpu = _smp_processor_id();
	struct cpu_trace *tr = cpu_traces + cpu;

	if (!tr->critical_start || atomic_read(&tr->disabled) ||
			trace_user_triggered || wakeup_timing)
		return;

	atomic_inc(&tr->disabled);
	____trace(cpu, TRACE_FN, tr, eip, parent_eip, 0, 0, 0);
	check_critical_timing(cpu, tr, eip);
	tr->critical_start = 0;
	atomic_dec(&tr->disabled);
}

#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

void notrace trace_irqs_off_lowlevel(void)
{
	unsigned long flags;

	local_save_flags(flags);

	if (!irqs_off_preempt_count() && irqs_disabled_flags(flags))
		__start_critical_timing(CALLER_ADDR0, 0);
}

void notrace trace_irqs_off(void)
{
	unsigned long flags;

	local_save_flags(flags);

	if (!irqs_off_preempt_count() && irqs_disabled_flags(flags))
		__start_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
}

EXPORT_SYMBOL(trace_irqs_off);

void notrace trace_irqs_on(void)
{
	unsigned long flags;

	local_save_flags(flags);

	if (!irqs_off_preempt_count() && irqs_disabled_flags(flags))
		__stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
}

EXPORT_SYMBOL(trace_irqs_on);

#endif

#endif /* LATENCY_TIMING */

#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_CRITICAL_TIMING)

void notrace add_preempt_count(int val)
{
	unsigned long eip = CALLER_ADDR0;
	unsigned long parent_eip = CALLER_ADDR1;

#ifdef CONFIG_DEBUG_PREEMPT
	/*
	 * Underflow?
	 */
	BUG_ON(((int)preempt_count() < 0));
	/*
	 * Spinlock count overflowing soon?
	 */
	BUG_ON((preempt_count() & PREEMPT_MASK) >= PREEMPT_MASK-10);
#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);
	}
#endif
	(void)eip, (void)parent_eip;
}
EXPORT_SYMBOL(add_preempt_count);

void notrace sub_preempt_count(int val)
{
#ifdef CONFIG_DEBUG_PREEMPT
	/*
	 * Underflow?
	 */
	BUG_ON(unlikely(val > preempt_count()));

	/*
	 * Is the spinlock portion underflowing?
	 */
	BUG_ON((val < PREEMPT_MASK) && !(preempt_count() & PREEMPT_MASK));
#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);

#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 latency;
	unsigned long t0, t1;
	cycles_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 = cycles();
	delta = T1-T0;

	if (!report_latency(delta))
		goto out;

	____trace(smp_processor_id(), TRACE_FN, tr, CALLER_ADDR0, parent_eip, 0, 0, 0);
	T1 = cycles();
	delta = T1-T0;

	if (tr->critical_sequence != max_sequence || down_trylock(&max_mutex))
		goto out;

	preempt_max_latency = delta;
	t0 = cycles_to_usecs(T0);
	t1 = cycles_to_usecs(T1);
	latency = cycles_to_usecs(delta);

	tr->critical_end = parent_eip;

	update_max_tr(tr);

	if (preempt_thresh)
		printk("(%16s-%-5d|#%d): %lu µs wakeup latency "
			"violates %lu µs threshold.\n",
				current->comm, current->pid,
				_smp_processor_id(), latency,
				cycles_to_usecs(preempt_thresh));
	else
		printk("(%16s-%-5d|#%d): new %lu µs maximum-latency "
			"wakeup.\n", current->comm, current->pid,
				_smp_processor_id(), latency);

	max_sequence++;

	up(&max_mutex);
out:
	atomic_dec(&tr->disabled);
}

/*
 * 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)
		return;

	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;
	sch.cpu = task_cpu(p);
	/*
	 * 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 + sch.cpu;
	if (trace_all_cpus)
		for_each_online_cpu(cpu)
			cpu_traces[cpu].trace_idx = 0;
	else
		tr->trace_idx = 0;

//	if (!atomic_read(&tr->disabled)) {
//		atomic_inc(&tr->disabled);
		tr->critical_sequence = max_sequence;
		tr->preempt_timestamp = cycles();
		tr->critical_start = CALLER_ADDR0;
		_trace_cmdline(_smp_processor_id(), tr);
//		atomic_dec(&tr->disabled);
//	}

	mcount();
out_unlock:
	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;

	trace_special_pid(p->pid, p->prio, 0);

	spin_lock_irqsave(&sch.trace_lock, flags);
	if (p == sch.task) {
		sch.task = NULL;
		tr = sch.tr;
		sch.tr = NULL;
		WARN_ON(!tr);
		/*
		 * Somewhat racy but safer - the printks within
		 * check_wakeup_timing() can call back into the
		 * wakup-timing code and deadlock:
		 */
//		atomic_inc(&tr->disabled);
		spin_unlock(&sch.trace_lock);
		check_wakeup_timing(tr, CALLER_ADDR0);
//		atomic_dec(&tr->disabled);
		local_irq_restore(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;
		spin_unlock_irqrestore(&sch.trace_lock, flags);
	}
}

void trace_change_sched_cpu(struct task_struct *p, int new_cpu)
{
	unsigned long flags;

	if (!wakeup_timing)
		return;

	trace_special(task_cpu(p), task_cpu(p), new_cpu);
	spin_lock_irqsave(&sch.trace_lock, flags);
	if (p == sch.task && task_cpu(p) != new_cpu) {
		sch.cpu = new_cpu;
		trace_special(task_cpu(p), new_cpu, 0);
	}
	spin_unlock_irqrestore(&sch.trace_lock, flags);
}

#endif

#ifdef CONFIG_LATENCY_TRACE

long user_trace_start(void)
{
	struct cpu_trace *tr;
	int cpu;

	if (!trace_user_triggered || trace_print_at_crash)
		return -EINVAL;

	if (down_trylock(&max_mutex))
		return -EAGAIN;

	preempt_disable();
	tr = cpu_traces + smp_processor_id();

#ifdef CONFIG_WAKEUP_TIMING
	if (wakeup_timing) {
		unsigned long flags;

		spin_lock_irqsave(&sch.trace_lock, flags);
		sch.task = current;
		sch.cpu = smp_processor_id();
		sch.tr = tr;
		spin_unlock_irqrestore(&sch.trace_lock, flags);
	}
#endif
	if (trace_all_cpus)
		for_each_online_cpu(cpu)
			cpu_traces[cpu].trace_idx = 0;
	else
		tr->trace_idx = 0;

	tr->critical_sequence = max_sequence;
	tr->preempt_timestamp = cycles();
	_trace_cmdline(_smp_processor_id(), tr);
	mcount();
	preempt_enable();

	up(&max_mutex);

	return 0;
}

long user_trace_stop(void)
{
	unsigned long latency;
	struct cpu_trace *tr;
	cycles_t delta;

	if (!trace_user_triggered || trace_print_at_crash)
		return -EINVAL;

	preempt_disable();
	mcount();

#ifdef CONFIG_WAKEUP_TIMING
	if (wakeup_timing) {
		unsigned long flags;

		spin_lock_irqsave(&sch.trace_lock, flags);
		if (current != sch.task) {
			spin_unlock_irqrestore(&sch.trace_lock, flags);
			preempt_enable();
			return -EINVAL;
		}
		sch.task = NULL;
		tr = sch.tr;
		sch.tr = NULL;
		spin_unlock_irqrestore(&sch.trace_lock, flags);
	} else
#endif
		tr = cpu_traces + smp_processor_id();

	atomic_inc(&tr->disabled);
	if (tr->preempt_timestamp) {
		delta = cycles() - tr->preempt_timestamp;
		if (!report_latency(delta))
			goto out;
		if (tr->critical_sequence != max_sequence ||
						down_trylock(&max_mutex))
			goto out;

		preempt_max_latency = delta;
		update_max_tr(tr);

		latency = cycles_to_usecs(delta);

		if (preempt_thresh)
			printk("(%16s-%-5d|#%d): %lu µs user-latency "
				"violates %lu µs threshold.\n",
					current->comm, current->pid,
					_smp_processor_id(), latency,
					cycles_to_usecs(preempt_thresh));
		else
			printk("(%16s-%-5d|#%d): new %lu µs user-latency.\n",
				current->comm, current->pid,
					_smp_processor_id(), latency);

		max_sequence++;
		up(&max_mutex);
out:
		tr->preempt_timestamp = 0;
	}
	atomic_dec(&tr->disabled);
	preempt_enable();

	return 0;
}

EXPORT_SYMBOL(user_trace_stop);

void stop_trace(void)
{
	if (trace_print_at_crash)
		trace_enabled = -1;
}

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);
}

static void print_entry(struct trace_entry *entry, struct trace_entry *entry0,
			struct trace_entry *next_entry)
{
	unsigned long abs_usecs, rel_usecs;
	int hardirq, softirq;

	abs_usecs = cycles_to_usecs(entry->timestamp - entry0->timestamp);
	rel_usecs = cycles_to_usecs(next_entry->timestamp - entry->timestamp);

	printk("%-5d ", entry->pid);

	printk("%c%c",
		(entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.',
		(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(".");
		}
	}

	printk(":%d %ld.%03ldms: ",
		entry->preempt_count, abs_usecs/1000, abs_usecs % 1000);

	printk_name(entry->u.fn.eip);
	printk("  <= (");
	printk_name(entry->u.fn.parent_eip);
	printk(")\n");
}

void print_last_trace(void)
{
	unsigned int idx0, idx, i;
	struct cpu_trace *tr;
	struct trace_entry *entry0, *entry, *next_entry;

	if (trace_enabled != -1)
		return;

	preempt_disable();
	tr = cpu_traces + smp_processor_id();

	printk("Last %ld trace entries:\n", MAX_TRACE);
	idx0 = tr->trace_idx;
	printk("curr idx: %d\n", idx0);
	if (idx0 >= MAX_TRACE)
		idx0 = MAX_TRACE-1;
	idx = idx0;
	entry0 = tr->trace + idx0;

	for (i = 0; i < MAX_TRACE; i++) {
		entry = tr->trace + idx;
		idx++;
		if (idx == MAX_TRACE)
			idx = 0;
		next_entry = tr->trace + idx;
		if (entry->type == TRACE_FN)
			print_entry(entry, entry0, next_entry);
	}
	trace_print_at_crash = 0;

	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->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_LATENCY_TRACE)
void print_traces(struct task_struct *task)
{
	preempt_disable();
#ifdef CONFIG_PREEMPT_TRACE
	print_preempt_trace(task);
#endif
#ifdef CONFIG_LATENCY_TRACE
	print_last_trace();
#endif
	preempt_enable();
}
#endif

#ifdef CONFIG_LATENCY_TIMING

static int preempt_read_proc(char *page, char **start, off_t off,
			      int count, int *eof, void *data)
{
	cycles_t *max = data;

	return sprintf(page, "%ld\n", cycles_to_usecs(*max));
}

static int preempt_write_proc(struct file *file, const char __user *buffer,
			       unsigned long count, void *data)
{
	unsigned int c, done = 0, val, sum = 0;
	cycles_t *max = data;

	while (count) {
		if (get_user(c, buffer))
			return -EFAULT;
		val = c - '0';
		buffer++;
		done++;
		count--;
		if (c == 0 || c == '\n')
			break;
		if (val > 9)
			return -EINVAL;
		sum *= 10;
		sum += val;
	}
	*max = usecs_to_cycles(sum);
	return done;
}

static __init int latency_init(void)
{
	struct proc_dir_entry *entry;

	entry = create_proc_entry("sys/kernel/preempt_max_latency", 0600, NULL);

	entry->nlink = 1;
	entry->data = &preempt_max_latency;
	entry->read_proc = preempt_read_proc;
	entry->write_proc = preempt_write_proc;

	entry = create_proc_entry("sys/kernel/preempt_thresh", 0600, NULL);

	entry->nlink = 1;
	entry->data = &preempt_thresh;
	entry->read_proc = preempt_read_proc;
	entry->write_proc = preempt_write_proc;

	return 0;
}
__initcall(latency_init);

#endif


Reply to: