svn commit: r192987 - in stable/7/sys: . amd64/linux32 compat/linux contrib/pf dev/ath/ath_hal dev/cxgb i386/linux

Dmitry Chagin dchagin at FreeBSD.org
Thu May 28 18:26:20 UTC 2009


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


More information about the svn-src-all mailing list