diff options
author | Alexander Leidinger <netchild@FreeBSD.org> | 2006-12-31 12:39:10 +0000 |
---|---|---|
committer | Alexander Leidinger <netchild@FreeBSD.org> | 2006-12-31 12:39:10 +0000 |
commit | 9ce8f9bcdd9d706c6990f6609914f710383a1590 (patch) | |
tree | 5f7a66921f13b7a6f4b7bf8ae9af0f639d8d2e9f /sys/compat | |
parent | ef95cfeab944437a09a8a396baac5213510aa528 (diff) | |
download | src-9ce8f9bcdd9d706c6990f6609914f710383a1590.tar.gz src-9ce8f9bcdd9d706c6990f6609914f710383a1590.zip |
MFp4 (111746+):
Redo the checking for 2.6 emulation. We now cache the value of
use26 and replace calls to linux_get_osrelease() + parsing with
a call to linux_use26(). Typical path is lockless now.
Pointed out by: kib
This allows to ship RELENG_7_0 with a default osrelease of 2.4.2 and the
possibility to enable 2.6.x emulation without the possible performance
impact of the previous version of the check.
Submitted by: rdivacky
Notes
Notes:
svn path=/head/; revision=165687
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linux/linux_mib.c | 28 | ||||
-rw-r--r-- | sys/compat/linux/linux_mib.h | 2 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 12 |
3 files changed, 33 insertions, 9 deletions
diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c index 0721d529bea0..3b025114371f 100644 --- a/sys/compat/linux/linux_mib.c +++ b/sys/compat/linux/linux_mib.c @@ -52,6 +52,7 @@ struct linux_prison { char pr_osname[LINUX_MAX_UTSNAME]; char pr_osrelease[LINUX_MAX_UTSNAME]; int pr_oss_version; + int pr_use_linux26; /* flag to determine whether to use 2.6 emulation */ }; SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0, @@ -82,6 +83,7 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, osname, "Linux kernel OS name"); static char linux_osrelease[LINUX_MAX_UTSNAME] = "2.4.2"; +static int linux_use_linux26 = 0; static int linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS) @@ -227,19 +229,45 @@ linux_get_osrelease(struct thread *td, char *dst) } int +linux_use26(struct thread *td) +{ + struct prison *pr; + struct linux_prison *lpr; + int use26 = 0; /* defaults to off */ + + pr = td->td_ucred->cr_prison; + if (pr != NULL) { + mtx_lock(&pr->pr_mtx); + if (pr->pr_linux != NULL) { + lpr = (struct linux_prison *)pr->pr_linux; + use26 = lpr->pr_use_linux26; + } + mtx_unlock(&pr->pr_mtx); + } else + use26 = linux_use_linux26; + + return (use26); +} + +int linux_set_osrelease(struct thread *td, char *osrelease) { struct prison *pr; struct linux_prison *lpr; + int use26; + + use26 = (strlen(osrelease) >= 3 && osrelease[2] == '6'); pr = linux_get_prison(td); if (pr != NULL) { lpr = (struct linux_prison *)pr->pr_linux; strcpy(lpr->pr_osrelease, osrelease); + lpr->pr_use_linux26 = use26; mtx_unlock(&pr->pr_mtx); } else { mtx_lock(&osname_lock); strcpy(linux_osrelease, osrelease); + linux_use_linux26 = use26; mtx_unlock(&osname_lock); } diff --git a/sys/compat/linux/linux_mib.h b/sys/compat/linux/linux_mib.h index 42d9d899266b..85f616352ad0 100644 --- a/sys/compat/linux/linux_mib.h +++ b/sys/compat/linux/linux_mib.h @@ -40,4 +40,6 @@ int linux_set_osrelease(struct thread *td, char *osrelease); int linux_get_oss_version(struct thread *td); int linux_set_oss_version(struct thread *td, int oss_version); +int linux_use26(struct thread *td); + #endif /* _LINUX_MIB_H_ */ diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 6fd69e066bf5..489b0790da64 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1400,15 +1400,13 @@ int linux_getpid(struct thread *td, struct linux_getpid_args *args) { struct linux_emuldata *em; - char osrel[LINUX_MAX_UTSNAME]; #ifdef DEBUG if (ldebug(getpid)) printf(ARGS(getpid, "")); #endif - linux_get_osrelease(td, osrel); - if (strlen(osrel) >= 3 && osrel[2] == '6') { + if (linux_use26(td)) { em = em_find(td->td_proc, EMUL_UNLOCKED); KASSERT(em != NULL, ("getpid: emuldata not found.\n")); td->td_retval[0] = em->shared->group_pid; @@ -1438,15 +1436,13 @@ linux_getppid(struct thread *td, struct linux_getppid_args *args) { struct linux_emuldata *em; struct proc *p, *pp; - char osrel[LINUX_MAX_UTSNAME]; #ifdef DEBUG if (ldebug(getppid)) printf(ARGS(getppid, "")); #endif - linux_get_osrelease(td, osrel); - if (strlen(osrel) >= 3 && osrel[2] != '6') { + if (!linux_use26(td)) { PROC_LOCK(td->td_proc); td->td_retval[0] = td->td_proc->p_pptr->p_pid; PROC_UNLOCK(td->td_proc); @@ -1573,15 +1569,13 @@ linux_exit_group(struct thread *td, struct linux_exit_group_args *args) { struct linux_emuldata *em, *td_em, *tmp_em; struct proc *sp; - char osrel[LINUX_MAX_UTSNAME]; #ifdef DEBUG if (ldebug(exit_group)) printf(ARGS(exit_group, "%i"), args->error_code); #endif - linux_get_osrelease(td, osrel); - if (strlen(osrel) >= 3 && osrel[2] == '6') { + if (linux_use26(td)) { td_em = em_find(td->td_proc, EMUL_UNLOCKED); KASSERT(td_em != NULL, ("exit_group: emuldata not found.\n")); |