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:
parent
a9456603f2
commit
79ca7cbf09
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333339
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user