http://lia64.bkbits.net/linux-ia64-test-2.6.9 aegl@agluck-lia64.sc.intel.com|ChangeSet|20040830211620|61691 aegl # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/08/30 17:31:16-07:00 akpm@bix.(none) # Merge http://lia64.bkbits.net/linux-ia64-test-2.6.9 # into bix.(none):/usr/src/bk-ia64 # # arch/ia64/kernel/perfmon.c # 2004/08/30 17:31:13-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/30 21:16:20+00:00 aegl@agluck-lia64.sc.intel.com # Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/work/sn2defconfig # into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.9 # # arch/ia64/configs/sn2_defconfig # 2004/08/30 21:16:15+00:00 aegl@agluck-lia64.sc.intel.com +0 -0 # Auto merged # # ChangeSet # 2004/08/30 20:49:38+00:00 jbarnes@sgi.com # [IA64-SGI] sn2_defconfig: Enable preempt, CPU hotplug, ext2 and IDE. # # o enable preempt per Andrew's request for testing # o enable CPU hotplug for testing # o add EXT2 and IDE disk support to make simulation easy # # Signed-off-by: Jesse Barnes # Signed-off-by: Tony Luck # # arch/ia64/configs/sn2_defconfig # 2004/08/30 20:46:40+00:00 aegl@agluck-lia64.sc.intel.com +24 -13 # Enable preempt, CPU hotplug, ext2 and IDE. # # ChangeSet # 2004/08/27 13:39:54-07:00 akpm@bix.(none) # Merge # # kernel/timer.c # 2004/08/27 13:39:50-07:00 akpm@bix.(none) +0 -0 # SCCS merged # # include/asm-ia64/acpi.h # 2004/08/27 13:34:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/mm/contig.c # 2004/08/27 13:34:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/kernel/time.c # 2004/08/27 13:34:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/ia64/kernel/asm-offsets.c # 2004/08/27 13:34:21-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/27 19:04:09+00:00 eranian@hpl.hp.com # [IA64] perfmon.c: file descriptor fixes # # - fix pfm_free_fd() to clear current->files->fd[fd] in # case of error during PFM_CONTEXT_CREATE, i.e., undo # the effect of fd_install(). This could cause kernel # panic if the file descriptor gets used by error through # perfmon. # - fix pfm_context_create() to correctly propagate the # return value of pfm_alloc_fd(). # # signed-off-by: stephane eranian # Signed-off-by: Tony Luck # # arch/ia64/kernel/perfmon.c # 2004/08/27 19:00:54+00:00 aegl@agluck-lia64.sc.intel.com +13 -2 # - fix pfm_free_fd() to clear current->files->fd[fd] in # case of error during PFM_CONTEXT_CREATE, i.e., undo # the effect of fd_install(). This could cause kernel # panic if the file descriptor gets used by error through # perfmon. # - fix pfm_context_create() to correctly propagate the # return value of pfm_alloc_fd(). # # ChangeSet # 2004/08/25 23:16:36+00:00 aegl@agluck-lia64.sc.intel.com # Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.8.1 # into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.9 # # arch/ia64/configs/generic_defconfig # 2004/08/25 23:16:31+00:00 aegl@agluck-lia64.sc.intel.com +0 -0 # Auto merged # # ChangeSet # 2004/08/25 22:40:12+00:00 levon@movementarian.org # [IA64] support for IA64 hardware performance counters via the perfmon interface # # This patch provides support for IA64 hardware performance counters via # the perfmon interface. Please consider applying. # # Signed-off-by: John Levon # Signed-off-by: Tony Luck # # arch/ia64/oprofile/perfmon.c # 2004/08/25 22:35:03+00:00 aegl@agluck-lia64.sc.intel.com +105 -0 # support for IA64 hardware performance counters via the perfmon interface # # arch/ia64/oprofile/perfmon.c # 2004/08/25 22:35:03+00:00 aegl@agluck-lia64.sc.intel.com +0 -0 # BitKeeper file /data/home/aegl/BK/work/oprofile/arch/ia64/oprofile/perfmon.c # # arch/ia64/oprofile/init.c # 2004/08/25 22:34:27+00:00 aegl@agluck-lia64.sc.intel.com +8 -1 # support for IA64 hardware performance counters via the perfmon interface # # arch/ia64/oprofile/Makefile # 2004/08/25 22:34:27+00:00 aegl@agluck-lia64.sc.intel.com +1 -0 # support for IA64 hardware performance counters via the perfmon interface # # arch/ia64/oprofile/Kconfig # 2004/08/25 22:34:27+00:00 aegl@agluck-lia64.sc.intel.com +4 -0 # support for IA64 hardware performance counters via the perfmon interface # # ChangeSet # 2004/08/25 18:27:33+00:00 dcn@sgi.com # [IA64] allow OEM written modules to make calls to ia64 OEM SAL functions. # # Add wrapper functions for SAL_CALL(), SAL_CALL_NOLOCK(), and # SAL_CALL_REENTRANT() that allow OEM written modules to make # calls to ia64 OEM SAL functions. # # Signed-off-by: Dean Nelson # Signed-off-by: Tony Luck # # include/asm-ia64/sal.h # 2004/08/25 18:25:25+00:00 aegl@agluck-lia64.sc.intel.com +10 -0 # allow OEM written modules to make calls to ia64 OEM SAL functions. # # arch/ia64/kernel/sal.c # 2004/08/25 18:24:59+00:00 aegl@agluck-lia64.sc.intel.com +38 -0 # allow OEM written modules to make calls to ia64 OEM SAL functions. # # ChangeSet # 2004/08/25 18:21:19+00:00 ianw@gelato.unsw.edu.au # [IA64] Remove extraneous MMU_TRACE debugging macros # # Patch created by Ian Wienand. # # Signed-off-by: Tony Luck # # include/asm-ia64/tlbflush.h # 2004/08/25 18:16:41+00:00 aegl@agluck-lia64.sc.intel.com +2 -5 # Remove extraneous MMU_TRACE debugging macros # # include/asm-ia64/mmu_context.h # 2004/08/25 18:16:03+00:00 aegl@agluck-lia64.sc.intel.com +1 -38 # Remove extraneous MMU_TRACE debugging macros # # ChangeSet # 2004/08/25 18:03:28+00:00 yanmin.zhang@intel.com # [IA64] contig.c: Function find_bootmap_location has 2 bugs. # # Firstly, if it's done successfully, it should return -1 instead of 1 # because its caller, efi_memmap_walk, will end when find_bootmap_location # returns a value smaller than 0. # # Secondly, statement "free_start = PAGE_ALIGN(rsvd_region[i].end)" should # been moved forward. free_start needs to be initialized for every loop # iteration. Current implementation is buggy where initialization is # skipped if range_end <= range_start. Skipping initializing will leads # to overlapping bootmap with one of the rsvd_regions and subsequently # kernel hang at boot time. # # Singed-off-by:(sic) Zhang Yanmin # Signed-off-by: Yao Jun # Signed-off-by: Tony Luck # # arch/ia64/mm/contig.c # 2004/08/25 17:56:35+00:00 aegl@agluck-lia64.sc.intel.com +4 -4 # Function find_bootmap_location has 2 bugs. # # ChangeSet # 2004/08/25 17:54:46+00:00 yanmin.zhang@intel.com # [IA64] Fix boot problems when using "mem=" boot parameter. # # My tiger-4 machine has 16GB memory. Kernel 2.6.8 fails to boot on it # when command line parameter mem=8G, and it also fails when mem being # set to other value, such as 7G, 10G. # # Basically, in function efi_memmap_walk, md->num_pages might be decreased # if mem_limit is set, and then at the next time when efi_memmap_walk is # called, trim_top might trim the md again because of IA64_GRANULE_SIZE # alignment, then another md which is beyond mem_limit at the beginning # will be chosen, and its physical page number is larger than max_pfn. Then, # a BUG check is triggered. # # Signed-off-by: Zhang Yanmin # Signed-off-by: Yao Jun # Signed-off-by: Tony Luck # # arch/ia64/kernel/efi.c # 2004/08/25 17:50:37+00:00 aegl@agluck-lia64.sc.intel.com +3 -1 # Fix boot problems when using "mem=" boot parameter. # # ChangeSet # 2004/08/25 17:45:09+00:00 jbarnes@sgi.com # [IA64] generic_defconfig: Enable codepage/iocharset for VFAT filesystems. # # VFAT filesystems need to have codepages and iocharsets specified these days, # so build some into the kernel to make it easier to mount /boot/efi on ia64 # systems. # # Signed-off-by: Jesse Barnes # Signed-off-by: Tony Luck # # arch/ia64/configs/generic_defconfig # 2004/08/25 17:43:06+00:00 aegl@agluck-lia64.sc.intel.com +19 -9 # Enable codepage/iocharset for VFAT filesystems. # # ChangeSet # 2004/08/25 17:39:35+00:00 jbarnes@sgi.com # [IA64] Add include pagemap.h to tlb.h to fix warnings when CONFIG_SWAP=n. # # I noticed when building with CONFIG_SWAP=n that tlb.h gave a warning about # some undefined symbols. This is because it was pulling them in through # swap.h, but when CONFIG_SWAP=n, they're no longer pulled in. Adding # pagemap.h to tlb.h fixes the problem. # # Signed-off-by: Jesse Barnes # Signed-off-by: Tony Luck # # include/asm-ia64/tlb.h # 2004/08/25 17:35:10+00:00 aegl@agluck-lia64.sc.intel.com +1 -0 # Add pagemap.h to fix warnings when CONFIG_SWAP=n. # # ChangeSet # 2004/08/25 17:30:26+00:00 bjohnson@sgi.com # [IA64-SGI] Add full PROM version banner to /proc/sgi_prominfo/nodeXX/version. # # Signed-off-by: Brian J. Johnson # Signed-off-by: Tony Luck # # arch/ia64/sn/kernel/sn2/prominfo_proc.c # 2004/08/25 17:27:31+00:00 aegl@agluck-lia64.sc.intel.com +61 -13 # Add full PROM version banner to /proc/sgi_prominfo/nodeXX/version. # # ChangeSet # 2004/08/24 22:21:59+00:00 aegl@agluck-lia64.sc.intel.com # Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.8.1 # into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.9 # # kernel/timer.c # 2004/08/24 22:21:54+00:00 aegl@agluck-lia64.sc.intel.com +0 -0 # Auto merged # # kernel/posix-timers.c # 2004/08/24 22:21:53+00:00 aegl@agluck-lia64.sc.intel.com +0 -0 # Auto merged # # include/asm-ia64/acpi.h # 2004/08/24 22:21:53+00:00 aegl@agluck-lia64.sc.intel.com +0 -1 # Auto merged # # ChangeSet # 2004/08/24 21:26:27+00:00 clameter@sgi.com # scalability & performance improvements for timers # # Signed-off-by: Christoph Lameter # Signed-off-by: Tony Luck # # - Include corrected test data since the test program had a bad # influence on the outcome. Scalability is better than the # test program indicated. # - Correctly setup the timer accuracy. # - Consistently increases performance over existing codebase # - Make the IA64 fastcall work for all clock sources and not only # for ITC based clocking. # - Add fastcall for clock_gettime(REALTIME and MONOTONIC) # (the fastcall also returns nanoseconds instead of usecs*1000) # - Scalability improvements in particular for the use of global clocks # by avoiding the use of a cmpxchg. For applications # that continually "live" in gettimeofday on an SMP system this # will be a significant improvement. # - Ability to switch off the cmpxchg for ITC based systems through # a "nojitter" option on the kernel command line. This increases # scalability of the time functions significantly. The ITC tuning code # that runs during bootup typically insures that ITC offsets are less # than a few cycles which are longer than the delay caused by the gettime # functions and therefore the cmpxchg is not necessary on most systems. # - Self tuning interpolator limiting the jumps forward to 10-20 usecs # on each occurrence and increasing accuracy as well as robustness. # There is no danger anymore that the interpolator is configured to # be running too fast. # - Report the increased accuracy via clock_getres() to userspace. # - Generic interface. An interpolator can be easily setup by simply # setting up a time_interpolator structure with some values. # No coding of special functions needed. # - Supports the HPET timer. # # kernel/timer.c # 2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +10 -5 # scalability & performance improvements for timers # # kernel/posix-timers.c # 2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +5 -0 # scalability & performance improvements for timers # # include/linux/timex.h # 2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +123 -52 # scalability & performance improvements for timers # # drivers/char/hpet.c # 2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +3 -33 # scalability & performance improvements for timers # # arch/ia64/sn/kernel/sn2/timer.c # 2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +4 -45 # scalability & performance improvements for timers # # arch/ia64/kernel/time.c # 2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +35 -84 # scalability & performance improvements for timers # # arch/ia64/kernel/fsys.S # 2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +185 -172 # scalability & performance improvements for timers # # arch/ia64/kernel/cyclone.c # 2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +4 -55 # scalability & performance improvements for timers # # arch/ia64/kernel/asm-offsets.c # 2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +16 -3 # scalability & performance improvements for timers # # ChangeSet # 2004/08/24 16:16:47+00:00 aegl@agluck-lia64.sc.intel.com # Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/Linus # into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.9 # # include/asm-ia64/acpi.h # 2004/08/24 16:16:42+00:00 aegl@agluck-lia64.sc.intel.com +0 -1 # Auto merged # # ChangeSet # 2004/08/17 23:50:42+00:00 aegl@agluck-lia64.sc.intel.com # Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.8.1 # into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.9 # # include/asm-ia64/acpi.h # 2004/08/17 23:50:37+00:00 aegl@agluck-lia64.sc.intel.com +0 -0 # Auto merged # diff -Nru a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig --- a/arch/ia64/configs/generic_defconfig 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/configs/generic_defconfig 2004-08-30 17:32:04 -07:00 @@ -1,5 +1,7 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.9-rc1 +# Tue Aug 24 15:08:24 2004 # # @@ -126,6 +128,7 @@ CONFIG_HOTPLUG_PCI=m # CONFIG_HOTPLUG_PCI_FAKE is not set CONFIG_HOTPLUG_PCI_ACPI=m +# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set # CONFIG_HOTPLUG_PCI_CPCI is not set # CONFIG_HOTPLUG_PCI_PCIE is not set # CONFIG_HOTPLUG_PCI_SHPC is not set @@ -172,6 +175,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_SIZE=4096 @@ -313,6 +317,7 @@ CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m +# CONFIG_MD_RAID10 is not set CONFIG_MD_RAID5=m CONFIG_MD_RAID6=m CONFIG_MD_MULTIPATH=m @@ -365,6 +370,7 @@ # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -767,6 +773,7 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set # # USB Host Controller Drivers @@ -919,6 +926,8 @@ CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_NTFS_FS=m # CONFIG_NTFS_DEBUG is not set # CONFIG_NTFS_RW is not set @@ -946,7 +955,6 @@ # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -971,6 +979,7 @@ CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m CONFIG_SMB_NLS_DEFAULT=y CONFIG_SMB_NLS_REMOTE="cp437" @@ -1007,7 +1016,7 @@ # CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m CONFIG_NLS_CODEPAGE_775=m CONFIG_NLS_CODEPAGE_850=m @@ -1031,7 +1040,7 @@ CONFIG_NLS_CODEPAGE_1250=m CONFIG_NLS_CODEPAGE_1251=m # CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_1=y CONFIG_NLS_ISO8859_2=m CONFIG_NLS_ISO8859_3=m CONFIG_NLS_ISO8859_4=m @@ -1068,18 +1077,18 @@ # # Kernel hacking # -CONFIG_IA64_GRANULE_16MB=y -# CONFIG_IA64_GRANULE_64MB is not set CONFIG_DEBUG_KERNEL=y -# CONFIG_IA64_PRINT_HAZARDS is not set -# CONFIG_DISABLE_VHPT is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_INFO is not set +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set +# CONFIG_IA64_PRINT_HAZARDS is not set +# CONFIG_DISABLE_VHPT is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set -# CONFIG_DEBUG_INFO is not set CONFIG_SYSVIPC_COMPAT=y # @@ -1102,11 +1111,12 @@ # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES_GENERIC is not set +# CONFIG_CRYPTO_AES is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set # CONFIG_CRYPTO_TEA is not set # CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set diff -Nru a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig --- a/arch/ia64/configs/sn2_defconfig 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/configs/sn2_defconfig 2004-08-30 17:32:04 -07:00 @@ -1,5 +1,7 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.9-rc1 +# Fri Aug 27 22:00:00 2004 # # @@ -7,7 +9,6 @@ # CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y -CONFIG_STANDALONE=y # # General setup @@ -74,8 +75,8 @@ CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=512 -# CONFIG_HOTPLUG_CPU is not set -# CONFIG_PREEMPT is not set +CONFIG_HOTPLUG_CPU=y +CONFIG_PREEMPT=y CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y @@ -115,7 +116,7 @@ # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_USE_VECTOR is not set +# CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y @@ -142,6 +143,7 @@ # # Generic Driver Options # +CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set @@ -171,6 +173,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y @@ -185,7 +188,8 @@ # Please see Documentation/ide.txt for help/info on IDE drives # # CONFIG_BLK_DEV_IDE_SATA is not set -# CONFIG_BLK_DEV_IDEDISK is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -316,6 +320,7 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set CONFIG_MD_RAID5=y # CONFIG_MD_RAID6 is not set CONFIG_MD_MULTIPATH=y @@ -368,11 +373,13 @@ # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set CONFIG_IPV6=m # CONFIG_IPV6_PRIVACY is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set # CONFIG_IPV6_TUNNEL is not set # CONFIG_NETFILTER is not set @@ -538,6 +545,7 @@ # Non-8250 serial port support # CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_SGI_L1_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y @@ -601,7 +609,6 @@ # Console display driver support # # CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y # @@ -621,6 +628,7 @@ # CONFIG_USB_DEVICEFS is not set # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set # # USB Host Controller Drivers @@ -717,7 +725,7 @@ # # File systems # -CONFIG_EXT2_FS=m +CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y @@ -792,7 +800,6 @@ # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -817,10 +824,12 @@ CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_XATTR is not set # CONFIG_CIFS_POSIX is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -907,18 +916,18 @@ # # Kernel hacking # -CONFIG_IA64_GRANULE_16MB=y -# CONFIG_IA64_GRANULE_64MB is not set CONFIG_DEBUG_KERNEL=y -# CONFIG_IA64_PRINT_HAZARDS is not set -# CONFIG_DISABLE_VHPT is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +CONFIG_DEBUG_INFO=y +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set +# CONFIG_IA64_PRINT_HAZARDS is not set +# CONFIG_DISABLE_VHPT is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set -CONFIG_DEBUG_INFO=y CONFIG_SYSVIPC_COMPAT=y # @@ -937,6 +946,7 @@ CONFIG_CRYPTO_SHA1=m # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WHIRLPOOL is not set CONFIG_CRYPTO_DES=m # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set @@ -946,6 +956,7 @@ # CONFIG_CRYPTO_CAST6 is not set # CONFIG_CRYPTO_TEA is not set # CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set CONFIG_CRYPTO_DEFLATE=m # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set diff -Nru a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c --- a/arch/ia64/kernel/asm-offsets.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/kernel/asm-offsets.c 2004-08-30 17:32:04 -07:00 @@ -188,9 +188,6 @@ DEFINE(IA64_CLONE_VM, CLONE_VM); BLANK(); - /* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */ - DEFINE(IA64_CPUINFO_ITM_DELTA_OFFSET, offsetof (struct cpuinfo_ia64, itm_delta)); - DEFINE(IA64_CPUINFO_ITM_NEXT_OFFSET, offsetof (struct cpuinfo_ia64, itm_next)); DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET, offsetof (struct cpuinfo_ia64, nsec_per_cyc)); DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec)); @@ -202,5 +199,21 @@ BLANK(); DEFINE(IA64_MCA_TLB_INFO_SIZE, sizeof (struct ia64_mca_tlb_info)); + /* used by head.S */ + DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET, offsetof (struct cpuinfo_ia64, nsec_per_cyc)); + BLANK(); + /* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */ + DEFINE(IA64_TIME_INTERPOLATOR_ADDRESS_OFFSET, offsetof (struct time_interpolator, addr)); + DEFINE(IA64_TIME_INTERPOLATOR_SOURCE_OFFSET, offsetof (struct time_interpolator, source)); + DEFINE(IA64_TIME_INTERPOLATOR_SHIFT_OFFSET, offsetof (struct time_interpolator, shift)); + DEFINE(IA64_TIME_INTERPOLATOR_NSEC_OFFSET, offsetof (struct time_interpolator, nsec_per_cyc)); + DEFINE(IA64_TIME_INTERPOLATOR_OFFSET_OFFSET, offsetof (struct time_interpolator, offset)); + DEFINE(IA64_TIME_INTERPOLATOR_LAST_CYCLE_OFFSET, offsetof (struct time_interpolator, last_cycle)); + DEFINE(IA64_TIME_INTERPOLATOR_LAST_COUNTER_OFFSET, offsetof (struct time_interpolator, last_counter)); + DEFINE(IA64_TIME_INTERPOLATOR_JITTER_OFFSET, offsetof (struct time_interpolator, jitter)); + DEFINE(IA64_TIME_SOURCE_CPU, TIME_SOURCE_CPU); + DEFINE(IA64_TIME_SOURCE_MMIO64, TIME_SOURCE_MMIO64); + DEFINE(IA64_TIME_SOURCE_MMIO32, TIME_SOURCE_MMIO32); + DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec)); } diff -Nru a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c --- a/arch/ia64/kernel/cyclone.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/kernel/cyclone.c 2004-08-30 17:32:04 -07:00 @@ -17,62 +17,10 @@ use_cyclone = 1; } -static u32* volatile cyclone_timer; /* Cyclone MPMC0 register */ -static u32 last_update_cyclone; - -static unsigned long offset_base; - -static unsigned long get_offset_cyclone(void) -{ - u32 now; - unsigned long offset; - - /* Read the cyclone timer */ - now = readl(cyclone_timer); - /* .. relative to previous update*/ - offset = now - last_update_cyclone; - - /* convert cyclone ticks to nanoseconds */ - offset = (offset*NSEC_PER_SEC)/CYCLONE_TIMER_FREQ; - - /* our adjusted time in nanoseconds */ - return offset_base + offset; -} - -static void update_cyclone(long delta_nsec) -{ - u32 now; - unsigned long offset; - - /* Read the cyclone timer */ - now = readl(cyclone_timer); - /* .. relative to previous update*/ - offset = now - last_update_cyclone; - - /* convert cyclone ticks to nanoseconds */ - offset = (offset*NSEC_PER_SEC)/CYCLONE_TIMER_FREQ; - - offset += offset_base; - - /* Be careful about signed/unsigned comparisons here: */ - if (delta_nsec < 0 || (unsigned long) delta_nsec < offset) - offset_base = offset - delta_nsec; - else - offset_base = 0; - - last_update_cyclone = now; -} - -static void reset_cyclone(void) -{ - offset_base = 0; - last_update_cyclone = readl(cyclone_timer); -} struct time_interpolator cyclone_interpolator = { - .get_offset = get_offset_cyclone, - .update = update_cyclone, - .reset = reset_cyclone, + .source = TIME_SOURCE_MMIO32, + .shift = 32, .frequency = CYCLONE_TIMER_FREQ, .drift = -100, }; @@ -83,6 +31,7 @@ u64 base; /* saved cyclone base address */ u64 offset; /* offset from pageaddr to cyclone_timer register */ int i; + u32* volatile cyclone_timer; /* Cyclone MPMC0 register */ if (!use_cyclone) return -ENODEV; @@ -150,7 +99,7 @@ } } /* initialize last tick */ - last_update_cyclone = readl(cyclone_timer); + cyclone_interpolator.addr = cyclone_timer; register_time_interpolator(&cyclone_interpolator); return 0; diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c --- a/arch/ia64/kernel/efi.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/kernel/efi.c 2004-08-30 17:32:04 -07:00 @@ -357,8 +357,10 @@ if (total_mem >= mem_limit) continue; total_mem += (md->num_pages << EFI_PAGE_SHIFT); - if (total_mem > mem_limit) + if (total_mem > mem_limit) { md->num_pages -= ((total_mem - mem_limit) >> EFI_PAGE_SHIFT); + max_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); + } if (md->num_pages == 0) continue; diff -Nru a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S --- a/arch/ia64/kernel/fsys.S 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/kernel/fsys.S 2004-08-30 17:32:04 -07:00 @@ -8,6 +8,8 @@ * 18-Feb-03 louisk Implement fsys_gettimeofday(). * 28-Feb-03 davidm Fixed several bugs in fsys_gettimeofday(). Tuned it some more, * probably broke it along the way... ;-) + * 13-Jul-04 clameter Implement fsys_clock_gettime and revise fsys_gettimeofday to make + * it capable of using memory based clocks without falling back to C code. */ #include @@ -144,195 +146,206 @@ END(fsys_set_tid_address) /* - * Note 1: This routine uses floating-point registers, but only with registers that - * operate on integers. Because of that, we don't need to set ar.fpsr to the - * kernel default value. - * - * Note 2: For now, we will assume that all CPUs run at the same clock-frequency. - * If that wasn't the case, we would have to disable preemption (e.g., - * by disabling interrupts) between reading the ITC and reading - * local_cpu_data->nsec_per_cyc. - * - * Note 3: On platforms where the ITC-drift bit is set in the SAL feature vector, - * we ought to either skip the ITC-based interpolation or run an ntp-like - * daemon to keep the ITCs from drifting too far apart. + * Ensure that the time interpolator structure is compatible with the asm code */ +#if IA64_TIME_INTERPOLATOR_SOURCE_OFFSET !=0 || IA64_TIME_INTERPOLATOR_SHIFT_OFFSET != 2 \ + || IA64_TIME_INTERPOLATOR_JITTER_OFFSET != 3 || IA64_TIME_INTERPOLATOR_NSEC_OFFSET != 4 +#error fsys_gettimeofday incompatible with changes to struct time_interpolator +#endif +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 +#define CLOCK_DIVIDE_BY_1000 0x4000 +#define CLOCK_ADD_MONOTONIC 0x8000 ENTRY(fsys_gettimeofday) .prologue .altrp b6 .body - add r9=TI_FLAGS+IA64_TASK_SIZE,r16 - addl r3=THIS_CPU(cpu_info),r0 - -#ifdef CONFIG_SMP - movl r10=__per_cpu_offset - movl r2=sal_platform_features - ;; - - ld8 r2=[r2] - movl r19=xtime // xtime is a timespec struct - - ld8 r10=[r10] // r10 <- __per_cpu_offset[0] - addl r21=THIS_CPU(cpu_info),r0 - ;; - add r10=r21, r10 // r10 <- &cpu_data(time_keeper_id) - tbit.nz p8,p0 = r2, IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT -(p8) br.spnt.many fsys_fallback_syscall -#else - ;; - mov r10=r3 - movl r19=xtime // xtime is a timespec struct -#endif - ld4 r9=[r9] - movl r17=xtime_lock - ;; - - // r32, r33 should contain the 2 args of gettimeofday - adds r21=IA64_CPUINFO_ITM_NEXT_OFFSET, r10 - mov r2=-1 - tnat.nz p6,p7=r32 // guard against NaT args - ;; - - adds r10=IA64_CPUINFO_ITM_DELTA_OFFSET, r10 -(p7) tnat.nz p6,p0=r33 -(p6) br.cond.spnt.few .fail_einval - - adds r8=IA64_CPUINFO_NSEC_PER_CYC_OFFSET, r3 - movl r24=2361183241434822607 // for division hack (only for / 1000) - ;; - - ldf8 f7=[r10] // f7 now contains itm_delta - setf.sig f11=r2 - adds r10=8, r32 - - adds r20=IA64_TIMESPEC_TV_NSEC_OFFSET, r19 // r20 = &xtime->tv_nsec - movl r26=jiffies - - setf.sig f9=r24 // f9 is used for division hack - movl r27=wall_jiffies - - and r9=TIF_ALLWORK_MASK,r9 - movl r25=last_nsec_offset - ;; - - /* - * Verify that we have permission to write to struct timeval. Note: - * Another thread might unmap the mapping before we actually get - * to store the result. That's OK as long as the stores are also - * protect by EX(). - */ -EX(.fail_efault, probe.w.fault r32, 3) // this must come _after_ NaT-check -EX(.fail_efault, probe.w.fault r10, 3) // this must come _after_ NaT-check - nop 0 - - ldf8 f10=[r8] // f10 <- local_cpu_data->nsec_per_cyc value - cmp.ne p8, p0=0, r9 -(p8) br.spnt.many fsys_fallback_syscall - ;; -.retry: // *** seq = read_seqbegin(&xtime_lock); *** - ld4.acq r23=[r17] // since &xtime_lock == &xtime_lock->sequence - ld8 r14=[r25] // r14 (old) = last_nsec_offset - - ld8 r28=[r26] // r28 = jiffies - ld8 r29=[r27] // r29 = wall_jiffies - ;; - - ldf8 f8=[r21] // f8 now contains itm_next - mov.m r31=ar.itc // put time stamp into r31 (ITC) == now - sub r28=r29, r28, 1 // r28 now contains "-(lost + 1)" - ;; - - ld8 r2=[r19] // r2 = sec = xtime.tv_sec - ld8 r29=[r20] // r29 = nsec = xtime.tv_nsec - tbit.nz p9, p10=r23, 0 // p9 <- is_odd(r23), p10 <- is_even(r23) - - setf.sig f6=r28 // f6 <- -(lost + 1) (6 cyc) - ;; - + mov r31 = r32 + tnat.nz p6,p0 = r33 // guard against NaT argument +(p6) br.cond.spnt.few .fail_einval + mov r30 = CLOCK_DIVIDE_BY_1000 + ;; +.gettime: + // Register map + // Incoming r31 = pointer to address where to place result + // r30 = flags determining how time is processed + // r2,r3 = temp r4-r7 preserved + // r8 = result nanoseconds + // r9 = result seconds + // r10 = temporary storage for clock difference + // r11 = preserved: saved ar.pfs + // r12 = preserved: memory stack + // r13 = preserved: thread pointer + // r14 = debug pointer / usable + // r15 = preserved: system call number + // r16 = preserved: current task pointer + // r17 = wall to monotonic use + // r18 = time_interpolator->offset + // r19 = address of wall_to_monotonic + // r20 = pointer to struct time_interpolator / pointer to time_interpolator->address + // r21 = shift factor + // r22 = address of time interpolator->last_counter + // r23 = address of time_interpolator->last_cycle + // r24 = adress of time_interpolator->offset + // r25 = last_cycle value + // r26 = last_counter value + // r27 = pointer to xtime + // r28 = sequence number at the beginning of critcal section + // r29 = address of seqlock + // r30 = time processing flags / memory address + // r31 = pointer to result + // Predicates + // p6,p7 short term use + // p8 = timesource ar.itc + // p9 = timesource mmio64 + // p10 = timesource mmio32 + // p11 = timesource not to be handled by asm code + // p12 = memory time source ( = p9 | p10) + // p13 = do cmpxchg with time_interpolator_last_cycle + // p14 = Divide by 1000 + // p15 = Add monotonic + // + // Note that instructions are optimized for McKinley. McKinley can process two + // bundles simultaneously and therefore we continuously try to feed the CPU + // two bundles and then a stop. + tnat.nz p6,p0 = r31 // branch deferred since it does not fit into bundle structure + mov pr = r30,0xc000 // Set predicates according to function + add r2 = TI_FLAGS+IA64_TASK_SIZE,r16 + movl r20 = time_interpolator + ;; + ld8 r20 = [r20] // get pointer to time_interpolator structure + movl r29 = xtime_lock + ld4 r2 = [r2] // process work pending flags + movl r27 = xtime + ;; // only one bundle here + ld8 r21 = [r20] // first quad with control information + and r2 = TIF_ALLWORK_MASK,r2 +(p6) br.cond.spnt.few .fail_einval // deferred branch + ;; + add r10 = IA64_TIME_INTERPOLATOR_ADDRESS_OFFSET,r20 + extr r3 = r21,32,32 // time_interpolator->nsec_per_cyc + extr r8 = r21,0,16 // time_interpolator->source + nop.i 123 + cmp.ne p6, p0 = 0, r2 // Fallback if work is scheduled +(p6) br.cond.spnt.many fsys_fallback_syscall + ;; + cmp.eq p8,p12 = 0,r8 // Check for cpu timer + cmp.eq p9,p0 = 1,r8 // MMIO64 ? + extr r2 = r21,24,8 // time_interpolator->jitter + cmp.eq p10,p0 = 2,r8 // MMIO32 ? + cmp.lt p11,p0 = 2,r8 // function? +(p11) br.cond.spnt.many fsys_fallback_syscall + ;; + setf.sig f7 = r3 // Setup for scaling of counter +(p15) movl r19 = wall_to_monotonic +(p12) ld8 r30 = [r10] + cmp.ne p13,p0 = r2,r0 // need jitter compensation? + extr r21 = r21,16,8 // shift factor + ;; +.time_redo: + .pred.rel.mutex p8,p9,p10 + ld4.acq r28 = [r29] // xtime_lock.sequence. Must come first for locking purposes +(p8) mov r2 = ar.itc // CPU_TIMER. 36 clocks latency!!! + add r22 = IA64_TIME_INTERPOLATOR_LAST_COUNTER_OFFSET,r20 +(p9) ld8 r2 = [r30] // readq(ti->address). Could also have latency issues.. +(p10) ld4 r2 = [r30] // readw(ti->address) +(p13) add r23 = IA64_TIME_INTERPOLATOR_LAST_CYCLE_OFFSET,r20 + ;; // could be removed by moving the last add upward + ld8 r26 = [r22] // time_interpolator->last_counter +(p13) ld8 r25 = [r23] // time interpolator->last_cycle + add r24 = IA64_TIME_INTERPOLATOR_OFFSET_OFFSET,r20 +(p15) ld8 r17 = [r19],IA64_TIMESPEC_TV_NSEC_OFFSET + ld8 r9 = [r27],IA64_TIMESPEC_TV_NSEC_OFFSET + nop.i 123 + ;; + ld8 r18 = [r24] // time_interpolator->offset + ld8 r8 = [r27],-IA64_TIMESPEC_TV_NSEC_OFFSET // xtime.tv_nsec +(p13) sub r3 = r25,r2 // Diff needed before comparison (thanks davidm) + ;; +(p13) cmp.gt.unc p6,p7 = r3,r0 // check if it is less than last. p6,p7 cleared + sub r10 = r2,r26 // current_counter - last_counter + ;; +(p6) sub r10 = r25,r26 // time we got was less than last_cycle +(p7) mov ar.ccv = r25 // more than last_cycle. Prep for cmpxchg + ;; + setf.sig f8 = r10 + nop.i 123 + ;; +(p7) cmpxchg8.rel r3 = [r23],r2,ar.ccv +EX(.fail_efault, probe.w.fault r31, 3) // This takes 5 cycles and we have spare time + xmpy.l f8 = f8,f7 // nsec_per_cyc*(counter-last_counter) +(p15) add r9 = r9,r17 // Add wall to monotonic.secs to result secs + ;; +(p15) ld8 r17 = [r19],-IA64_TIMESPEC_TV_NSEC_OFFSET +(p7) cmp.ne p7,p0 = r25,r3 // if cmpxchg not successful redo + // simulate tbit.nz.or p7,p0 = r28,0 + and r28 = ~1,r28 // Make sequence even to force retry if odd + getf.sig r2 = f8 mf - xma.l f8=f6, f7, f8 // f8 (last_tick) <- -(lost + 1)*itm_delta + itm_next (5 cyc) - nop 0 - - setf.sig f12=r31 // f12 <- ITC (6 cyc) - // *** if (unlikely(read_seqretry(&xtime_lock, seq))) continue; *** - ld4 r24=[r17] // r24 = xtime_lock->sequence (re-read) - nop 0 - ;; - - xma.l f8=f11, f8, f12 // f8 (elapsed_cycles) <- (-1*last_tick + now) = (now - last_tick) - nop 0 - ;; - - getf.sig r18=f8 // r18 <- (now - last_tick) - xmpy.l f8=f8, f10 // f8 <- elapsed_cycles*nsec_per_cyc (5 cyc) - add r3=r29, r14 // r3 = (nsec + old) - ;; - - cmp.lt p7, p8=r18, r0 // if now < last_tick, set p7 = 1, p8 = 0 - getf.sig r18=f8 // r18 = elapsed_cycles*nsec_per_cyc (6 cyc) - nop 0 - ;; - -(p10) cmp.ne p9, p0=r23, r24 // if xtime_lock->sequence != seq, set p9 - shr.u r18=r18, IA64_NSEC_PER_CYC_SHIFT // r18 <- offset -(p9) br.spnt.many .retry - ;; - - mov ar.ccv=r14 // ar.ccv = old (1 cyc) - cmp.leu p7, p8=r18, r14 // if (offset <= old), set p7 = 1, p8 = 0 + add r8 = r8,r18 // Add time interpolator offset ;; - -(p8) cmpxchg8.rel r24=[r25], r18, ar.ccv // compare-and-exchange (atomic!) -(p8) add r3=r29, r18 // r3 = (nsec + offset) - ;; - shr.u r3=r3, 3 // initiate dividing r3 by 1000 - ;; - setf.sig f8=r3 // (6 cyc) - mov r10=1000000 // r10 = 1000000 + ld4 r10 = [r29] // xtime_lock.sequence +(p15) add r8 = r8, r17 // Add monotonic.nsecs to nsecs + shr.u r2 = r2,r21 + ;; // overloaded 3 bundles! + // End critical section. + add r8 = r8,r2 // Add xtime.nsecs + cmp4.ne.or p7,p0 = r28,r10 +(p7) br.cond.dpnt.few .time_redo // sequence number changed ? + // Now r8=tv->tv_nsec and r9=tv->tv_sec + mov r10 = r0 + movl r2 = 1000000000 + add r23 = IA64_TIMESPEC_TV_NSEC_OFFSET, r31 +(p14) movl r3 = 2361183241434822607 // Prep for / 1000 hack + ;; +.time_normalize: + mov r21 = r8 + cmp.ge p6,p0 = r8,r2 +(p14) shr.u r20 = r8, 3 // We can repeat this if necessary just wasting some time + ;; +(p14) setf.sig f8 = r20 +(p6) sub r8 = r8,r2 +(p6) add r9 = 1,r9 // two nops before the branch. +(p14) setf.sig f7 = r3 // Chances for repeats are 1 in 10000 for gettod +(p6) br.cond.dpnt.few .time_normalize + ;; + // Divided by 8 though shift. Now divide by 125 + // The compiler was able to do that with a multiply + // and a shift and we do the same +EX(.fail_efault, probe.w.fault r23, 3) // This also costs 5 cycles +(p14) xmpy.hu f8 = f8, f7 // xmpy has 5 cycles latency so use it... ;; -(p8) cmp.ne.unc p9, p0=r24, r14 - xmpy.hu f6=f8, f9 // (5 cyc) -(p9) br.spnt.many .retry - ;; - - getf.sig r3=f6 // (6 cyc) + mov r8 = r0 +(p14) getf.sig r2 = f8 ;; - shr.u r3=r3, 4 // end of division, r3 is divided by 1000 (=usec) - ;; - -1: cmp.geu p7, p0=r3, r10 // while (usec >= 1000000) - ;; -(p7) sub r3=r3, r10 // usec -= 1000000 -(p7) adds r2=1, r2 // ++sec -(p7) br.spnt.many 1b - - // finally: r2 = sec, r3 = usec -EX(.fail_efault, st8 [r32]=r2) - adds r9=8, r32 - mov r8=r0 // success +(p14) shr.u r21 = r2, 4 ;; -EX(.fail_efault, st8 [r9]=r3) // store them in the timeval struct - mov r10=0 +EX(.fail_efault, st8 [r31] = r9) +EX(.fail_efault, st8 [r23] = r21) FSYS_RETURN - /* - * Note: We are NOT clearing the scratch registers here. Since the only things - * in those registers are time-related variables and some addresses (which - * can be obtained from System.map), none of this should be security-sensitive - * and we should be fine. - */ - .fail_einval: - mov r8=EINVAL // r8 = EINVAL - mov r10=-1 // r10 = -1 + mov r8 = EINVAL + mov r10 = -1 FSYS_RETURN - .fail_efault: - mov r8=EFAULT // r8 = EFAULT - mov r10=-1 // r10 = -1 + mov r8 = EFAULT + mov r10 = -1 FSYS_RETURN END(fsys_gettimeofday) +ENTRY(fsys_clock_gettime) + .prologue + .altrp b6 + .body + cmp4.lt p6, p0 = CLOCK_MONOTONIC, r32 + // Fallback if this is not CLOCK_REALTIME or CLOCK_MONOTONIC +(p6) br.spnt.few fsys_fallback_syscall + mov r31 = r33 + shl r30 = r32,15 + br.many .gettime +END(fsys_clock_gettime) + /* * long fsys_rt_sigprocmask (int how, sigset_t *set, sigset_t *oset, size_t sigsetsize). */ @@ -838,7 +851,7 @@ data8 0 // timer_getoverrun data8 0 // timer_delete data8 0 // clock_settime - data8 0 // clock_gettime + data8 fsys_clock_gettime // clock_gettime data8 0 // clock_getres // 1255 data8 0 // clock_nanosleep data8 0 // fstatfs64 diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c --- a/arch/ia64/kernel/perfmon.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/kernel/perfmon.c 2004-08-30 17:32:04 -07:00 @@ -2227,6 +2227,15 @@ static void pfm_free_fd(int fd, struct file *file) { + struct files_struct *files = current->files; + + /* + * there ie no fd_uninstall(), so we do it here + */ + spin_lock(&files->file_lock); + files->fd[fd] = NULL; + spin_unlock(&files->file_lock); + if (file) put_filp(file); put_unused_fd(fd); } @@ -2659,8 +2668,10 @@ ctx = pfm_context_alloc(); if (!ctx) goto error; - req->ctx_fd = ctx->ctx_fd = pfm_alloc_fd(&filp); - if (req->ctx_fd < 0) goto error_file; + ret = pfm_alloc_fd(&filp); + if (ret < 0) goto error_file; + + req->ctx_fd = ctx->ctx_fd = ret; /* * attach context to file diff -Nru a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c --- a/arch/ia64/kernel/sal.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/kernel/sal.c 2004-08-30 17:32:04 -07:00 @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -262,3 +263,40 @@ p += SAL_DESC_SIZE(*p); } } + +int +ia64_sal_oemcall(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1, + u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7) +{ + if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX) + return -1; + SAL_CALL(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return 0; +} +EXPORT_SYMBOL(ia64_sal_oemcall); + +int +ia64_sal_oemcall_nolock(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1, + u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, + u64 arg7) +{ + if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX) + return -1; + SAL_CALL_NOLOCK(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6, + arg7); + return 0; +} +EXPORT_SYMBOL(ia64_sal_oemcall_nolock); + +int +ia64_sal_oemcall_reentrant(struct ia64_sal_retval *isrvp, u64 oemfunc, + u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, + u64 arg6, u64 arg7) +{ + if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX) + return -1; + SAL_CALL_REENTRANT(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6, + arg7); + return 0; +} +EXPORT_SYMBOL(ia64_sal_oemcall_reentrant); diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c --- a/arch/ia64/kernel/time.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/kernel/time.c 2004-08-30 17:32:04 -07:00 @@ -45,46 +45,7 @@ #endif -static void -itc_reset (void) -{ -} - -/* - * Adjust for the fact that xtime has been advanced by delta_nsec (may be negative and/or - * larger than NSEC_PER_SEC. - */ -static void -itc_update (long delta_nsec) -{ -} - -/* - * Return the number of nano-seconds that elapsed since the last - * update to jiffy. It is quite possible that the timer interrupt - * will interrupt this and result in a race for any of jiffies, - * wall_jiffies or itm_next. Thus, the xtime_lock must be at least - * read synchronised when calling this routine (see do_gettimeofday() - * below for an example). - */ -unsigned long -itc_get_offset (void) -{ - unsigned long elapsed_cycles, lost = jiffies - wall_jiffies; - unsigned long now = ia64_get_itc(), last_tick; - - last_tick = (cpu_data(TIME_KEEPER_ID)->itm_next - - (lost + 1)*cpu_data(TIME_KEEPER_ID)->itm_delta); - - elapsed_cycles = now - last_tick; - return (elapsed_cycles*local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT; -} - -static struct time_interpolator itc_interpolator = { - .get_offset = itc_get_offset, - .update = itc_update, - .reset = itc_reset -}; +static struct time_interpolator itc_interpolator; int do_settimeofday (struct timespec *tv) @@ -127,51 +88,13 @@ void do_gettimeofday (struct timeval *tv) { - unsigned long seq, nsec, usec, sec, old, offset; - - while (1) { + unsigned long seq, nsec, usec, sec, offset; + do { seq = read_seqbegin(&xtime_lock); - { - old = last_nsec_offset; - offset = time_interpolator_get_offset(); - sec = xtime.tv_sec; - nsec = xtime.tv_nsec; - } - if (unlikely(read_seqretry(&xtime_lock, seq))) - continue; - /* - * Ensure that for any pair of causally ordered gettimeofday() calls, time - * never goes backwards (even when ITC on different CPUs are not perfectly - * synchronized). (A pair of concurrent calls to gettimeofday() is by - * definition non-causal and hence it makes no sense to talk about - * time-continuity for such calls.) - * - * Doing this in a lock-free and race-free manner is tricky. Here is why - * it works (most of the time): read_seqretry() just succeeded, which - * implies we calculated a consistent (valid) value for "offset". If the - * cmpxchg() below succeeds, we further know that last_nsec_offset still - * has the same value as at the beginning of the loop, so there was - * presumably no timer-tick or other updates to last_nsec_offset in the - * meantime. This isn't 100% true though: there _is_ a possibility of a - * timer-tick occurring right right after read_seqretry() and then getting - * zero or more other readers which will set last_nsec_offset to the same - * value as the one we read at the beginning of the loop. If this - * happens, we'll end up returning a slightly newer time than we ought to - * (the jump forward is at most "offset" nano-seconds). There is no - * danger of causing time to go backwards, though, so we are safe in that - * sense. We could make the probability of this unlucky case occurring - * arbitrarily small by encoding a version number in last_nsec_offset, but - * even without versioning, the probability of this unlucky case should be - * so small that we won't worry about it. - */ - if (offset <= old) { - offset = old; - break; - } else if (likely(cmpxchg(&last_nsec_offset, old, offset) == old)) - break; - - /* someone else beat us to updating last_nsec_offset; try again */ - } + offset = time_interpolator_get_offset(); + sec = xtime.tv_sec; + nsec = xtime.tv_nsec; + } while (unlikely(read_seqretry(&xtime_lock, seq))); usec = (nsec + offset) / 1000; @@ -277,6 +200,18 @@ ia64_set_itm(local_cpu_data->itm_next); } +static int nojitter; + +static int __init nojitter_setup(char *str) +{ + nojitter = 1; + printk("Jitter checking for ITC timers disabled\n"); + return 1; +} + +__setup("nojitter", nojitter_setup); + + void __devinit ia64_init_itm (void) { @@ -339,7 +274,23 @@ if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) { itc_interpolator.frequency = local_cpu_data->itc_freq; + itc_interpolator.shift = 16; itc_interpolator.drift = itc_drift; + itc_interpolator.source = TIME_SOURCE_CPU; +#ifdef CONFIG_SMP + /* On IA64 in an SMP configuration ITCs are never accurately synchronized. + * Jitter compensation requires a cmpxchg which may limit + * the scalability of the syscalls for retrieving time. + * The ITC synchronization is usually successful to within a few + * ITC ticks but this is not a sure thing. If you need to improve + * timer performance in SMP situations then boot the kernel with the + * "nojitter" option. However, doing so may result in time fluctuating (maybe + * even going backward) if the ITC offsets between the individual CPUs + * are too large. + */ + if (!nojitter) itc_interpolator.jitter = 1; +#endif + itc_interpolator.addr = NULL; register_time_interpolator(&itc_interpolator); } diff -Nru a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c --- a/arch/ia64/mm/contig.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/mm/contig.c 2004-08-30 17:32:04 -07:00 @@ -116,19 +116,19 @@ range_start = max(start, free_start); range_end = min(end, rsvd_region[i].start & PAGE_MASK); + free_start = PAGE_ALIGN(rsvd_region[i].end); + if (range_end <= range_start) continue; /* skip over empty range */ - if (range_end - range_start >= needed) { + if (range_end - range_start >= needed) { bootmap_start = __pa(range_start); - return 1; /* done */ + return -1; /* done */ } /* nothing more available in this segment */ if (range_end == end) return 0; - - free_start = PAGE_ALIGN(rsvd_region[i].end); } return 0; } diff -Nru a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig --- a/arch/ia64/oprofile/Kconfig 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/oprofile/Kconfig 2004-08-30 17:32:04 -07:00 @@ -16,6 +16,10 @@ whole system, include the kernel, kernel modules, libraries, and applications. + Due to firmware bugs, you may need to use the "nohalt" boot + option if you're using OProfile with the hardware performance + counters. + If unsure, say N. endmenu diff -Nru a/arch/ia64/oprofile/Makefile b/arch/ia64/oprofile/Makefile --- a/arch/ia64/oprofile/Makefile 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/oprofile/Makefile 2004-08-30 17:32:04 -07:00 @@ -7,3 +7,4 @@ timer_int.o ) oprofile-y := $(DRIVER_OBJS) init.o +oprofile-$(CONFIG_PERFMON) += perfmon.o diff -Nru a/arch/ia64/oprofile/init.c b/arch/ia64/oprofile/init.c --- a/arch/ia64/oprofile/init.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/oprofile/init.c 2004-08-30 17:32:04 -07:00 @@ -12,14 +12,21 @@ #include #include -extern void timer_init(struct oprofile_operations ** ops); +extern int perfmon_init(struct oprofile_operations ** ops); +extern void perfmon_exit(void); int __init oprofile_arch_init(struct oprofile_operations ** ops) { +#ifdef CONFIG_PERFMON + return perfmon_init(ops); +#endif return -ENODEV; } void oprofile_arch_exit(void) { +#ifdef CONFIG_PERFMON + perfmon_exit(); +#endif } diff -Nru a/arch/ia64/oprofile/perfmon.c b/arch/ia64/oprofile/perfmon.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ia64/oprofile/perfmon.c 2004-08-30 17:32:04 -07:00 @@ -0,0 +1,105 @@ +/** + * @file perfmon.c + * + * @remark Copyright 2003 OProfile authors + * @remark Read the file COPYING + * + * @author John Levon + */ + +#include +#include +#include +#include +#include +#include +#include + +static int allow_ints; + +static int +perfmon_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, + struct pt_regs *regs, unsigned long stamp) +{ + int cpu = smp_processor_id(); + unsigned long eip = instruction_pointer(regs); + int event = arg->pmd_eventid; + + arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1; + + /* the owner of the oprofile event buffer may have exited + * without perfmon being shutdown (e.g. SIGSEGV) + */ + if (allow_ints) + oprofile_add_sample(eip, !user_mode(regs), event, cpu); + return 0; +} + + +static int perfmon_start(void) +{ + allow_ints = 1; + return 0; +} + + +static void perfmon_stop(void) +{ + allow_ints = 0; +} + + +#define OPROFILE_FMT_UUID { \ + 0x77, 0x7a, 0x6e, 0x61, 0x20, 0x65, 0x73, 0x69, 0x74, 0x6e, 0x72, 0x20, 0x61, 0x65, 0x0a, 0x6c } + +static pfm_buffer_fmt_t oprofile_fmt = { + .fmt_name = "oprofile_format", + .fmt_uuid = OPROFILE_FMT_UUID, + .fmt_handler = perfmon_handler, +}; + + +static char * get_cpu_type(void) +{ + __u8 family = local_cpu_data->family; + + switch (family) { + case 0x07: + return "ia64/itanium"; + case 0x1f: + return "ia64/itanium2"; + default: + return "ia64/ia64"; + } +} + + +/* all the ops are handled via userspace for IA64 perfmon */ +static struct oprofile_operations perfmon_ops = { + .start = perfmon_start, + .stop = perfmon_stop, +}; + +static int using_perfmon; + +int perfmon_init(struct oprofile_operations ** ops) +{ + int ret = pfm_register_buffer_fmt(&oprofile_fmt); + if (ret) + return -ENODEV; + + perfmon_ops.cpu_type = get_cpu_type(); + *ops = &perfmon_ops; + using_perfmon = 1; + printk(KERN_INFO "oprofile: using perfmon.\n"); + return 0; +} + + +void perfmon_exit(void) +{ + if (!using_perfmon) + return; + + pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid); +} diff -Nru a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c --- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c 2004-08-30 17:32:04 -07:00 @@ -3,10 +3,10 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All Rights Reserved. * * Module to export the system's Firmware Interface Tables, including - * PROM revision numbers, in /proc + * PROM revision numbers and banners, in /proc */ #include #include @@ -45,9 +45,18 @@ # define TRACE() #endif +/* Architected IA64 firmware space */ +#define FW_BASE 0x00000000FF000000 +#define FW_TOP 0x0000000100000000 + /* Sub-regions determined by bits in Node Offset */ #define LB_PROM_SPACE 0x0000000700000000ul /* Local LB PROM */ +/* Offset of PROM banner pointers in SAL A and SAL B */ +#define SAL_A_BANNER_OFFSET (1 * 16) +#define SAL_B_BANNER_OFFSET (3 * 16) + + #define FIT_SIGNATURE 0x2020205f5449465ful /* Standard Intel FIT entry types */ #define FIT_ENTRY_FIT_HEADER 0x00 /* FIT header entry */ @@ -125,6 +134,26 @@ return "Unknown type"; } +static unsigned long +convert_fw_addr(nasid_t nasid, unsigned long addr) +{ + /* snag just the node-relative offset */ + addr &= ~0ul >> (63-35); + /* the pointer to SAL A is relative to IA-64 compatibility + * space. However, the PROM is mapped at a different offset + * in MMR space (both local and global) + */ + addr += 0x700000000; + return GLOBAL_MMR_ADDR(nasid, addr); +} + +static int +valid_fw_addr(unsigned long addr) +{ + addr &= ~(1ul << 63); /* Clear cached/uncached bit */ + return (addr >= FW_BASE && addr < FW_TOP); +} + /* These two routines read the FIT table directly from the FLASH PROM * on a specific node. The PROM can only be accessed using aligned 64 * bit reads, so we do that and then shift and mask the result to get @@ -194,6 +223,8 @@ int nentries; int fentry; unsigned long qw; + int len; + nasid_t nasid = NASID_GET(fit); TRACE(); @@ -203,10 +234,31 @@ for (fentry = 0; fentry < nentries; fentry++) { qw = readq(fit + 2 * fentry + 1); if (FIT_TYPE(qw) == FIT_ENTRY_SAL_A) - return sprintf(page, "%x.%02x\n", - FIT_MAJOR(qw), FIT_MINOR(qw)); + break; } - return 0; + if (fentry >= nentries) + return 0; + + len = sprintf(page, "%x.%02x\n", FIT_MAJOR(qw), FIT_MINOR(qw)); + page += len; + + qw = readq(fit + 2 * fentry); /* Address of SAL A */ + DPRINTK("SAL A at %p\n", (void *)qw); + if (!valid_fw_addr(qw)) + return len; + + qw += SAL_A_BANNER_OFFSET; + qw = convert_fw_addr(nasid, qw); + DPRINTK("Banner ptr at %p\n", (void *)qw); + + qw = readq(qw); /* Address of banner */ + if (!valid_fw_addr(qw)) + return len; + qw = convert_fw_addr(nasid, qw); + DPRINTK("Banner at %p\n", (void *)qw); + + len += snprintf(page, PAGE_SIZE-len, "%s\n", (char *)qw); + return len; } /* same as in proc_misc.c */ @@ -278,14 +330,10 @@ DPRINTK("pointer to fit at %p\n", (void *)fitp); fit_paddr = readq(fitp); DPRINTK("fit pointer contains %lx\n", fit_paddr); - /* snag just the node-relative offset */ - fit_paddr &= ~0ul >> (63-35); - /* the pointer to the FIT is relative to IA-64 compatibility - * space. However, the PROM is mapped at a different offset - * in MMR space (both local and global) - */ - fit_paddr += 0x700000000; - fit_vaddr = (void *)GLOBAL_MMR_ADDR(nasid, fit_paddr); + + BUG_ON(!valid_fw_addr(fit_paddr)); + fit_vaddr = (void *)convert_fw_addr(nasid, fit_paddr); + DPRINTK("fit at %p\n", (void *)fit_vaddr); return fit_vaddr; } diff -Nru a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c --- a/arch/ia64/sn/kernel/sn2/timer.c 2004-08-30 17:32:04 -07:00 +++ b/arch/ia64/sn/kernel/sn2/timer.c 2004-08-30 17:32:04 -07:00 @@ -20,57 +20,16 @@ extern unsigned long sn_rtc_cycles_per_second; -static volatile unsigned long last_wall_rtc; -static unsigned long rtc_offset; /* updated only when xtime write-lock is held! */ -static long rtc_nsecs_per_cycle; -static long rtc_per_timer_tick; - -static unsigned long -getoffset(void) -{ - return rtc_offset + (GET_RTC_COUNTER() - last_wall_rtc)*rtc_nsecs_per_cycle; -} - - -static void -update(long delta_nsec) -{ - unsigned long rtc_counter = GET_RTC_COUNTER(); - unsigned long offset = rtc_offset + (rtc_counter - last_wall_rtc)*rtc_nsecs_per_cycle; - - /* Be careful about signed/unsigned comparisons here: */ - if (delta_nsec < 0 || (unsigned long) delta_nsec < offset) - rtc_offset = offset - delta_nsec; - else - rtc_offset = 0; - last_wall_rtc = rtc_counter; -} - - -static void -reset(void) -{ - rtc_offset = 0; - last_wall_rtc = GET_RTC_COUNTER(); -} - - -static struct time_interpolator sn2_interpolator = { - .get_offset = getoffset, - .update = update, - .reset = reset -}; +static struct time_interpolator sn2_interpolator; void __init sn_timer_init(void) { sn2_interpolator.frequency = sn_rtc_cycles_per_second; sn2_interpolator.drift = -1; /* unknown */ + sn2_interpolator.shift = 10; /* RTC is 54 bits maximum shift is 10 */ + sn2_interpolator.addr = RTC_COUNTER_ADDR; + sn2_interpolator.source = TIME_SOURCE_MMIO64; register_time_interpolator(&sn2_interpolator); - - rtc_per_timer_tick = sn_rtc_cycles_per_second / HZ; - rtc_nsecs_per_cycle = 1000000000 / sn_rtc_cycles_per_second; - - last_wall_rtc = GET_RTC_COUNTER(); } diff -Nru a/drivers/char/hpet.c b/drivers/char/hpet.c --- a/drivers/char/hpet.c 2004-08-30 17:32:04 -07:00 +++ b/drivers/char/hpet.c 2004-08-30 17:32:04 -07:00 @@ -662,40 +662,10 @@ #ifdef CONFIG_TIME_INTERPOLATION -static unsigned long hpet_offset, last_wall_hpet; -static long hpet_nsecs_per_cycle, hpet_cycles_per_sec; - -static unsigned long hpet_getoffset(void) -{ - return hpet_offset + (read_counter(&hpets->hp_hpet->hpet_mc) - - last_wall_hpet) * hpet_nsecs_per_cycle; -} - -static void hpet_update(long delta) -{ - unsigned long mc; - unsigned long offset; - - mc = read_counter(&hpets->hp_hpet->hpet_mc); - offset = hpet_offset + (mc - last_wall_hpet) * hpet_nsecs_per_cycle; - - if (delta < 0 || (unsigned long)delta < offset) - hpet_offset = offset - delta; - else - hpet_offset = 0; - last_wall_hpet = mc; -} - -static void hpet_reset(void) -{ - hpet_offset = 0; - last_wall_hpet = read_counter(&hpets->hp_hpet->hpet_mc); -} - static struct time_interpolator hpet_interpolator = { - .get_offset = hpet_getoffset, - .update = hpet_update, - .reset = hpet_reset + .source = TIME_SOURCE_MMIO64, + .shift = 10, + .addr = MC }; #endif diff -Nru a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h --- a/include/asm-ia64/mmu_context.h 2004-08-30 17:32:04 -07:00 +++ b/include/asm-ia64/mmu_context.h 2004-08-30 17:32:04 -07:00 @@ -28,36 +28,6 @@ #include -#define MMU_CONTEXT_DEBUG 0 - -#if MMU_CONTEXT_DEBUG - -#include - -extern struct mmu_trace_entry { - char op; - u8 cpu; - u32 context; - void *mm; -} mmu_tbuf[1024]; - -extern volatile int mmu_tbuf_index; - -# define MMU_TRACE(_op,_cpu,_mm,_ctx) \ -do { \ - int i = __sync_fetch_and_add(&mmu_tbuf_index, 1) % ARRAY_SIZE(mmu_tbuf); \ - struct mmu_trace_entry e; \ - e.op = (_op); \ - e.cpu = (_cpu); \ - e.mm = (_mm); \ - e.context = (_ctx); \ - mmu_tbuf[i] = e; \ -} while (0) - -#else -# define MMU_TRACE(op,cpu,mm,ctx) do { ; } while (0) -#endif - struct ia64_ctx { spinlock_t lock; unsigned int next; /* next context number to use */ @@ -123,7 +93,6 @@ static inline int init_new_context (struct task_struct *p, struct mm_struct *mm) { - MMU_TRACE('N', smp_processor_id(), mm, 0); mm->context = 0; return 0; } @@ -132,7 +101,6 @@ destroy_context (struct mm_struct *mm) { /* Nothing to do. */ - MMU_TRACE('D', smp_processor_id(), mm, mm->context); } static inline void @@ -171,19 +139,14 @@ do { context = get_mmu_context(mm); - MMU_TRACE('A', smp_processor_id(), mm, context); if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) cpu_set(smp_processor_id(), mm->cpu_vm_mask); reload_context(context); - MMU_TRACE('a', smp_processor_id(), mm, context); /* in the unlikely event of a TLB-flush by another thread, redo the load: */ } while (unlikely(context != mm->context)); } -#define deactivate_mm(tsk,mm) \ -do { \ - MMU_TRACE('d', smp_processor_id(), mm, mm->context); \ -} while (0) +#define deactivate_mm(tsk,mm) do { } while (0) /* * Switch from address space PREV to address space NEXT. diff -Nru a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h --- a/include/asm-ia64/sal.h 2004-08-30 17:32:04 -07:00 +++ b/include/asm-ia64/sal.h 2004-08-30 17:32:04 -07:00 @@ -819,6 +819,16 @@ long r8; long r9; long r10; long r11; }; +#define IA64_SAL_OEMFUNC_MIN 0x02000000 +#define IA64_SAL_OEMFUNC_MAX 0x03ffffff + +extern int ia64_sal_oemcall(struct ia64_sal_retval *, u64, u64, u64, u64, u64, + u64, u64, u64); +extern int ia64_sal_oemcall_nolock(struct ia64_sal_retval *, u64, u64, u64, + u64, u64, u64, u64, u64); +extern int ia64_sal_oemcall_reentrant(struct ia64_sal_retval *, u64, u64, u64, + u64, u64, u64, u64, u64); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_IA64_SAL_H */ diff -Nru a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h --- a/include/asm-ia64/tlb.h 2004-08-30 17:32:04 -07:00 +++ b/include/asm-ia64/tlb.h 2004-08-30 17:32:04 -07:00 @@ -39,6 +39,7 @@ */ #include #include +#include #include #include diff -Nru a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h --- a/include/asm-ia64/tlbflush.h 2004-08-30 17:32:04 -07:00 +++ b/include/asm-ia64/tlbflush.h 2004-08-30 17:32:04 -07:00 @@ -48,22 +48,19 @@ static inline void flush_tlb_mm (struct mm_struct *mm) { - MMU_TRACE('F', smp_processor_id(), mm, mm->context); if (!mm) - goto out; + return; mm->context = 0; if (atomic_read(&mm->mm_users) == 0) - goto out; /* happens as a result of exit_mmap() */ + return; /* happens as a result of exit_mmap() */ #ifdef CONFIG_SMP smp_flush_tlb_mm(mm); #else local_finish_flush_tlb_mm(mm); #endif - out: - MMU_TRACE('f', smp_processor_id(), mm, mm->context); } extern void flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end); diff -Nru a/include/linux/timex.h b/include/linux/timex.h --- a/include/linux/timex.h 2004-08-30 17:32:04 -07:00 +++ b/include/linux/timex.h 2004-08-30 17:32:04 -07:00 @@ -47,14 +47,18 @@ * kernel PLL updated to 1994-12-13 specs (rfc-1589) * 1997-08-30 Ulrich Windl * Added new constant NTP_PHASE_LIMIT + * 2004-08-12 Christoph Lameter + * Reworked time interpolation logic */ #ifndef _LINUX_TIMEX_H #define _LINUX_TIMEX_H #include #include +#include #include +#include /* * The following defines establish the engineering parameters of the PLL @@ -320,81 +324,148 @@ #ifdef CONFIG_TIME_INTERPOLATION -struct time_interpolator { - /* cache-hot stuff first: */ - unsigned long (*get_offset) (void); - void (*update) (long); - void (*reset) (void); +#define TIME_SOURCE_CPU 0 +#define TIME_SOURCE_MMIO64 1 +#define TIME_SOURCE_MMIO32 2 +#define TIME_SOURCE_FUNCTION 3 + +/* For proper operations time_interpolator clocks must run slightly slower + * than the standard clock since the interpolator may only correct by having + * time jump forward during a tick. A slower clock is usually a side effect + * of the integer divide of the nanoseconds in a second by the frequency. + * The accuracy of the division can be increased by specifying a shift. + * However, this may cause the clock not to be slow enough. + * The interpolator will self-tune the clock by slowing down if no + * resets occur or speeding up if the time jumps per analysis cycle + * become too high. + * + * Setting jitter compensates for a fluctuating timesource by comparing + * to the last value read from the timesource to insure that an earlier value + * is not returned by a later call. The price to pay + * for the compensation is that the timer routines are not as scalable anymore. + */ - /* cache-cold stuff follows here: */ - struct time_interpolator *next; +#define INTERPOLATOR_ADJUST 65536 +#define INTERPOLATOR_MAX_SKIP 10*INTERPOLATOR_ADJUST + +struct time_interpolator { + unsigned short source; /* time source flags */ + unsigned char shift; /* increases accuracy of multiply by shifting. */ + /* Note that bits may be lost if shift is set too high */ + unsigned char jitter; /* if set compensate for fluctuations */ + unsigned nsec_per_cyc; /* set by register_time_interpolator() */ + void *addr; /* address of counter or function */ + unsigned long offset; /* nsec offset at last update of interpolator */ + unsigned long last_counter; /* counter value in units of the counter at last update */ + unsigned long last_cycle; /* Last timer value if TIME_SOURCE_JITTER is set */ unsigned long frequency; /* frequency in counts/second */ long drift; /* drift in parts-per-million (or -1) */ + unsigned long skips; /* skips forward */ + unsigned long ns_skipped; /* nanoseconds skipped */ + struct time_interpolator *next; }; -extern volatile unsigned long last_nsec_offset; -#ifndef __HAVE_ARCH_CMPXCHG -extern spin_lock_t last_nsec_offset_lock; -#endif extern struct time_interpolator *time_interpolator; -extern void register_time_interpolator(struct time_interpolator *); -extern void unregister_time_interpolator(struct time_interpolator *); +static inline unsigned long +time_interpolator_get_cycles(unsigned int src) +{ + unsigned long (*x)(void); -/* Called with xtime WRITE-lock acquired. */ -static inline void -time_interpolator_update(long delta_nsec) + switch (src) + { + case TIME_SOURCE_FUNCTION: + x = time_interpolator->addr; + return x(); + + case TIME_SOURCE_MMIO64 : + return readq(time_interpolator->addr); + + case TIME_SOURCE_MMIO32 : + return readl(time_interpolator->addr); + + default: return get_cycles(); + } +} + +static inline unsigned long +time_interpolator_get_counter(void) { - struct time_interpolator *ti = time_interpolator; + unsigned int src = time_interpolator->source; - if (last_nsec_offset > 0) { -#ifdef __HAVE_ARCH_CMPXCHG - unsigned long new, old; + if (time_interpolator->jitter) + { + unsigned long lcycle; + unsigned long now; do { - old = last_nsec_offset; - if (old > delta_nsec) - new = old - delta_nsec; - else - new = 0; - } while (cmpxchg(&last_nsec_offset, old, new) != old); -#else - /* - * This really hurts, because it serializes gettimeofday(), but without an - * atomic single-word compare-and-exchange, there isn't all that much else - * we can do. - */ - spin_lock(&last_nsec_offset_lock); - { - last_nsec_offset -= min(last_nsec_offset, delta_nsec); - } - spin_unlock(&last_nsec_offset_lock); -#endif + lcycle = time_interpolator->last_cycle; + now = time_interpolator_get_cycles(src); + if (lcycle && time_after(lcycle,now)) return lcycle; + /* Keep track of the last timer value returned. The use of cmpxchg here + * will cause contention in an SMP environment. + */ + } while (unlikely(cmpxchg(&time_interpolator->last_cycle,lcycle,now) != lcycle)); + return now; } - - if (ti) - (*ti->update)(delta_nsec); + else + return time_interpolator_get_cycles(src); } -/* Called with xtime WRITE-lock acquired. */ +extern void register_time_interpolator(struct time_interpolator *); +extern void unregister_time_interpolator(struct time_interpolator *); + static inline void time_interpolator_reset(void) { - struct time_interpolator *ti = time_interpolator; - - last_nsec_offset = 0; - if (ti) - (*ti->reset)(); + time_interpolator->offset = 0; + time_interpolator->last_counter = time_interpolator_get_counter(); } -/* Called with xtime READ-lock acquired. */ +#define GET_TI_NSECS(count,i) ((((count) - i->last_counter) * i->nsec_per_cyc) >> i->shift) + static inline unsigned long time_interpolator_get_offset(void) { - struct time_interpolator *ti = time_interpolator; - if (ti) - return (*ti->get_offset)(); - return last_nsec_offset; + return time_interpolator->offset + + GET_TI_NSECS(time_interpolator_get_counter(),time_interpolator); +} + +static inline void time_interpolator_update(long delta_nsec) +{ + unsigned long counter=time_interpolator_get_counter(); + unsigned long offset=time_interpolator->offset + GET_TI_NSECS(counter,time_interpolator); + + /* The interpolator compensates for late ticks by accumulating + * the late time in time_interpolator->offset. A tick earlier than + * expected will lead to a reset of the offset and a corresponding + * jump of the clock forward. Again this only works if the + * interpolator clock is running slightly slower than the regular clock + * and the tuning logic insures that. + */ + + if (delta_nsec < 0 || (unsigned long) delta_nsec < offset) + time_interpolator->offset = offset - delta_nsec; + else { + time_interpolator->skips++; + time_interpolator->ns_skipped += delta_nsec - offset; + time_interpolator->offset = 0; + } + time_interpolator->last_counter = counter; + + /* Tuning logic for time interpolator invoked every minute or so. + * Decrease interpolator clock speed if no skips occurred and an offset is carried. + * Increase interpolator clock speed if we skip too much time. + */ + if (jiffies % INTERPOLATOR_ADJUST == 0) + { + if (time_interpolator->skips == 0 && time_interpolator->offset > TICK_NSEC) + time_interpolator->nsec_per_cyc--; + if (time_interpolator->ns_skipped > INTERPOLATOR_MAX_SKIP && time_interpolator->offset == 0) + time_interpolator->nsec_per_cyc++; + time_interpolator->skips = 0; + time_interpolator->ns_skipped = 0; + } } #else /* !CONFIG_TIME_INTERPOLATION */ diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c --- a/kernel/posix-timers.c 2004-08-30 17:32:04 -07:00 +++ b/kernel/posix-timers.c 2004-08-30 17:32:04 -07:00 @@ -219,6 +219,11 @@ .clock_set = do_posix_clock_monotonic_settime }; +#ifdef CONFIG_TIME_INTERPOLATION + /* Clocks are more accurate with time interpolators */ + clock_realtime.res = clock_monotonic.res = NSEC_PER_SEC/time_interpolator->frequency; +#endif + register_posix_clock(CLOCK_REALTIME, &clock_realtime); register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic); diff -Nru a/kernel/timer.c b/kernel/timer.c --- a/kernel/timer.c 2004-08-30 17:32:04 -07:00 +++ b/kernel/timer.c 2004-08-30 17:32:04 -07:00 @@ -621,6 +621,9 @@ if (xtime.tv_sec % 86400 == 0) { xtime.tv_sec--; wall_to_monotonic.tv_sec++; + /* The timer interpolator will make time change gradually instead + * of an immediate jump by one second. + */ time_interpolator_update(-NSEC_PER_SEC); time_state = TIME_OOP; clock_was_set(); @@ -632,6 +635,7 @@ if ((xtime.tv_sec + 1) % 86400 == 0) { xtime.tv_sec++; wall_to_monotonic.tv_sec--; + /* Use of time interpolator for a gradual change of time */ time_interpolator_update(NSEC_PER_SEC); time_state = TIME_WAIT; clock_was_set(); @@ -1427,10 +1431,6 @@ } #ifdef CONFIG_TIME_INTERPOLATION -volatile unsigned long last_nsec_offset; -#ifndef __HAVE_ARCH_CMPXCHG -spinlock_t last_nsec_offset_lock = SPIN_LOCK_UNLOCKED; -#endif struct time_interpolator *time_interpolator; static struct time_interpolator *time_interpolator_list; @@ -1441,7 +1441,7 @@ { if (!time_interpolator) return 1; - return new->frequency > 2*time_interpolator->frequency || + return new->frequency > 2 * time_interpolator->frequency || (unsigned long)new->drift < (unsigned long)time_interpolator->drift; } @@ -1450,10 +1450,14 @@ { unsigned long flags; + ti->nsec_per_cyc = (NSEC_PER_SEC << ti->shift) / ti->frequency; spin_lock(&time_interpolator_lock); write_seqlock_irqsave(&xtime_lock, flags); if (is_better_time_interpolator(ti)) + { time_interpolator = ti; + time_interpolator_reset(); + } write_sequnlock_irqrestore(&xtime_lock, flags); ti->next = time_interpolator_list; @@ -1485,6 +1489,7 @@ for (curr = time_interpolator_list; curr; curr = curr->next) if (is_better_time_interpolator(curr)) time_interpolator = curr; + time_interpolator_reset(); } write_sequnlock_irqrestore(&xtime_lock, flags); spin_unlock(&time_interpolator_lock);