svn commit: r273707 - in head/sys: compat/freebsd32 kern kgssapi netinet nfs nlm sys

Mateusz Guzik mjg at FreeBSD.org
Sun Oct 26 19:42:48 UTC 2014


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;


More information about the svn-src-head mailing list