aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-10-17 02:30:13 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 11:43:00 -0400
commit3e6c6f630a5282df8f3393a59f10eb9c56536d23 (patch)
tree744539fb9d35425784149e2f015589d593e2b968
parentfd5eea4214f72bd7ac77c1c5346a9c096319131a (diff)
Delay creation of khcvd thread
This changes hvc_init() to be called only when someone actually uses the hvc_console driver. Dave Jones complained when profiling bootup. hvc_console used to only be for Power aka pSeries: now lguest and Xen both want it built-in in case the kernel is a guest under one of those, even though usually it will be a native boot. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Cc: Paul Mackerras <paulus@samba.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Jeremy Fitzhardinge <jeremy@goop.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/hvc_console.c56
2 files changed, 42 insertions, 18 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 1232ace097e1..57b801716fbe 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -585,8 +585,8 @@ config TIPAR
585config HVC_DRIVER 585config HVC_DRIVER
586 bool 586 bool
587 help 587 help
588 Users of pSeries machines that want to utilize the hvc console front-end 588 Generic "hypervisor virtual console" infrastructure for various
589 module for their backend console driver should select this option. 589 hypervisors (pSeries, Xen, lguest).
590 It will automatically be selected if one of the back-end console drivers 590 It will automatically be selected if one of the back-end console drivers
591 is selected. 591 is selected.
592 592
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 83c1151ec7a2..8252f8668538 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -69,6 +69,8 @@ static struct task_struct *hvc_task;
69/* Picks up late kicks after list walk but before schedule() */ 69/* Picks up late kicks after list walk but before schedule() */
70static int hvc_kicked; 70static int hvc_kicked;
71 71
72static int hvc_init(void);
73
72#ifdef CONFIG_MAGIC_SYSRQ 74#ifdef CONFIG_MAGIC_SYSRQ
73static int sysrq_pressed; 75static int sysrq_pressed;
74#endif 76#endif
@@ -754,6 +756,13 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
754 struct hvc_struct *hp; 756 struct hvc_struct *hp;
755 int i; 757 int i;
756 758
759 /* We wait until a driver actually comes along */
760 if (!hvc_driver) {
761 int err = hvc_init();
762 if (err)
763 return ERR_PTR(err);
764 }
765
757 hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size, 766 hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size,
758 GFP_KERNEL); 767 GFP_KERNEL);
759 if (!hp) 768 if (!hp)
@@ -829,16 +838,18 @@ int __devexit hvc_remove(struct hvc_struct *hp)
829 return 0; 838 return 0;
830} 839}
831 840
832/* Driver initialization. Follow console initialization. This is where the TTY 841/* Driver initialization: called as soon as someone uses hvc_alloc(). */
833 * interfaces start to become available. */ 842static int hvc_init(void)
834static int __init hvc_init(void)
835{ 843{
836 struct tty_driver *drv; 844 struct tty_driver *drv;
845 int err;
837 846
838 /* We need more than hvc_count adapters due to hotplug additions. */ 847 /* We need more than hvc_count adapters due to hotplug additions. */
839 drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); 848 drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
840 if (!drv) 849 if (!drv) {
841 return -ENOMEM; 850 err = -ENOMEM;
851 goto out;
852 }
842 853
843 drv->owner = THIS_MODULE; 854 drv->owner = THIS_MODULE;
844 drv->driver_name = "hvc"; 855 drv->driver_name = "hvc";
@@ -854,30 +865,43 @@ static int __init hvc_init(void)
854 * added later. */ 865 * added later. */
855 hvc_task = kthread_run(khvcd, NULL, "khvcd"); 866 hvc_task = kthread_run(khvcd, NULL, "khvcd");
856 if (IS_ERR(hvc_task)) { 867 if (IS_ERR(hvc_task)) {
857 panic("Couldn't create kthread for console.\n"); 868 printk(KERN_ERR "Couldn't create kthread for console.\n");
858 put_tty_driver(drv); 869 err = PTR_ERR(hvc_task);
859 return -EIO; 870 goto put_tty;
860 } 871 }
861 872
862 if (tty_register_driver(drv)) 873 err = tty_register_driver(drv);
863 panic("Couldn't register hvc console driver\n"); 874 if (err) {
875 printk(KERN_ERR "Couldn't register hvc console driver\n");
876 goto stop_thread;
877 }
864 878
879 /* FIXME: This mb() seems completely random. Remove it. */
865 mb(); 880 mb();
866 hvc_driver = drv; 881 hvc_driver = drv;
867 return 0; 882 return 0;
883
884put_tty:
885 put_tty_driver(hvc_driver);
886stop_thread:
887 kthread_stop(hvc_task);
888 hvc_task = NULL;
889out:
890 return err;
868} 891}
869module_init(hvc_init);
870 892
871/* This isn't particularly necessary due to this being a console driver 893/* This isn't particularly necessary due to this being a console driver
872 * but it is nice to be thorough. 894 * but it is nice to be thorough.
873 */ 895 */
874static void __exit hvc_exit(void) 896static void __exit hvc_exit(void)
875{ 897{
876 kthread_stop(hvc_task); 898 if (hvc_driver) {
899 kthread_stop(hvc_task);
877 900
878 tty_unregister_driver(hvc_driver); 901 tty_unregister_driver(hvc_driver);
879 /* return tty_struct instances allocated in hvc_init(). */ 902 /* return tty_struct instances allocated in hvc_init(). */
880 put_tty_driver(hvc_driver); 903 put_tty_driver(hvc_driver);
881 unregister_console(&hvc_con_driver); 904 unregister_console(&hvc_con_driver);
905 }
882} 906}
883module_exit(hvc_exit); 907module_exit(hvc_exit);