From owner-freebsd-hackers@FreeBSD.ORG Fri May 8 17:24:03 2009 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E4FF4106566B for ; Fri, 8 May 2009 17:24:03 +0000 (UTC) (envelope-from brampton@gmail.com) Received: from mail-bw0-f165.google.com (mail-bw0-f165.google.com [209.85.218.165]) by mx1.freebsd.org (Postfix) with ESMTP id 5FDED8FC18 for ; Fri, 8 May 2009 17:24:03 +0000 (UTC) (envelope-from brampton@gmail.com) Received: by bwz9 with SMTP id 9so1490343bwz.43 for ; Fri, 08 May 2009 10:24:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:received:date :x-google-sender-auth:message-id:subject:from:to:content-type :content-transfer-encoding; bh=Pk7xbEe6XP8VDOgkzx/JmLKy3JyD3qfWpxU2Fsibe94=; b=Ul8Bs3L0dBzqadrVFOXOizJ0RFUX+f3t5tQVeg5qb6UTehFHyOiNi8ytnMGnda6EaC tMRAYc++TAKRsZVUkIHqltIi6JgLmvsLv/BjXqbDLvZgzD4cGPwfAXvyMXM8bsNJCKKO PpgFV92F7+1t3rwznKgKMS6ouIq+HxjN8lq8c= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type:content-transfer-encoding; b=FXAUt/0kZRJmtNZDQXKV7J9vh3CPyG9JzPXCx29swgfcscBZA8SvAf+lcEVUhcHWEq b7OevQ2r51kV8U2iaIGmI3wnxCytPRbxX09O6bhZbCdiegAThDaGZKlTasl7yCkBRB8a iET+ifn7TPWqz/Rz83L2Bw29jb3Ozb/Ar1dzM= MIME-Version: 1.0 Sender: brampton@gmail.com Received: by 10.223.122.15 with SMTP id j15mr2335538far.10.1241803442098; Fri, 08 May 2009 10:24:02 -0700 (PDT) Date: Fri, 8 May 2009 18:24:01 +0100 X-Google-Sender-Auth: b374440d6b8016dc Message-ID: From: Andrew Brampton To: freebsd-hackers@freebsd.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: kthreads and sched_relinquish X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 May 2009 17:24:04 -0000 Hi, I'm writing a FreeBSD kernel module and I think I really misunderstand something. My module spawns a thread, which should be running while the module is loaded. The thread does some work and then should yield for other threads. However, if there are no other threads waiting, then I would like to continue to do more work. The problem is that I am getting weird deadlocks so I wrote a simple test app to ask why this doesn't work: ------------------------ #include #include #include #include #include #include #include #include #include static void test_thread(void *blah) { unsigned int i = 100000000; /* Limit the number of iterations */ printf("Test Thread Started\n"); while (i > 0) { sched_relinquish(curthread); i--; } printf("Test Thread Exited\n"); kthread_exit(0); } /* The function called at load/unload. */ static int event_handler(struct module *module, int event, void *arg) { int e = 0; /* Error, 0 for normal return status */ switch (event) { case MOD_LOAD: printf("Test Module Loaded\n"); kthread_create(test_thread, NULL, NULL, 0, 0, "test"); break; case MOD_UNLOAD: printf("Test Module Unloaded\n"); break; default: e = EOPNOTSUPP; /* Error, Operation Not Supported */ } return e; } /* The second argument of DECLARE_MODULE. */ static moduledata_t test_conf = { "test_mod", /* module name */ event_handler, /* event handler */ NULL /* extra data */ }; DECLARE_MODULE(test_mod, test_conf, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); ---------------------------- While my thread is running the rest of the system is unresponsive. The thread should sched_relinquish() every time round the loop, and from my understanding that should yield to allow other threads to run, for example the thread which executes my shell (bash). I suspect my thread is yielding and getting instantly rescheduled. I noticed that poll_idle() in sys/kern_poll.c does something similar to me, but they first lower their priority. This however has not worked for me, since my more complex module interacts with higher priority threads and ends up deadlocking. So I just want to ask, Why does this example code lock the system? Am I using sched_relinquish correctly? Or should I be doing something else? I did try using tsleep(...,1), but I don't want my thread sleeping if there are no other threads waiting. I would also be grateful if people could point me at other examples in the kernel where something like this is done. I have looked in quite a few places, but I can't see why my simple app is wrong. thanks Andrew