Date: Thu, 28 May 2009 18:26:19 +0000 (UTC) From: Dmitry Chagin <dchagin@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r192987 - in stable/7/sys: . amd64/linux32 compat/linux contrib/pf dev/ath/ath_hal dev/cxgb i386/linux Message-ID: <200905281826.n4SIQJ3D046065@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dchagin Date: Thu May 28 18:26:18 2009 New Revision: 192987 URL: http://svn.freebsd.org/changeset/base/192987 Log: Merge r191883,191966,191973 from HEAD to stable/7: Linux exports HZ value to user space via AT_CLKTCK auxiliary vector entry since 2.4.0. Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK), glibc falls back to the hard-coded CLK_TCK value when aux entry is not present. Glibc versions prior to 2.2.1 always use hard-coded CLK_TCK value. For older applications/libc's which depends on hard-coded CLK_TCK value user should set compat.linux.osrelease less than 2.4.0. linux_times() shall use the value that is exported to user space. PR: kern/134251 Approved by: kib (mentor) Modified: stable/7/sys/ (props changed) stable/7/sys/amd64/linux32/linux32_sysvec.c stable/7/sys/compat/linux/linux_mib.h stable/7/sys/compat/linux/linux_misc.c stable/7/sys/compat/linux/linux_misc.h stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) stable/7/sys/i386/linux/linux_sysvec.c Modified: stable/7/sys/amd64/linux32/linux32_sysvec.c ============================================================================== --- stable/7/sys/amd64/linux32/linux32_sysvec.c Thu May 28 18:11:09 2009 (r192986) +++ stable/7/sys/amd64/linux32/linux32_sysvec.c Thu May 28 18:26:18 2009 (r192987) @@ -263,7 +263,17 @@ elf_linux_fixup(register_t **stack_base, pos = base + (imgp->args->argc + imgp->args->envc + 2); AUXARGS_ENTRY_32(pos, LINUX_AT_HWCAP, cpu_feature); - AUXARGS_ENTRY_32(pos, LINUX_AT_CLKTCK, hz); + + /* + * Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0, + * as it has appeared in the 2.4.0-rc7 first time. + * Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK), + * glibc falls back to the hard-coded CLK_TCK value when aux entry + * is not present. + * Also see linux_times() implementation. + */ + if (linux_kernver(curthread) >= LINUX_KERNVER_2004000) + AUXARGS_ENTRY_32(pos, LINUX_AT_CLKTCK, stclohz); AUXARGS_ENTRY_32(pos, AT_PHDR, args->phdr); AUXARGS_ENTRY_32(pos, AT_PHENT, args->phent); AUXARGS_ENTRY_32(pos, AT_PHNUM, args->phnum); @@ -1120,6 +1130,7 @@ linux_elf_modevent(module_t mod, int typ linux_proc_exec, NULL, 1000); linux_szplatform = roundup(strlen(linux_platform) + 1, sizeof(char *)); + stclohz = (stathz ? stathz : hz); if (bootverbose) printf("Linux ELF exec handler installed\n"); } else Modified: stable/7/sys/compat/linux/linux_mib.h ============================================================================== --- stable/7/sys/compat/linux/linux_mib.h Thu May 28 18:11:09 2009 (r192986) +++ stable/7/sys/compat/linux/linux_mib.h Thu May 28 18:26:18 2009 (r192987) @@ -42,6 +42,7 @@ int linux_set_oss_version(struct thread int linux_kernver(struct thread *td); +#define LINUX_KERNVER_2004000 2004000 #define LINUX_KERNVER_2006000 2006000 #define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000) Modified: stable/7/sys/compat/linux/linux_misc.c ============================================================================== --- stable/7/sys/compat/linux/linux_misc.c Thu May 28 18:11:09 2009 (r192986) +++ stable/7/sys/compat/linux/linux_misc.c Thu May 28 18:26:18 2009 (r192987) @@ -90,6 +90,8 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_emul.h> #include <compat/linux/linux_misc.h> +int stclohz; /* Statistics clock frequency */ + #define BSD_TO_LINUX_SIGNAL(sig) \ (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) @@ -661,9 +663,19 @@ struct l_times_argv { l_clock_t tms_cstime; }; -#define CLK_TCK 100 /* Linux uses 100 */ -#define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) +/* + * Glibc versions prior to 2.2.1 always use hard-coded CLK_TCK value. + * Since 2.2.1 Glibc uses value exported from kernel via AT_CLKTCK + * auxiliary vector entry. + */ +#define CLK_TCK 100 + +#define CONVOTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) +#define CONVNTCK(r) (r.tv_sec * stclohz + r.tv_usec / (1000000 / stclohz)) + +#define CONVTCK(r) (linux_kernver(td) >= LINUX_KERNVER_2004000 ? \ + CONVNTCK(r) : CONVOTCK(r)) int linux_times(struct thread *td, struct linux_times_args *args) Modified: stable/7/sys/compat/linux/linux_misc.h ============================================================================== --- stable/7/sys/compat/linux/linux_misc.h Thu May 28 18:11:09 2009 (r192986) +++ stable/7/sys/compat/linux/linux_misc.h Thu May 28 18:26:18 2009 (r192987) @@ -65,4 +65,6 @@ extern const char *linux_platform; #define __LINUX_NPXCW__ 0x37f #endif +extern int stclohz; + #endif /* _LINUX_MISC_H_ */ Modified: stable/7/sys/i386/linux/linux_sysvec.c ============================================================================== --- stable/7/sys/i386/linux/linux_sysvec.c Thu May 28 18:11:09 2009 (r192986) +++ stable/7/sys/i386/linux/linux_sysvec.c Thu May 28 18:26:18 2009 (r192987) @@ -257,7 +257,17 @@ elf_linux_fixup(register_t **stack_base, pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature); - AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, hz); + + /* + * Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0, + * as it has appeared in the 2.4.0-rc7 first time. + * Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK), + * glibc falls back to the hard-coded CLK_TCK value when aux entry + * is not present. + * Also see linux_times() implementation. + */ + if (linux_kernver(curthread) >= LINUX_KERNVER_2004000) + AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz); AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); AUXARGS_ENTRY(pos, AT_PHENT, args->phent); AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); @@ -1091,6 +1101,7 @@ linux_elf_modevent(module_t mod, int typ linux_get_machine(&linux_platform); linux_szplatform = roundup(strlen(linux_platform) + 1, sizeof(char *)); + stclohz = (stathz ? stathz : hz); if (bootverbose) printf("Linux ELF exec handler installed\n"); } else
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905281826.n4SIQJ3D046065>