From owner-freebsd-arch@FreeBSD.ORG Thu Sep 12 18:00:31 2013 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 9602D3CE; Thu, 12 Sep 2013 18:00:31 +0000 (UTC) (envelope-from dkandula@gmail.com) Received: from mail-wg0-x231.google.com (mail-wg0-x231.google.com [IPv6:2a00:1450:400c:c00::231]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id ECDD8250D; Thu, 12 Sep 2013 18:00:30 +0000 (UTC) Received: by mail-wg0-f49.google.com with SMTP id l18so149157wgh.4 for ; Thu, 12 Sep 2013 11:00:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=BNaQKmIfay73VNuYodkgNBVhFCTQbs7EranM2VPTVZw=; b=Hhogtid9SyRg5I/nuzSz7ygZ5SLFBzIx9BUuVJ/LiOx0BgvguDEATRms7icLBDF9LI yj4gwOaWR0mdRH784eJe+9pXEBNfvmLLWpP4902phbqUbJrjZ2/7019f3aSjn1wS3gAB +y6cqedi8j+pZuz4Y4qut35Y8YnMe8Yr2wJaM8a3S1vQezgDdjMeV6WpSH9ZL2Yv4miy 3KJwejT33LU82AtR/RS3NuLzppcP/bfQ68oNzZ8UhHR04cDhj2vwVMvPJtayBmxKhkf/ hC/lRGnZ0P9srtXKgXmco2clUP1BJGzXrkpzEsevoCvHa6TrQbpIo+STlBa9IQo1q0pj d+JA== MIME-Version: 1.0 X-Received: by 10.194.158.67 with SMTP id ws3mr7349703wjb.5.1379008829278; Thu, 12 Sep 2013 11:00:29 -0700 (PDT) Received: by 10.194.38.167 with HTTP; Thu, 12 Sep 2013 11:00:29 -0700 (PDT) In-Reply-To: <201309120824.52916.jhb@freebsd.org> References: <201309120824.52916.jhb@freebsd.org> Date: Thu, 12 Sep 2013 14:00:29 -0400 Message-ID: Subject: Re: Why do we need to acquire the current thread's lock before context switching? From: Dheeraj Kandula To: John Baldwin Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.14 Cc: Alfred Perlstein , Svatopluk Kraus , freebsd-arch@freebsd.org X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Sep 2013 18:00:31 -0000 Thanks John for the detailed clarification. Wow that is lot of information. I will digest it and will email you any further questions that I may have. Dheeraj On Thu, Sep 12, 2013 at 8:24 AM, John Baldwin wrote: > On Thursday, September 12, 2013 7:16:20 am Dheeraj Kandula wrote: > > Thanks a lot Svatopluk for the clarification. Right after I replied to > > Alfred's mail, I realized that it can't be thread specific lock as it > > should also protect the scheduler variables. So if I understand it righ= t, > > even though it is a mutex, it can be unlocked by another thread which i= s > > usually not the case with regular mutexes as the thread that locks it > must > > unlock it unlike a binary semaphore. Isn't it? > > It's less complicated than that. :) It is a mutex, but to expand on what > Svatopluk said with an example: take a thread that is asleep on a sleep > queue. td_lock points to the relevant SC_LOCK() for the sleep queue chai= n > in that case, so any other thread that wants to examine that thread's > state ends up locking the sleep queue while it examines that thread. In > particular, the thread that is doing a wakeup() can resume all of the > sleeping threads for a wait channel by holding the one SC_LOCK() for that > wait channel since that will be td_lock for all those threads. > > In general mutexes are only unlocked by the thread that locks them, > and the td_lock of the old thread is unlocked during sched_switch(). > However, the old thread has to grab td_lock of the new thread during > sched_switch() and then hand it off to the new thread when it resumes. > This is why sched_throw() and sched_switch() in ULE directly assign > 'mtx_lock' of the run queue lock before calling cpu_throw() or > cpu_switch(). That gives the effect that the new thread resumes while > holding the lock pinted to by its td_lock. > > > Dheeraj > > > > > > On Thu, Sep 12, 2013 at 7:04 AM, Svatopluk Kraus > wrote: > > > > > Think about td_lock like something what is lent by current thread > owner. > > > If a thread is running, it's owned by scheduler and td_lock points > > > to scheduler lock. If a thread is sleeping, it's owned by sleeping > queue > > > and td_lock points to sleep queue lock. If a thread is contested, it'= s > > > owned by turnstile queue and td_lock points to turnstile queue lock. > And so > > > on. This way an owner can work with owned threads safely without gian= t > > > lock. The td_lock pointer is changed atomically, so it's safe. > > > > > > Svatopluk Kraus > > > > > > On Thu, Sep 12, 2013 at 12:48 PM, Dheeraj Kandula >wrote: > > > > > >> Thanks a lot Alfred for the clarification. So is the td_lock granula= r > i.e. > > >> one separate lock for each thread but also used for protecting the > > >> scheduler variables or is it just one lock used by all threads and t= he > > >> scheduler as well. I will anyway go through the code that you > suggested > > >> but > > >> just wanted to have a deeper understanding before I go about hunting > in > > >> the > > >> code. > > >> > > >> Dheeraj > > >> > > >> > > >> On Thu, Sep 12, 2013 at 3:10 AM, Alfred Perlstein > wrote: > > >> > > >> > On 9/11/13 2:39 PM, Dheeraj Kandula wrote: > > >> > > > >> >> Hey All, > > >> >> > > >> >> When the current thread is being context switched with a newly > selected > > >> >> thread, why is the current thread's lock acquired before context > > >> switch =96 > > >> >> mi_switch() is invoked after thread_lock(td) is called. A thread > at any > > >> >> time runs only on one of the cores of a CPU. Hence when it is bei= ng > > >> >> context > > >> >> switched it is added either to the real time runq or the timeshar= e > > >> runq or > > >> >> the idle runq with the lock still held or it is added to the slee= p > > >> queue > > >> >> or > > >> >> the blocked queue. So this happens atomically even without the > lock. > > >> Isn't > > >> >> it? Am I missing something here? I don't see any contention for t= he > > >> thread > > >> >> in order to demand a lock for the thread which will basically > protect > > >> the > > >> >> contents of the thread structure for the thread. > > >> >> > > >> >> Dheeraj > > >> >> > > >> >> > > >> > The thread lock also happens to protect various scheduler variable= s: > > >> > > > >> > struct mtx *volatile td_lock; /* replaces sched lock = */ > > >> > > > >> > see sys/kern/sched_ule.c on how the thread lock td_lock is changed > > >> > depending on what the thread is doing. > > >> > > > >> > -- > > >> > Alfred Perlstein > > >> > > > >> > > > >> _______________________________________________ > > >> freebsd-arch@freebsd.org mailing list > > >> http://lists.freebsd.org/mailman/listinfo/freebsd-arch > > >> To unsubscribe, send any mail to " > freebsd-arch-unsubscribe@freebsd.org" > > >> > > > > > > > > _______________________________________________ > > freebsd-arch@freebsd.org mailing list > > http://lists.freebsd.org/mailman/listinfo/freebsd-arch > > To unsubscribe, send any mail to "freebsd-arch-unsubscribe@freebsd.org" > > > > -- > John Baldwin >