Avoid calls to syscall_thread_enter/exit for statically defined syscalls

The entire mechanism is rarely used and is quite not performant due to
atomci ops on the syscall table. It also has added overhead for completely
unrelated syscalls.

Reduce it by avoiding the func calls if possible (which consistutes vast
majority of cases).

Provides about 3% syscall rate speed up for getuid on Broadwell.
This commit is contained in:
Mateusz Guzik 2018-05-07 22:29:32 +00:00
parent a9456603f2
commit 79ca7cbf09
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333339
2 changed files with 22 additions and 8 deletions

View File

@ -80,14 +80,12 @@ syscall_thread_drain(struct sysent *se)
}
int
syscall_thread_enter(struct thread *td, struct sysent *se)
_syscall_thread_enter(struct thread *td, struct sysent *se)
{
u_int32_t cnt, oldcnt;
do {
oldcnt = se->sy_thrcnt;
if ((oldcnt & SY_THR_STATIC) != 0)
return (0);
if ((oldcnt & (SY_THR_DRAINING | SY_THR_ABSENT)) != 0)
return (ENOSYS);
cnt = oldcnt + SY_THR_INCR;
@ -96,14 +94,12 @@ syscall_thread_enter(struct thread *td, struct sysent *se)
}
void
syscall_thread_exit(struct thread *td, struct sysent *se)
_syscall_thread_exit(struct thread *td, struct sysent *se)
{
u_int32_t cnt, oldcnt;
do {
oldcnt = se->sy_thrcnt;
if ((oldcnt & SY_THR_STATIC) != 0)
return;
cnt = oldcnt - SY_THR_INCR;
} while (atomic_cmpset_rel_32(&se->sy_thrcnt, oldcnt, cnt) == 0);
}

View File

@ -289,8 +289,26 @@ struct nosys_args;
int lkmnosys(struct thread *, struct nosys_args *);
int lkmressys(struct thread *, struct nosys_args *);
int syscall_thread_enter(struct thread *td, struct sysent *se);
void syscall_thread_exit(struct thread *td, struct sysent *se);
int _syscall_thread_enter(struct thread *td, struct sysent *se);
void _syscall_thread_exit(struct thread *td, struct sysent *se);
static inline int
syscall_thread_enter(struct thread *td, struct sysent *se)
{
if (__predict_true((se->sy_thrcnt & SY_THR_STATIC) != 0))
return (0);
return (_syscall_thread_enter(td, se));
}
static inline void
syscall_thread_exit(struct thread *td, struct sysent *se)
{
if (__predict_true((se->sy_thrcnt & SY_THR_STATIC) != 0))
return;
_syscall_thread_exit(td, se);
}
int shared_page_alloc(int size, int align);
int shared_page_fill(int size, int align, const void *data);