Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750942AbdHaEIQ (ORCPT ); Thu, 31 Aug 2017 00:08:16 -0400 Received: from mail.lotspeich.org ([23.21.113.224]:40008 "EHLO mail.lotspeich.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750733AbdHaEIP (ORCPT ); Thu, 31 Aug 2017 00:08:15 -0400 X-Greylist: delayed 1700 seconds by postgrey-1.27 at vger.kernel.org; Thu, 31 Aug 2017 00:08:15 EDT To: linux-kernel@vger.kernel.org From: Erik Lotspeich Subject: kthread behavior question Message-ID: Date: Wed, 30 Aug 2017 22:39:38 -0500 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="2680VID80jQLFrh9MJqM2E9FicnIPthRo" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4660 Lines: 174 This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --2680VID80jQLFrh9MJqM2E9FicnIPthRo Content-Type: multipart/mixed; boundary="wd8xPkXaeuCm8fw9qorwlPCoFSN2riCEk"; protected-headers="v1" From: Erik Lotspeich To: linux-kernel@vger.kernel.org Message-ID: Subject: kthread behavior question --wd8xPkXaeuCm8fw9qorwlPCoFSN2riCEk Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi, I have seen a behavior using kernel threads that I do not understand. I would like to know if there is a real issue within the kernel or if I am expecting something that is not possible. I have donned the flame suit. I would expect the kernel module listed below to load successfully and run, albeit with a very heavy load on the system. On the following OS environments, this is the case: * OpenSuSE 12.3 x86_64 (kernel: 3.7.10-1.45-desktop) VMware Workstation 12.5.7, 1GB RAM, 2 processors * OpenSuSE Leap 42.1 x86_64 (kernel: 4.1.39-56-default) VMware Workstation 12.5.7, 4GB RAM, 4 processors I would expect the behavior I described above due to the fact that kernel threads run in process context and timer interrupt results in a running of the scheduler thus allowing the system to function even under the load caused by the busy loops in the threads. What boggles my mind is why insmodding this kernel module on bare metal systems (no VM) causes an instant lockup of the system. There is no output to the VGA or serial consoles at all (even the printks that should be printed before the threads started implying that buffers couldn't even be flushed). It seems that in this case, the timer interrupt is getting lost or something. But this is weird because interrupts shouldn't be disabled for normal kthreads. Here are the bare metal systems that I've tried: * Slackware i686 (kernel: custom Linux 3.18.18) Intel Pentium III, 512MB = RAM * OpenSuSE Leap 42.2 x86_64 (kernel: 4.4.79-18.26-default), Intel Celeron J3060 (2 cores, no hyperthreading), 4GB RAM I don't understand the difference on bare metal vs. VM. It seems that if the lockup is the expected behavior, it wouldn't work on the VM environment. Also, the behavior does not seem to be affected by 3.x vs 4.x kernel or 32-bit vs 64-bit. Of course, if I enable the yield() in the code below, the kernel module loads and runs as expected in all cases. Any advice, thoughts, questions, or comments greatly appreciated. Thanks! Regards Erik P.S. Yes, I know I should have locking around my counter variable if this was a real program doing important work. But I'm trying to create the simplest example that shows the behavior. ** Begin threadtest.c ** #include #include #include #include #include #define NTHREADS 10 #define YIELD_ENABLED 0 static struct task_struct *test_th[NTHREADS]; static struct task_struct *monitor_th; static volatile int val =3D 0; static int monitor_thread(void *); static int test_thread(void *); int monitor_thread(void *arg) { while (! kthread_should_stop()) { printk("%s val: %d\n", __func__, val); msleep_interruptible(5000); } return 0; } int test_thread(void *arg) { int *num =3D (int *)arg; printk("%s %d started\n", __func__, *num); while (! kthread_should_stop()) { val++; #if YIELD_ENABLED yield(); #endif } printk("%s %d stopping\n", __func__, *num); if (num) { kfree(num); } return 0; } int __init threadtest_init(void) { int i; printk("%s\n", __func__); for (i =3D 0; i < NTHREADS; i++) { int *num =3D kmalloc(sizeof(int), GFP_KERNEL); *num =3D i; test_th[i] =3D kthread_run(test_thread, num, "test_th_%d", i); } monitor_th =3D kthread_run(monitor_thread, NULL, "monitor_th"); return 0; } void __exit threadtest_exit(void) { int i; if (monitor_th) { kthread_stop(monitor_th); } for (i =3D 0; i < NTHREADS; i++) { if (test_th[i]) { kthread_stop(test_th[i]); } } printk("%s val: %d\n", __func__, val); } module_init(threadtest_init); module_exit(threadtest_exit); MODULE_AUTHOR(""); MODULE_LICENSE("GPL"); ** End threadtest.c ** --wd8xPkXaeuCm8fw9qorwlPCoFSN2riCEk-- --2680VID80jQLFrh9MJqM2E9FicnIPthRo Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iEYEARECAAYFAlmnhQcACgkQY21D/n6bGwfLpwCgw/gx9AP9E/Im4+TH5XU8++d9 H2wAn3Qmzd0HDE4+M18MB2GgAZtdtSAM =1zYd -----END PGP SIGNATURE----- --2680VID80jQLFrh9MJqM2E9FicnIPthRo--