LCOV - code coverage report
Current view: top level - kernel/irq - spurious.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 14 110 12.7 %
Date: 2014-02-18 Functions: 1 9 11.1 %
Branches: 14 102 13.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * linux/kernel/irq/spurious.c
       3                 :            :  *
       4                 :            :  * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
       5                 :            :  *
       6                 :            :  * This file contains spurious interrupt handling.
       7                 :            :  */
       8                 :            : 
       9                 :            : #include <linux/jiffies.h>
      10                 :            : #include <linux/irq.h>
      11                 :            : #include <linux/module.h>
      12                 :            : #include <linux/kallsyms.h>
      13                 :            : #include <linux/interrupt.h>
      14                 :            : #include <linux/moduleparam.h>
      15                 :            : #include <linux/timer.h>
      16                 :            : 
      17                 :            : #include "internals.h"
      18                 :            : 
      19                 :            : static int irqfixup __read_mostly;
      20                 :            : 
      21                 :            : #define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10)
      22                 :            : static void poll_spurious_irqs(unsigned long dummy);
      23                 :            : static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs, 0, 0);
      24                 :            : static int irq_poll_cpu;
      25                 :            : static atomic_t irq_poll_active;
      26                 :            : 
      27                 :            : /*
      28                 :            :  * We wait here for a poller to finish.
      29                 :            :  *
      30                 :            :  * If the poll runs on this CPU, then we yell loudly and return
      31                 :            :  * false. That will leave the interrupt line disabled in the worst
      32                 :            :  * case, but it should never happen.
      33                 :            :  *
      34                 :            :  * We wait until the poller is done and then recheck disabled and
      35                 :            :  * action (about to be disabled). Only if it's still active, we return
      36                 :            :  * true and let the handler run.
      37                 :            :  */
      38                 :          0 : bool irq_wait_for_poll(struct irq_desc *desc)
      39                 :            : {
      40 [ #  # ][ #  # ]:          0 :         if (WARN_ONCE(irq_poll_cpu == smp_processor_id(),
         [ #  # ][ #  # ]
      41                 :            :                       "irq poll in progress on cpu %d for irq %d\n",
      42                 :            :                       smp_processor_id(), desc->irq_data.irq))
      43                 :            :                 return false;
      44                 :            : 
      45                 :            : #ifdef CONFIG_SMP
      46                 :            :         do {
      47                 :            :                 raw_spin_unlock(&desc->lock);
      48         [ #  # ]:          0 :                 while (irqd_irq_inprogress(&desc->irq_data))
      49                 :          0 :                         cpu_relax();
      50                 :          0 :                 raw_spin_lock(&desc->lock);
      51         [ #  # ]:          0 :         } while (irqd_irq_inprogress(&desc->irq_data));
      52                 :            :         /* Might have been disabled in meantime */
      53 [ #  # ][ #  # ]:          0 :         return !irqd_irq_disabled(&desc->irq_data) && desc->action;
      54                 :            : #else
      55                 :            :         return false;
      56                 :            : #endif
      57                 :            : }
      58                 :            : 
      59                 :            : 
      60                 :            : /*
      61                 :            :  * Recovery handler for misrouted interrupts.
      62                 :            :  */
      63                 :          0 : static int try_one_irq(int irq, struct irq_desc *desc, bool force)
      64                 :            : {
      65                 :            :         irqreturn_t ret = IRQ_NONE;
      66                 :            :         struct irqaction *action;
      67                 :            : 
      68                 :          0 :         raw_spin_lock(&desc->lock);
      69                 :            : 
      70                 :            :         /*
      71                 :            :          * PER_CPU, nested thread interrupts and interrupts explicitely
      72                 :            :          * marked polled are excluded from polling.
      73                 :            :          */
      74 [ #  # ][ #  # ]:          0 :         if (irq_settings_is_per_cpu(desc) ||
      75         [ #  # ]:          0 :             irq_settings_is_nested_thread(desc) ||
      76                 :            :             irq_settings_is_polled(desc))
      77                 :            :                 goto out;
      78                 :            : 
      79                 :            :         /*
      80                 :            :          * Do not poll disabled interrupts unless the spurious
      81                 :            :          * disabled poller asks explicitely.
      82                 :            :          */
      83 [ #  # ][ #  # ]:          0 :         if (irqd_irq_disabled(&desc->irq_data) && !force)
      84                 :            :                 goto out;
      85                 :            : 
      86                 :            :         /*
      87                 :            :          * All handlers must agree on IRQF_SHARED, so we test just the
      88                 :            :          * first.
      89                 :            :          */
      90                 :          0 :         action = desc->action;
      91 [ #  # ][ #  # ]:          0 :         if (!action || !(action->flags & IRQF_SHARED) ||
      92                 :            :             (action->flags & __IRQF_TIMER))
      93                 :            :                 goto out;
      94                 :            : 
      95                 :            :         /* Already running on another processor */
      96         [ #  # ]:          0 :         if (irqd_irq_inprogress(&desc->irq_data)) {
      97                 :            :                 /*
      98                 :            :                  * Already running: If it is shared get the other
      99                 :            :                  * CPU to go looking for our mystery interrupt too
     100                 :            :                  */
     101                 :          0 :                 desc->istate |= IRQS_PENDING;
     102                 :            :                 goto out;
     103                 :            :         }
     104                 :            : 
     105                 :            :         /* Mark it poll in progress */
     106                 :          0 :         desc->istate |= IRQS_POLL_INPROGRESS;
     107                 :            :         do {
     108         [ #  # ]:          0 :                 if (handle_irq_event(desc) == IRQ_HANDLED)
     109                 :            :                         ret = IRQ_HANDLED;
     110                 :            :                 /* Make sure that there is still a valid action */
     111                 :          0 :                 action = desc->action;
     112 [ #  # ][ #  # ]:          0 :         } while ((desc->istate & IRQS_PENDING) && action);
     113                 :          0 :         desc->istate &= ~IRQS_POLL_INPROGRESS;
     114                 :            : out:
     115                 :            :         raw_spin_unlock(&desc->lock);
     116                 :          0 :         return ret == IRQ_HANDLED;
     117                 :            : }
     118                 :            : 
     119                 :          0 : static int misrouted_irq(int irq)
     120                 :            : {
     121                 :            :         struct irq_desc *desc;
     122                 :            :         int i, ok = 0;
     123                 :            : 
     124         [ #  # ]:          0 :         if (atomic_inc_return(&irq_poll_active) != 1)
     125                 :            :                 goto out;
     126                 :            : 
     127                 :          0 :         irq_poll_cpu = smp_processor_id();
     128                 :            : 
     129 [ #  # ][ #  # ]:          0 :         for_each_irq_desc(i, desc) {
     130         [ #  # ]:          0 :                 if (!i)
     131                 :          0 :                          continue;
     132                 :            : 
     133         [ #  # ]:          0 :                 if (i == irq)   /* Already tried */
     134                 :          0 :                         continue;
     135                 :            : 
     136         [ #  # ]:          0 :                 if (try_one_irq(i, desc, false))
     137                 :            :                         ok = 1;
     138                 :            :         }
     139                 :            : out:
     140                 :            :         atomic_dec(&irq_poll_active);
     141                 :            :         /* So the caller can adjust the irq error counts */
     142                 :          0 :         return ok;
     143                 :            : }
     144                 :            : 
     145                 :          0 : static void poll_spurious_irqs(unsigned long dummy)
     146                 :            : {
     147                 :            :         struct irq_desc *desc;
     148                 :            :         int i;
     149                 :            : 
     150         [ #  # ]:          0 :         if (atomic_inc_return(&irq_poll_active) != 1)
     151                 :            :                 goto out;
     152                 :          0 :         irq_poll_cpu = smp_processor_id();
     153                 :            : 
     154 [ #  # ][ #  # ]:          0 :         for_each_irq_desc(i, desc) {
     155                 :            :                 unsigned int state;
     156                 :            : 
     157         [ #  # ]:          0 :                 if (!i)
     158                 :          0 :                          continue;
     159                 :            : 
     160                 :            :                 /* Racy but it doesn't matter */
     161                 :          0 :                 state = desc->istate;
     162                 :          0 :                 barrier();
     163         [ #  # ]:          0 :                 if (!(state & IRQS_SPURIOUS_DISABLED))
     164                 :          0 :                         continue;
     165                 :            : 
     166                 :            :                 local_irq_disable();
     167                 :          0 :                 try_one_irq(i, desc, true);
     168                 :            :                 local_irq_enable();
     169                 :            :         }
     170                 :            : out:
     171                 :            :         atomic_dec(&irq_poll_active);
     172                 :          0 :         mod_timer(&poll_spurious_irq_timer,
     173                 :            :                   jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
     174                 :          0 : }
     175                 :            : 
     176                 :            : static inline int bad_action_ret(irqreturn_t action_ret)
     177                 :            : {
     178 [ -  + ][ #  # ]:    3081428 :         if (likely(action_ret <= (IRQ_HANDLED | IRQ_WAKE_THREAD)))
     179                 :            :                 return 0;
     180                 :            :         return 1;
     181                 :            : }
     182                 :            : 
     183                 :            : /*
     184                 :            :  * If 99,900 of the previous 100,000 interrupts have not been handled
     185                 :            :  * then assume that the IRQ is stuck in some manner. Drop a diagnostic
     186                 :            :  * and try to turn the IRQ off.
     187                 :            :  *
     188                 :            :  * (The other 100-of-100,000 interrupts may have been a correctly
     189                 :            :  *  functioning device sharing an IRQ with the failing one)
     190                 :            :  */
     191                 :            : static void
     192                 :          0 : __report_bad_irq(unsigned int irq, struct irq_desc *desc,
     193                 :            :                  irqreturn_t action_ret)
     194                 :            : {
     195                 :            :         struct irqaction *action;
     196                 :            :         unsigned long flags;
     197                 :            : 
     198         [ #  # ]:          0 :         if (bad_action_ret(action_ret)) {
     199                 :          0 :                 printk(KERN_ERR "irq event %d: bogus return value %x\n",
     200                 :            :                                 irq, action_ret);
     201                 :            :         } else {
     202                 :          0 :                 printk(KERN_ERR "irq %d: nobody cared (try booting with "
     203                 :            :                                 "the \"irqpoll\" option)\n", irq);
     204                 :            :         }
     205                 :          0 :         dump_stack();
     206                 :          0 :         printk(KERN_ERR "handlers:\n");
     207                 :            : 
     208                 :            :         /*
     209                 :            :          * We need to take desc->lock here. note_interrupt() is called
     210                 :            :          * w/o desc->lock held, but IRQ_PROGRESS set. We might race
     211                 :            :          * with something else removing an action. It's ok to take
     212                 :            :          * desc->lock here. See synchronize_irq().
     213                 :            :          */
     214                 :          0 :         raw_spin_lock_irqsave(&desc->lock, flags);
     215                 :          0 :         action = desc->action;
     216         [ #  # ]:          0 :         while (action) {
     217                 :          0 :                 printk(KERN_ERR "[<%p>] %pf", action->handler, action->handler);
     218         [ #  # ]:          0 :                 if (action->thread_fn)
     219                 :          0 :                         printk(KERN_CONT " threaded [<%p>] %pf",
     220                 :            :                                         action->thread_fn, action->thread_fn);
     221                 :          0 :                 printk(KERN_CONT "\n");
     222                 :          0 :                 action = action->next;
     223                 :            :         }
     224                 :          0 :         raw_spin_unlock_irqrestore(&desc->lock, flags);
     225                 :          0 : }
     226                 :            : 
     227                 :            : static void
     228                 :            : report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
     229                 :            : {
     230                 :            :         static int count = 100;
     231                 :            : 
     232         [ #  # ]:          0 :         if (count > 0) {
     233                 :          0 :                 count--;
     234                 :          0 :                 __report_bad_irq(irq, desc, action_ret);
     235                 :            :         }
     236                 :            : }
     237                 :            : 
     238                 :            : static inline int
     239                 :            : try_misrouted_irq(unsigned int irq, struct irq_desc *desc,
     240                 :            :                   irqreturn_t action_ret)
     241                 :            : {
     242                 :            :         struct irqaction *action;
     243                 :            : 
     244         [ -  + ]:    3081428 :         if (!irqfixup)
     245                 :            :                 return 0;
     246                 :            : 
     247                 :            :         /* We didn't actually handle the IRQ - see if it was misrouted? */
     248         [ #  # ]:          0 :         if (action_ret == IRQ_NONE)
     249                 :            :                 return 1;
     250                 :            : 
     251                 :            :         /*
     252                 :            :          * But for 'irqfixup == 2' we also do it for handled interrupts if
     253                 :            :          * they are marked as IRQF_IRQPOLL (or for irq zero, which is the
     254                 :            :          * traditional PC timer interrupt.. Legacy)
     255                 :            :          */
     256         [ #  # ]:          0 :         if (irqfixup < 2)
     257                 :            :                 return 0;
     258                 :            : 
     259         [ #  # ]:          0 :         if (!irq)
     260                 :            :                 return 1;
     261                 :            : 
     262                 :            :         /*
     263                 :            :          * Since we don't get the descriptor lock, "action" can
     264                 :            :          * change under us.  We don't really care, but we don't
     265                 :            :          * want to follow a NULL pointer. So tell the compiler to
     266                 :            :          * just load it once by using a barrier.
     267                 :            :          */
     268                 :          0 :         action = desc->action;
     269                 :          0 :         barrier();
     270 [ #  # ][ #  # ]:          0 :         return action && (action->flags & IRQF_IRQPOLL);
     271                 :            : }
     272                 :            : 
     273                 :          0 : void note_interrupt(unsigned int irq, struct irq_desc *desc,
     274                 :            :                     irqreturn_t action_ret)
     275                 :            : {
     276 [ +  - ][ +  + ]:    3081432 :         if (desc->istate & IRQS_POLL_INPROGRESS ||
     277                 :            :             irq_settings_is_polled(desc))
     278                 :            :                 return;
     279                 :            : 
     280                 :            :         /* we get here again via the threaded handler */
     281         [ +  + ]:    3081430 :         if (action_ret == IRQ_WAKE_THREAD)
     282                 :            :                 return;
     283                 :            : 
     284         [ -  + ]:    3081428 :         if (bad_action_ret(action_ret)) {
     285                 :            :                 report_bad_irq(irq, desc, action_ret);
     286                 :            :                 return;
     287                 :            :         }
     288                 :            : 
     289         [ +  + ]:    3081428 :         if (unlikely(action_ret == IRQ_NONE)) {
     290                 :            :                 /*
     291                 :            :                  * If we are seeing only the odd spurious IRQ caused by
     292                 :            :                  * bus asynchronicity then don't eventually trigger an error,
     293                 :            :                  * otherwise the counter becomes a doomsday timer for otherwise
     294                 :            :                  * working systems
     295                 :            :                  */
     296         [ +  + ]:         77 :                 if (time_after(jiffies, desc->last_unhandled + HZ/10))
     297                 :         41 :                         desc->irqs_unhandled = 1;
     298                 :            :                 else
     299                 :         36 :                         desc->irqs_unhandled++;
     300                 :         77 :                 desc->last_unhandled = jiffies;
     301                 :            :         }
     302                 :            : 
     303            [ - ]:    3081428 :         if (unlikely(try_misrouted_irq(irq, desc, action_ret))) {
     304                 :          0 :                 int ok = misrouted_irq(irq);
     305         [ #  # ]:          0 :                 if (action_ret == IRQ_NONE)
     306                 :          0 :                         desc->irqs_unhandled -= ok;
     307                 :            :         }
     308                 :            : 
     309                 :          0 :         desc->irq_count++;
     310            [ + ]:          0 :         if (likely(desc->irq_count < 100000))
     311                 :            :                 return;
     312                 :            : 
     313                 :         31 :         desc->irq_count = 0;
     314         [ -  + ]:         31 :         if (unlikely(desc->irqs_unhandled > 99900)) {
     315                 :            :                 /*
     316                 :            :                  * The interrupt is stuck
     317                 :            :                  */
     318                 :          0 :                 __report_bad_irq(irq, desc, action_ret);
     319                 :            :                 /*
     320                 :            :                  * Now kill the IRQ
     321                 :            :                  */
     322                 :          0 :                 printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
     323                 :          0 :                 desc->istate |= IRQS_SPURIOUS_DISABLED;
     324                 :          0 :                 desc->depth++;
     325                 :          0 :                 irq_disable(desc);
     326                 :            : 
     327                 :          0 :                 mod_timer(&poll_spurious_irq_timer,
     328                 :            :                           jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
     329                 :            :         }
     330                 :         31 :         desc->irqs_unhandled = 0;
     331                 :            : }
     332                 :            : 
     333                 :            : bool noirqdebug __read_mostly;
     334                 :            : 
     335                 :          0 : int noirqdebug_setup(char *str)
     336                 :            : {
     337                 :          0 :         noirqdebug = 1;
     338                 :          0 :         printk(KERN_INFO "IRQ lockup detection disabled\n");
     339                 :            : 
     340                 :          0 :         return 1;
     341                 :            : }
     342                 :            : 
     343                 :            : __setup("noirqdebug", noirqdebug_setup);
     344                 :            : module_param(noirqdebug, bool, 0644);
     345                 :            : MODULE_PARM_DESC(noirqdebug, "Disable irq lockup detection when true");
     346                 :            : 
     347                 :          0 : static int __init irqfixup_setup(char *str)
     348                 :            : {
     349                 :          0 :         irqfixup = 1;
     350                 :          0 :         printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n");
     351                 :          0 :         printk(KERN_WARNING "This may impact system performance.\n");
     352                 :            : 
     353                 :          0 :         return 1;
     354                 :            : }
     355                 :            : 
     356                 :            : __setup("irqfixup", irqfixup_setup);
     357                 :            : module_param(irqfixup, int, 0644);
     358                 :            : 
     359                 :          0 : static int __init irqpoll_setup(char *str)
     360                 :            : {
     361                 :          0 :         irqfixup = 2;
     362                 :          0 :         printk(KERN_WARNING "Misrouted IRQ fixup and polling support "
     363                 :            :                                 "enabled\n");
     364                 :          0 :         printk(KERN_WARNING "This may significantly impact system "
     365                 :            :                                 "performance\n");
     366                 :          0 :         return 1;
     367                 :            : }
     368                 :            : 
     369                 :            : __setup("irqpoll", irqpoll_setup);

Generated by: LCOV version 1.9