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
This commit is contained in:
parent
f0c8263e55
commit
e015b1ab0a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=273707
@ -2628,8 +2628,12 @@ freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
|
|||||||
|
|
||||||
int
|
int
|
||||||
syscall32_register(int *offset, struct sysent *new_sysent,
|
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) {
|
if (*offset == NO_SYSCALL) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -2648,16 +2652,19 @@ syscall32_register(int *offset, struct sysent *new_sysent,
|
|||||||
|
|
||||||
*old_sysent = freebsd32_sysent[*offset];
|
*old_sysent = freebsd32_sysent[*offset];
|
||||||
freebsd32_sysent[*offset] = *new_sysent;
|
freebsd32_sysent[*offset] = *new_sysent;
|
||||||
return 0;
|
atomic_store_rel_32(&freebsd32_sysent[*offset].sy_thrcnt, flags);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
syscall32_deregister(int *offset, struct sysent *old_sysent)
|
syscall32_deregister(int *offset, struct sysent *old_sysent)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (*offset)
|
if (*offset == 0)
|
||||||
freebsd32_sysent[*offset] = *old_sysent;
|
return (0);
|
||||||
return 0;
|
|
||||||
|
freebsd32_sysent[*offset] = *old_sysent;
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -2670,7 +2677,7 @@ syscall32_module_handler(struct module *mod, int what, void *arg)
|
|||||||
switch (what) {
|
switch (what) {
|
||||||
case MOD_LOAD:
|
case MOD_LOAD:
|
||||||
error = syscall32_register(data->offset, data->new_sysent,
|
error = syscall32_register(data->offset, data->new_sysent,
|
||||||
&data->old_sysent);
|
&data->old_sysent, SY_THR_STATIC_KLD);
|
||||||
if (error) {
|
if (error) {
|
||||||
/* Leave a mark so we know to safely unload below. */
|
/* Leave a mark so we know to safely unload below. */
|
||||||
data->offset = NULL;
|
data->offset = NULL;
|
||||||
@ -2707,14 +2714,14 @@ syscall32_module_handler(struct module *mod, int what, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
syscall32_helper_register(struct syscall_helper_data *sd)
|
syscall32_helper_register(struct syscall_helper_data *sd, int flags)
|
||||||
{
|
{
|
||||||
struct syscall_helper_data *sd1;
|
struct syscall_helper_data *sd1;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
|
for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
|
||||||
error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent,
|
error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent,
|
||||||
&sd1->old_sysent);
|
&sd1->old_sysent, flags);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
syscall32_helper_unregister(sd);
|
syscall32_helper_unregister(sd);
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -98,10 +98,10 @@ SYSCALL32_MODULE(syscallname, \
|
|||||||
}
|
}
|
||||||
|
|
||||||
int syscall32_register(int *offset, struct sysent *new_sysent,
|
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_deregister(int *offset, struct sysent *old_sysent);
|
||||||
int syscall32_module_handler(struct module *mod, int what, void *arg);
|
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);
|
int syscall32_helper_unregister(struct syscall_helper_data *sd);
|
||||||
|
|
||||||
struct iovec32;
|
struct iovec32;
|
||||||
|
@ -105,10 +105,13 @@ syscall_thread_exit(struct thread *td, struct sysent *se)
|
|||||||
|
|
||||||
int
|
int
|
||||||
syscall_register(int *offset, struct sysent *new_sysent,
|
syscall_register(int *offset, struct sysent *new_sysent,
|
||||||
struct sysent *old_sysent)
|
struct sysent *old_sysent, int flags)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if ((flags & ~SY_THR_STATIC) != 0)
|
||||||
|
return (EINVAL);
|
||||||
|
|
||||||
if (*offset == NO_SYSCALL) {
|
if (*offset == NO_SYSCALL) {
|
||||||
for (i = 1; i < SYS_MAXSYSCALL; ++i)
|
for (i = 1; i < SYS_MAXSYSCALL; ++i)
|
||||||
if (sysent[i].sy_call == (sy_call_t *)lkmnosys)
|
if (sysent[i].sy_call == (sy_call_t *)lkmnosys)
|
||||||
@ -127,18 +130,23 @@ syscall_register(int *offset, struct sysent *new_sysent,
|
|||||||
*old_sysent = sysent[*offset];
|
*old_sysent = sysent[*offset];
|
||||||
new_sysent->sy_thrcnt = SY_THR_ABSENT;
|
new_sysent->sy_thrcnt = SY_THR_ABSENT;
|
||||||
sysent[*offset] = *new_sysent;
|
sysent[*offset] = *new_sysent;
|
||||||
atomic_store_rel_32(&sysent[*offset].sy_thrcnt, 0);
|
atomic_store_rel_32(&sysent[*offset].sy_thrcnt, flags);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
syscall_deregister(int *offset, struct sysent *old_sysent)
|
syscall_deregister(int *offset, struct sysent *old_sysent)
|
||||||
{
|
{
|
||||||
|
struct sysent *se;
|
||||||
|
|
||||||
if (*offset) {
|
if (*offset == 0)
|
||||||
syscall_thread_drain(&sysent[*offset]);
|
return (0); /* XXX? */
|
||||||
sysent[*offset] = *old_sysent;
|
|
||||||
}
|
se = &sysent[*offset];
|
||||||
|
if ((se->sy_thrcnt & SY_THR_STATIC) != 0)
|
||||||
|
return (EINVAL);
|
||||||
|
syscall_thread_drain(se);
|
||||||
|
sysent[*offset] = *old_sysent;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +160,7 @@ syscall_module_handler(struct module *mod, int what, void *arg)
|
|||||||
switch (what) {
|
switch (what) {
|
||||||
case MOD_LOAD:
|
case MOD_LOAD:
|
||||||
error = syscall_register(data->offset, data->new_sysent,
|
error = syscall_register(data->offset, data->new_sysent,
|
||||||
&data->old_sysent);
|
&data->old_sysent, SY_THR_STATIC_KLD);
|
||||||
if (error) {
|
if (error) {
|
||||||
/* Leave a mark so we know to safely unload below. */
|
/* Leave a mark so we know to safely unload below. */
|
||||||
data->offset = NULL;
|
data->offset = NULL;
|
||||||
@ -190,14 +198,14 @@ syscall_module_handler(struct module *mod, int what, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
syscall_helper_register(struct syscall_helper_data *sd)
|
syscall_helper_register(struct syscall_helper_data *sd, int flags)
|
||||||
{
|
{
|
||||||
struct syscall_helper_data *sd1;
|
struct syscall_helper_data *sd1;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
|
for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
|
||||||
error = syscall_register(&sd1->syscall_no, &sd1->new_sysent,
|
error = syscall_register(&sd1->syscall_no, &sd1->new_sysent,
|
||||||
&sd1->old_sysent);
|
&sd1->old_sysent, flags);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
syscall_helper_unregister(sd);
|
syscall_helper_unregister(sd);
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -252,11 +252,11 @@ msginit()
|
|||||||
}
|
}
|
||||||
mtx_init(&msq_mtx, "msq", NULL, MTX_DEF);
|
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)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
error = syscall32_helper_register(msg32_syscalls);
|
error = syscall32_helper_register(msg32_syscalls, SY_THR_STATIC_KLD);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
#endif
|
#endif
|
||||||
|
@ -278,11 +278,11 @@ seminit(void)
|
|||||||
semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
|
semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
|
||||||
EVENTHANDLER_PRI_ANY);
|
EVENTHANDLER_PRI_ANY);
|
||||||
|
|
||||||
error = syscall_helper_register(sem_syscalls);
|
error = syscall_helper_register(sem_syscalls, SY_THR_STATIC_KLD);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
error = syscall32_helper_register(sem32_syscalls);
|
error = syscall32_helper_register(sem32_syscalls, SY_THR_STATIC_KLD);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
#endif
|
#endif
|
||||||
|
@ -910,11 +910,11 @@ shminit()
|
|||||||
shmexit_hook = &shmexit_myhook;
|
shmexit_hook = &shmexit_myhook;
|
||||||
shmfork_hook = &shmfork_myhook;
|
shmfork_hook = &shmfork_myhook;
|
||||||
|
|
||||||
error = syscall_helper_register(shm_syscalls);
|
error = syscall_helper_register(shm_syscalls, SY_THR_STATIC_KLD);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
error = syscall32_helper_register(shm32_syscalls);
|
error = syscall32_helper_register(shm32_syscalls, SY_THR_STATIC_KLD);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2809,11 +2809,11 @@ mqinit(void)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = syscall_helper_register(mq_syscalls);
|
error = syscall_helper_register(mq_syscalls, SY_THR_STATIC_KLD);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
error = syscall32_helper_register(mq32_syscalls);
|
error = syscall32_helper_register(mq32_syscalls, SY_THR_STATIC_KLD);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
#endif
|
#endif
|
||||||
|
@ -993,11 +993,11 @@ ksem_module_init(void)
|
|||||||
p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
|
p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
|
||||||
p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_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)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
error = syscall32_helper_register(ksem32_syscalls);
|
error = syscall32_helper_register(ksem32_syscalls, SY_THR_STATIC_KLD);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
#endif
|
#endif
|
||||||
|
@ -511,11 +511,11 @@ aio_onceonly(void)
|
|||||||
p31b_setcfg(CTL_P1003_1B_AIO_MAX, MAX_AIO_QUEUE);
|
p31b_setcfg(CTL_P1003_1B_AIO_MAX, MAX_AIO_QUEUE);
|
||||||
p31b_setcfg(CTL_P1003_1B_AIO_PRIO_DELTA_MAX, 0);
|
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)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
error = syscall32_helper_register(aio32_syscalls);
|
error = syscall32_helper_register(aio32_syscalls, SY_THR_STATIC_KLD);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
#endif
|
#endif
|
||||||
|
@ -70,7 +70,7 @@ kgss_init(void *dummy)
|
|||||||
|
|
||||||
LIST_INIT(&kgss_mechs);
|
LIST_INIT(&kgss_mechs);
|
||||||
error = syscall_register(&gssd_syscall_offset, &gssd_syscall_sysent,
|
error = syscall_register(&gssd_syscall_offset, &gssd_syscall_sysent,
|
||||||
&gssd_syscall_prev_sysent);
|
&gssd_syscall_prev_sysent, SY_THR_STATIC_KLD);
|
||||||
if (error)
|
if (error)
|
||||||
printf("Can't register GSSD syscall\n");
|
printf("Can't register GSSD syscall\n");
|
||||||
else
|
else
|
||||||
|
@ -94,11 +94,11 @@ sctp_syscalls_init(void *unused __unused)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = syscall_helper_register(sctp_syscalls);
|
error = syscall_helper_register(sctp_syscalls, SY_THR_STATIC);
|
||||||
KASSERT((error == 0),
|
KASSERT((error == 0),
|
||||||
("%s: syscall_helper_register failed for sctp syscalls", __func__));
|
("%s: syscall_helper_register failed for sctp syscalls", __func__));
|
||||||
#ifdef COMPAT_FREEBSD32
|
#ifdef COMPAT_FREEBSD32
|
||||||
error = syscall32_helper_register(sctp_syscalls);
|
error = syscall32_helper_register(sctp_syscalls, SY_THR_STATIC);
|
||||||
KASSERT((error == 0),
|
KASSERT((error == 0),
|
||||||
("%s: syscall32_helper_register failed for sctp syscalls",
|
("%s: syscall32_helper_register failed for sctp syscalls",
|
||||||
__func__));
|
__func__));
|
||||||
|
@ -123,7 +123,7 @@ nfssvc_modevent(module_t mod, int type, void *data)
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case MOD_LOAD:
|
case MOD_LOAD:
|
||||||
error = syscall_register(&nfssvc_offset, &nfssvc_sysent,
|
error = syscall_register(&nfssvc_offset, &nfssvc_sysent,
|
||||||
&nfssvc_prev_sysent);
|
&nfssvc_prev_sysent, SY_THR_STATIC_KLD);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
registered = 1;
|
registered = 1;
|
||||||
|
@ -295,7 +295,7 @@ nlm_init(void *dummy)
|
|||||||
TAILQ_INIT(&nlm_hosts);
|
TAILQ_INIT(&nlm_hosts);
|
||||||
|
|
||||||
error = syscall_register(&nlm_syscall_offset, &nlm_syscall_sysent,
|
error = syscall_register(&nlm_syscall_offset, &nlm_syscall_sysent,
|
||||||
&nlm_syscall_prev_sysent);
|
&nlm_syscall_prev_sysent, SY_THR_STATIC_KLD);
|
||||||
if (error)
|
if (error)
|
||||||
NLM_ERR("Can't register NLM syscall\n");
|
NLM_ERR("Can't register NLM syscall\n");
|
||||||
else
|
else
|
||||||
|
@ -76,6 +76,12 @@ struct sysent { /* system call table */
|
|||||||
#define SY_THR_ABSENT 0x4
|
#define SY_THR_ABSENT 0x4
|
||||||
#define SY_THR_INCR 0x8
|
#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 image_params;
|
||||||
struct __sigset;
|
struct __sigset;
|
||||||
struct syscall_args;
|
struct syscall_args;
|
||||||
@ -242,10 +248,10 @@ struct syscall_helper_data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int syscall_register(int *offset, struct sysent *new_sysent,
|
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_deregister(int *offset, struct sysent *old_sysent);
|
||||||
int syscall_module_handler(struct module *mod, int what, void *arg);
|
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);
|
int syscall_helper_unregister(struct syscall_helper_data *sd);
|
||||||
|
|
||||||
struct proc;
|
struct proc;
|
||||||
|
Loading…
Reference in New Issue
Block a user