ChangeSet 1.2276, 2005/03/31 08:41:23-08:00, [EMAIL PROTECTED]

        [PATCH] vt: don't call unblank at irq time
        
        This patch removes the call to unblank() from printk, and avoids calling
        unblank at irq() time _unless_ oops_in_progress is 1.  I also export
        oops_in_progress() so drivers who care like radeonfb can test it and 
know
        what to do.  I audited call sites of unblank_screen(), 
console_unblank(),
        etc...  and I _hope_ I got them all, the patch includes a small patch to
        the s390 bust_spinlocks code that sets oops_in_progress back to 0 
_after_
        unblanking for example.
        
        I added a few might_sleep() to help us catch possible remaining callers.
        
        I'll soon write a document explaining fbdev locking.  The current 
situation
        after this patch is that:
        
        - All callbacks have console_semaphore held (fbdev's are fully
          serialised).
        
        - Everything is called in schedule'able context, except the cfb_*
          rendering operations and cursor operations, with the special case of
          unblank who can be called at any time when "oops_in_progress" is 
true.  A
          driver that needs to sleep in it's unblank implementation is welcome 
to
          test that variable and use a fallback path (or just do nothing if it's
          not simple).
        
        Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]>
        Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
        Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>



 arch/s390/mm/fault.c |    2 +-
 drivers/char/vt.c    |   18 +++++++++++++++---
 kernel/printk.c      |   18 +++++++++++++-----
 3 files changed, 29 insertions(+), 9 deletions(-)


diff -Nru a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
--- a/arch/s390/mm/fault.c      2005-03-31 10:21:46 -08:00
+++ b/arch/s390/mm/fault.c      2005-03-31 10:21:46 -08:00
@@ -62,8 +62,8 @@
                oops_in_progress = 1;
        } else {
                int loglevel_save = console_loglevel;
-               oops_in_progress = 0;
                console_unblank();
+               oops_in_progress = 0;
                /*
                 * OK, the message is on the console.  Now we call printk()
                 * without oops_in_progress set so that printk will give klogd
diff -Nru a/drivers/char/vt.c b/drivers/char/vt.c
--- a/drivers/char/vt.c 2005-03-31 10:21:46 -08:00
+++ b/drivers/char/vt.c 2005-03-31 10:21:46 -08:00
@@ -2212,9 +2212,6 @@
        }
        set_cursor(vc);
 
-       if (!oops_in_progress)
-               poke_blanked_console();
-
 quit:
        clear_bit(0, &printing);
 }
@@ -2815,6 +2812,13 @@
 {
        struct vc_data *vc;
 
+       /* This should now always be called from a "sane" (read: can schedule)
+        * context for the sake of the low level drivers, except in the special
+        * case of oops_in_progress
+        */
+       if (!oops_in_progress)
+               might_sleep();
+
        WARN_CONSOLE_UNLOCKED();
 
        ignore_poke = 0;
@@ -2870,6 +2874,14 @@
 void poke_blanked_console(void)
 {
        WARN_CONSOLE_UNLOCKED();
+
+       /* Add this so we quickly catch whoever might call us in a non
+        * safe context. Nowadays, unblank_screen() isn't to be called in
+        * atomic contexts and is allowed to schedule (with the special case
+        * of oops_in_progress, but that isn't of any concern for this
+        * function. --BenH.
+        */
+       might_sleep();
 
        /* This isn't perfectly race free, but a race here would be mostly 
harmless,
         * at worse, we'll do a spurrious blank and it's unlikely
diff -Nru a/kernel/printk.c b/kernel/printk.c
--- a/kernel/printk.c   2005-03-31 10:21:46 -08:00
+++ b/kernel/printk.c   2005-03-31 10:21:46 -08:00
@@ -54,7 +54,12 @@
 
 EXPORT_SYMBOL(console_printk);
 
+/*
+ * Low lever drivers may need that to know if they can schedule in
+ * their unblank() callback or not. So let's export it.
+ */
 int oops_in_progress;
+EXPORT_SYMBOL(oops_in_progress);
 
 /*
  * console_sem protects the console_drivers list, and also
@@ -751,12 +756,15 @@
        struct console *c;
 
        /*
-        * Try to get the console semaphore. If someone else owns it
-        * we have to return without unblanking because console_unblank
-        * may be called in interrupt context.
+        * console_unblank can no longer be called in interrupt context unless
+        * oops_in_progress is set to 1..
         */
-       if (down_trylock(&console_sem) != 0)
-               return;
+       if (oops_in_progress) {
+               if (down_trylock(&console_sem) != 0)
+                       return;
+       } else
+               acquire_console_sem();
+
        console_locked = 1;
        console_may_schedule = 0;
        for (c = console_drivers; c != NULL; c = c->next)
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to