From owner-svn-src-head@FreeBSD.ORG Sun Oct 26 19:42:48 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CF3844E7; Sun, 26 Oct 2014 19:42:48 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B0487E25; Sun, 26 Oct 2014 19:42:48 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s9QJgmpA081647; Sun, 26 Oct 2014 19:42:48 GMT (envelope-from mjg@FreeBSD.org) Received: (from mjg@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s9QJgjch081623; Sun, 26 Oct 2014 19:42:45 GMT (envelope-from mjg@FreeBSD.org) Message-Id: <201410261942.s9QJgjch081623@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: mjg set sender to mjg@FreeBSD.org using -f From: Mateusz Guzik Date: Sun, 26 Oct 2014 19:42:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r273707 - in head/sys: compat/freebsd32 kern kgssapi netinet nfs nlm sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 26 Oct 2014 19:42:48 -0000 Author: mjg Date: Sun Oct 26 19:42:44 2014 New Revision: 273707 URL: https://svnweb.freebsd.org/changeset/base/273707 Log: Avoid dynamic syscall overhead for statically compiled modules. The kernel tracks syscall users so that modules can safely unregister them. But if the module is not unloadable or was compiled into the kernel, there is no need to do this. Achieve this by adding SY_THR_STATIC_KLD macro which expands to SY_THR_STATIC during kernel build and 0 otherwise. Reviewed by: kib (previous version) MFC after: 2 weeks Modified: head/sys/compat/freebsd32/freebsd32_misc.c head/sys/compat/freebsd32/freebsd32_util.h head/sys/kern/kern_syscalls.c head/sys/kern/sysv_msg.c head/sys/kern/sysv_sem.c head/sys/kern/sysv_shm.c head/sys/kern/uipc_mqueue.c head/sys/kern/uipc_sem.c head/sys/kern/vfs_aio.c head/sys/kgssapi/gss_impl.c head/sys/netinet/sctp_syscalls.c head/sys/nfs/nfs_nfssvc.c head/sys/nlm/nlm_prot_impl.c head/sys/sys/sysent.h Modified: head/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_misc.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/compat/freebsd32/freebsd32_misc.c Sun Oct 26 19:42:44 2014 (r273707) @@ -2628,8 +2628,12 @@ freebsd32_xxx(struct thread *td, struct int syscall32_register(int *offset, struct sysent *new_sysent, - struct sysent *old_sysent) + struct sysent *old_sysent, int flags) { + + if ((flags & ~SY_THR_STATIC) != 0) + return (EINVAL); + if (*offset == NO_SYSCALL) { int i; @@ -2648,16 +2652,19 @@ syscall32_register(int *offset, struct s *old_sysent = freebsd32_sysent[*offset]; freebsd32_sysent[*offset] = *new_sysent; - return 0; + atomic_store_rel_32(&freebsd32_sysent[*offset].sy_thrcnt, flags); + return (0); } int syscall32_deregister(int *offset, struct sysent *old_sysent) { - if (*offset) - freebsd32_sysent[*offset] = *old_sysent; - return 0; + if (*offset == 0) + return (0); + + freebsd32_sysent[*offset] = *old_sysent; + return (0); } int @@ -2670,7 +2677,7 @@ syscall32_module_handler(struct module * switch (what) { case MOD_LOAD: error = syscall32_register(data->offset, data->new_sysent, - &data->old_sysent); + &data->old_sysent, SY_THR_STATIC_KLD); if (error) { /* Leave a mark so we know to safely unload below. */ data->offset = NULL; @@ -2707,14 +2714,14 @@ syscall32_module_handler(struct module * } int -syscall32_helper_register(struct syscall_helper_data *sd) +syscall32_helper_register(struct syscall_helper_data *sd, int flags) { struct syscall_helper_data *sd1; int error; for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) { error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent, - &sd1->old_sysent); + &sd1->old_sysent, flags); if (error != 0) { syscall32_helper_unregister(sd); return (error); Modified: head/sys/compat/freebsd32/freebsd32_util.h ============================================================================== --- head/sys/compat/freebsd32/freebsd32_util.h Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/compat/freebsd32/freebsd32_util.h Sun Oct 26 19:42:44 2014 (r273707) @@ -98,10 +98,10 @@ SYSCALL32_MODULE(syscallname, } int syscall32_register(int *offset, struct sysent *new_sysent, - struct sysent *old_sysent); + struct sysent *old_sysent, int flags); int syscall32_deregister(int *offset, struct sysent *old_sysent); int syscall32_module_handler(struct module *mod, int what, void *arg); -int syscall32_helper_register(struct syscall_helper_data *sd); +int syscall32_helper_register(struct syscall_helper_data *sd, int flags); int syscall32_helper_unregister(struct syscall_helper_data *sd); struct iovec32; Modified: head/sys/kern/kern_syscalls.c ============================================================================== --- head/sys/kern/kern_syscalls.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/kern/kern_syscalls.c Sun Oct 26 19:42:44 2014 (r273707) @@ -105,10 +105,13 @@ syscall_thread_exit(struct thread *td, s int syscall_register(int *offset, struct sysent *new_sysent, - struct sysent *old_sysent) + struct sysent *old_sysent, int flags) { int i; + if ((flags & ~SY_THR_STATIC) != 0) + return (EINVAL); + if (*offset == NO_SYSCALL) { for (i = 1; i < SYS_MAXSYSCALL; ++i) if (sysent[i].sy_call == (sy_call_t *)lkmnosys) @@ -127,18 +130,23 @@ syscall_register(int *offset, struct sys *old_sysent = sysent[*offset]; new_sysent->sy_thrcnt = SY_THR_ABSENT; sysent[*offset] = *new_sysent; - atomic_store_rel_32(&sysent[*offset].sy_thrcnt, 0); + atomic_store_rel_32(&sysent[*offset].sy_thrcnt, flags); return (0); } int syscall_deregister(int *offset, struct sysent *old_sysent) { + struct sysent *se; - if (*offset) { - syscall_thread_drain(&sysent[*offset]); - sysent[*offset] = *old_sysent; - } + if (*offset == 0) + return (0); /* XXX? */ + + se = &sysent[*offset]; + if ((se->sy_thrcnt & SY_THR_STATIC) != 0) + return (EINVAL); + syscall_thread_drain(se); + sysent[*offset] = *old_sysent; return (0); } @@ -152,7 +160,7 @@ syscall_module_handler(struct module *mo switch (what) { case MOD_LOAD: error = syscall_register(data->offset, data->new_sysent, - &data->old_sysent); + &data->old_sysent, SY_THR_STATIC_KLD); if (error) { /* Leave a mark so we know to safely unload below. */ data->offset = NULL; @@ -190,14 +198,14 @@ syscall_module_handler(struct module *mo } int -syscall_helper_register(struct syscall_helper_data *sd) +syscall_helper_register(struct syscall_helper_data *sd, int flags) { struct syscall_helper_data *sd1; int error; for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) { error = syscall_register(&sd1->syscall_no, &sd1->new_sysent, - &sd1->old_sysent); + &sd1->old_sysent, flags); if (error != 0) { syscall_helper_unregister(sd); return (error); Modified: head/sys/kern/sysv_msg.c ============================================================================== --- head/sys/kern/sysv_msg.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/kern/sysv_msg.c Sun Oct 26 19:42:44 2014 (r273707) @@ -252,11 +252,11 @@ msginit() } mtx_init(&msq_mtx, "msq", NULL, MTX_DEF); - error = syscall_helper_register(msg_syscalls); + error = syscall_helper_register(msg_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(msg32_syscalls); + error = syscall32_helper_register(msg32_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #endif Modified: head/sys/kern/sysv_sem.c ============================================================================== --- head/sys/kern/sysv_sem.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/kern/sysv_sem.c Sun Oct 26 19:42:44 2014 (r273707) @@ -278,11 +278,11 @@ seminit(void) semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL, EVENTHANDLER_PRI_ANY); - error = syscall_helper_register(sem_syscalls); + error = syscall_helper_register(sem_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(sem32_syscalls); + error = syscall32_helper_register(sem32_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #endif Modified: head/sys/kern/sysv_shm.c ============================================================================== --- head/sys/kern/sysv_shm.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/kern/sysv_shm.c Sun Oct 26 19:42:44 2014 (r273707) @@ -910,11 +910,11 @@ shminit() shmexit_hook = &shmexit_myhook; shmfork_hook = &shmfork_myhook; - error = syscall_helper_register(shm_syscalls); + error = syscall_helper_register(shm_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(shm32_syscalls); + error = syscall32_helper_register(shm32_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #endif Modified: head/sys/kern/uipc_mqueue.c ============================================================================== --- head/sys/kern/uipc_mqueue.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/kern/uipc_mqueue.c Sun Oct 26 19:42:44 2014 (r273707) @@ -2809,11 +2809,11 @@ mqinit(void) { int error; - error = syscall_helper_register(mq_syscalls); + error = syscall_helper_register(mq_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(mq32_syscalls); + error = syscall32_helper_register(mq32_syscalls, SY_THR_STATIC_KLD); if (error != 0) return (error); #endif Modified: head/sys/kern/uipc_sem.c ============================================================================== --- head/sys/kern/uipc_sem.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/kern/uipc_sem.c Sun Oct 26 19:42:44 2014 (r273707) @@ -993,11 +993,11 @@ ksem_module_init(void) p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX); p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX); - error = syscall_helper_register(ksem_syscalls); + error = syscall_helper_register(ksem_syscalls, SY_THR_STATIC_KLD); if (error) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(ksem32_syscalls); + error = syscall32_helper_register(ksem32_syscalls, SY_THR_STATIC_KLD); if (error) return (error); #endif Modified: head/sys/kern/vfs_aio.c ============================================================================== --- head/sys/kern/vfs_aio.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/kern/vfs_aio.c Sun Oct 26 19:42:44 2014 (r273707) @@ -511,11 +511,11 @@ aio_onceonly(void) p31b_setcfg(CTL_P1003_1B_AIO_MAX, MAX_AIO_QUEUE); p31b_setcfg(CTL_P1003_1B_AIO_PRIO_DELTA_MAX, 0); - error = syscall_helper_register(aio_syscalls); + error = syscall_helper_register(aio_syscalls, SY_THR_STATIC_KLD); if (error) return (error); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(aio32_syscalls); + error = syscall32_helper_register(aio32_syscalls, SY_THR_STATIC_KLD); if (error) return (error); #endif Modified: head/sys/kgssapi/gss_impl.c ============================================================================== --- head/sys/kgssapi/gss_impl.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/kgssapi/gss_impl.c Sun Oct 26 19:42:44 2014 (r273707) @@ -70,7 +70,7 @@ kgss_init(void *dummy) LIST_INIT(&kgss_mechs); error = syscall_register(&gssd_syscall_offset, &gssd_syscall_sysent, - &gssd_syscall_prev_sysent); + &gssd_syscall_prev_sysent, SY_THR_STATIC_KLD); if (error) printf("Can't register GSSD syscall\n"); else Modified: head/sys/netinet/sctp_syscalls.c ============================================================================== --- head/sys/netinet/sctp_syscalls.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/netinet/sctp_syscalls.c Sun Oct 26 19:42:44 2014 (r273707) @@ -94,11 +94,11 @@ sctp_syscalls_init(void *unused __unused { int error; - error = syscall_helper_register(sctp_syscalls); + error = syscall_helper_register(sctp_syscalls, SY_THR_STATIC); KASSERT((error == 0), ("%s: syscall_helper_register failed for sctp syscalls", __func__)); #ifdef COMPAT_FREEBSD32 - error = syscall32_helper_register(sctp_syscalls); + error = syscall32_helper_register(sctp_syscalls, SY_THR_STATIC); KASSERT((error == 0), ("%s: syscall32_helper_register failed for sctp syscalls", __func__)); Modified: head/sys/nfs/nfs_nfssvc.c ============================================================================== --- head/sys/nfs/nfs_nfssvc.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/nfs/nfs_nfssvc.c Sun Oct 26 19:42:44 2014 (r273707) @@ -123,7 +123,7 @@ nfssvc_modevent(module_t mod, int type, switch (type) { case MOD_LOAD: error = syscall_register(&nfssvc_offset, &nfssvc_sysent, - &nfssvc_prev_sysent); + &nfssvc_prev_sysent, SY_THR_STATIC_KLD); if (error) break; registered = 1; Modified: head/sys/nlm/nlm_prot_impl.c ============================================================================== --- head/sys/nlm/nlm_prot_impl.c Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/nlm/nlm_prot_impl.c Sun Oct 26 19:42:44 2014 (r273707) @@ -295,7 +295,7 @@ nlm_init(void *dummy) TAILQ_INIT(&nlm_hosts); error = syscall_register(&nlm_syscall_offset, &nlm_syscall_sysent, - &nlm_syscall_prev_sysent); + &nlm_syscall_prev_sysent, SY_THR_STATIC_KLD); if (error) NLM_ERR("Can't register NLM syscall\n"); else Modified: head/sys/sys/sysent.h ============================================================================== --- head/sys/sys/sysent.h Sun Oct 26 19:03:06 2014 (r273706) +++ head/sys/sys/sysent.h Sun Oct 26 19:42:44 2014 (r273707) @@ -76,6 +76,12 @@ struct sysent { /* system call table * #define SY_THR_ABSENT 0x4 #define SY_THR_INCR 0x8 +#ifdef KLD_MODULE +#define SY_THR_STATIC_KLD 0 +#else +#define SY_THR_STATIC_KLD SY_THR_STATIC +#endif + struct image_params; struct __sigset; struct syscall_args; @@ -242,10 +248,10 @@ struct syscall_helper_data { } int syscall_register(int *offset, struct sysent *new_sysent, - struct sysent *old_sysent); + struct sysent *old_sysent, int flags); int syscall_deregister(int *offset, struct sysent *old_sysent); int syscall_module_handler(struct module *mod, int what, void *arg); -int syscall_helper_register(struct syscall_helper_data *sd); +int syscall_helper_register(struct syscall_helper_data *sd, int flags); int syscall_helper_unregister(struct syscall_helper_data *sd); struct proc;