lockf: slightly depessimize

1. check if P_ADVLOCK is already set and if so, don't lock to set it
(stolen from DragonFly)
2. when trying for fast path unlock, check that we are doing unlock
first instead of taking the interlock for no reason (e.g. if we want
to *lock*). whilere make it more likely that falling fast path will
not take the interlock either by checking for state

Note the code is severely pessimized both single- and multithreaded.
This commit is contained in:
Mateusz Guzik 2018-04-22 09:30:07 +00:00
parent 2a2234c0f4
commit 7d853f62bf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=332870
2 changed files with 14 additions and 10 deletions

View File

@ -648,9 +648,11 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
error = EBADF;
break;
}
PROC_LOCK(p->p_leader);
p->p_leader->p_flag |= P_ADVLOCK;
PROC_UNLOCK(p->p_leader);
if ((p->p_leader->p_flag & P_ADVLOCK) == 0) {
PROC_LOCK(p->p_leader);
p->p_leader->p_flag |= P_ADVLOCK;
PROC_UNLOCK(p->p_leader);
}
error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK,
flp, flg);
break;
@ -659,9 +661,11 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
error = EBADF;
break;
}
PROC_LOCK(p->p_leader);
p->p_leader->p_flag |= P_ADVLOCK;
PROC_UNLOCK(p->p_leader);
if ((p->p_leader->p_flag & P_ADVLOCK) == 0) {
PROC_LOCK(p->p_leader);
p->p_leader->p_flag |= P_ADVLOCK;
PROC_UNLOCK(p->p_leader);
}
error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK,
flp, flg);
break;

View File

@ -479,15 +479,15 @@ lf_advlockasync(struct vop_advlockasync_args *ap, struct lockf **statep,
/*
* Avoid the common case of unlocking when inode has no locks.
*/
VI_LOCK(vp);
if ((*statep) == NULL) {
if (ap->a_op != F_SETLK) {
if (ap->a_op != F_SETLK && (*statep) == NULL) {
VI_LOCK(vp);
if ((*statep) == NULL) {
fl->l_type = F_UNLCK;
VI_UNLOCK(vp);
return (0);
}
VI_UNLOCK(vp);
}
VI_UNLOCK(vp);
/*
* Map our arguments to an existing lock owner or create one