From owner-freebsd-current Mon Feb 11 19:40:23 2002 Delivered-To: freebsd-current@freebsd.org Received: from newman2.bestweb.net (newman2.bestweb.net [209.94.102.67]) by hub.freebsd.org (Postfix) with ESMTP id A2FA537B69E for ; Mon, 11 Feb 2002 18:19:40 -0800 (PST) Received: from okeeffe.bestweb.net (okeefe.bestweb.net [209.94.100.110]) by newman2.bestweb.net (Postfix) with ESMTP id 4811423344; Mon, 11 Feb 2002 21:18:28 -0500 (EST) Received: by okeeffe.bestweb.net (Postfix, from userid 0) id C93779F019; Mon, 11 Feb 2002 21:12:58 -0500 (EST) Date: Fri, 8 Feb 2002 20:20:40 +1100 (EST) From: Bruce Evans To: Julian Elischer Cc: Subject: Re: ucred for threads Message-Id: <20020212021258.C93779F019@okeeffe.bestweb.net> Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Thu, 7 Feb 2002, Julian Elischer wrote: > As part of the KSe stuff I ended up changing ht ebehaviour of threads with > respect to their ucreds. Previously, they freed their ucred reference when > they entered user space and picked them up again when they re-entered the > kernel. It there was an AST then they re-loaded teh already freed ucred to > perform the AST. (and then freed it again, (For each AST). > Since each 'get' and free required a lock and unlock of the proc > structure, this meant that there were at least 2 locks and 2 unlocks, and > possibly many more, for the average kernel entry/exit pair. The 2 locks and 2 unlocks pessimized syscall overhead by 10-20%. > Since the chance that the ucred on the next entry is not the same as the > thread already had on it's last kernel exit, is almiost negligible, > it makes sence to hold the ucred acress the user period an dsimply check > it agains the process's ucred on th enext entry. > > In the KSE code I have: > in trap(), and syscall() > > if (td->td_ucred != p->p_ucred) { > PROC_LOCK(p); > if (td->td_ucred) { > crfree(td->td_ucred); > td->td_ucred = NULL; > } > if (p->p_ucred != NULL) { > td->td_ucred = crhold(p->p_ucred); > } > PROC_UNLOCK(p); > } I deleted too much of the followup to this, so I can't quote it. Races here could be reduced by putting some sort of synchronization instruction at the beginning. Then there would only be a race between executing the sync instruction and checking p_ucred. The race window could be very large if the process is preempted in between. But this race is obviously unavoidable in the current framework. You may end up with a slightly stale td_ucred, but this is insignificantly different from ending up with a slightly stale td_ucred when p_ucred changes just after you release the lock. Both can have almost any amount of staleness if processes can be preempted... Without the sync instruction, the race starts a little earlier, in userland. It's not so obvious that the effects of this race are not really different from the the effects of p_ucred changing after you release the lock, but I think they are. Terry argued this point from a different viewpoint. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message