Showing error 1431

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: kernel/irq/handle.c
Line in file: 153
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2012-05-21 20:30:05 UTC


Source:

  1/*
  2 * linux/kernel/irq/handle.c
  3 *
  4 * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
  5 * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
  6 *
  7 * This file contains the core interrupt handling code.
  8 *
  9 * Detailed information is available in Documentation/DocBook/genericirq
 10 *
 11 */
 12
 13#include <linux/irq.h>
 14#include <linux/module.h>
 15#include <linux/random.h>
 16#include <linux/interrupt.h>
 17#include <linux/kernel_stat.h>
 18
 19#include "internals.h"
 20
 21/**
 22 * handle_bad_irq - handle spurious and unhandled irqs
 23 * @irq:       the interrupt number
 24 * @desc:      description of the interrupt
 25 *
 26 * Handles spurious and unhandled IRQ's. It also prints a debugmessage.
 27 */
 28void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
 29{
 30        print_irq_desc(irq, desc);
 31        kstat_incr_irqs_this_cpu(irq, desc);
 32        ack_bad_irq(irq);
 33}
 34
 35/*
 36 * Linux has a controller-independent interrupt architecture.
 37 * Every controller has a 'controller-template', that is used
 38 * by the main code to do the right thing. Each driver-visible
 39 * interrupt source is transparently wired to the appropriate
 40 * controller. Thus drivers need not be aware of the
 41 * interrupt-controller.
 42 *
 43 * The code is designed to be easily extended with new/different
 44 * interrupt controllers, without having to do assembly magic or
 45 * having to touch the generic code.
 46 *
 47 * Controller mappings for all interrupt sources:
 48 */
 49int nr_irqs = NR_IRQS;
 50EXPORT_SYMBOL_GPL(nr_irqs);
 51
 52struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
 53        [0 ... NR_IRQS-1] = {
 54                .status = IRQ_DISABLED,
 55                .chip = &no_irq_chip,
 56                .handle_irq = handle_bad_irq,
 57                .depth = 1,
 58                .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
 59#ifdef CONFIG_SMP
 60                .affinity = CPU_MASK_ALL
 61#endif
 62        }
 63};
 64
 65/*
 66 * What should we do if we get a hw irq event on an illegal vector?
 67 * Each architecture has to answer this themself.
 68 */
 69static void ack_bad(unsigned int irq)
 70{
 71        struct irq_desc *desc = irq_to_desc(irq);
 72
 73        print_irq_desc(irq, desc);
 74        ack_bad_irq(irq);
 75}
 76
 77/*
 78 * NOP functions
 79 */
 80static void noop(unsigned int irq)
 81{
 82}
 83
 84static unsigned int noop_ret(unsigned int irq)
 85{
 86        return 0;
 87}
 88
 89/*
 90 * Generic no controller implementation
 91 */
 92struct irq_chip no_irq_chip = {
 93        .name                = "none",
 94        .startup        = noop_ret,
 95        .shutdown        = noop,
 96        .enable                = noop,
 97        .disable        = noop,
 98        .ack                = ack_bad,
 99        .end                = noop,
100};
101
102/*
103 * Generic dummy implementation which can be used for
104 * real dumb interrupt sources
105 */
106struct irq_chip dummy_irq_chip = {
107        .name                = "dummy",
108        .startup        = noop_ret,
109        .shutdown        = noop,
110        .enable                = noop,
111        .disable        = noop,
112        .ack                = noop,
113        .mask                = noop,
114        .unmask                = noop,
115        .end                = noop,
116};
117
118/*
119 * Special, empty irq handler:
120 */
121irqreturn_t no_action(int cpl, void *dev_id)
122{
123        return IRQ_NONE;
124}
125
126/**
127 * handle_IRQ_event - irq action chain handler
128 * @irq:        the interrupt number
129 * @action:        the interrupt action chain for this irq
130 *
131 * Handles the action chain of an irq event
132 */
133irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
134{
135        irqreturn_t ret, retval = IRQ_NONE;
136        unsigned int status = 0;
137
138        if (!(action->flags & IRQF_DISABLED))
139                local_irq_enable_in_hardirq();
140
141        do {
142                ret = action->handler(irq, action->dev_id);
143                if (ret == IRQ_HANDLED)
144                        status |= action->flags;
145                retval |= ret;
146                action = action->next;
147        } while (action);
148
149        if (status & IRQF_SAMPLE_RANDOM)
150                add_interrupt_randomness(irq);
151        local_irq_disable();
152
153        return retval;
154}
155
156#ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
157/**
158 * __do_IRQ - original all in one highlevel IRQ handler
159 * @irq:        the interrupt number
160 *
161 * __do_IRQ handles all normal device IRQ's (the special
162 * SMP cross-CPU interrupts have their own specific
163 * handlers).
164 *
165 * This is the original x86 implementation which is used for every
166 * interrupt type.
167 */
168unsigned int __do_IRQ(unsigned int irq)
169{
170        struct irq_desc *desc = irq_to_desc(irq);
171        struct irqaction *action;
172        unsigned int status;
173
174        kstat_incr_irqs_this_cpu(irq, desc);
175
176        if (CHECK_IRQ_PER_CPU(desc->status)) {
177                irqreturn_t action_ret;
178
179                /*
180                 * No locking required for CPU-local interrupts:
181                 */
182                if (desc->chip->ack)
183                        desc->chip->ack(irq);
184                if (likely(!(desc->status & IRQ_DISABLED))) {
185                        action_ret = handle_IRQ_event(irq, desc->action);
186                        if (!noirqdebug)
187                                note_interrupt(irq, desc, action_ret);
188                }
189                desc->chip->end(irq);
190                return 1;
191        }
192
193        spin_lock(&desc->lock);
194        if (desc->chip->ack)
195                desc->chip->ack(irq);
196        /*
197         * REPLAY is when Linux resends an IRQ that was dropped earlier
198         * WAITING is used by probe to mark irqs that are being tested
199         */
200        status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
201        status |= IRQ_PENDING; /* we _want_ to handle it */
202
203        /*
204         * If the IRQ is disabled for whatever reason, we cannot
205         * use the action we have.
206         */
207        action = NULL;
208        if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
209                action = desc->action;
210                status &= ~IRQ_PENDING; /* we commit to handling */
211                status |= IRQ_INPROGRESS; /* we are handling it */
212        }
213        desc->status = status;
214
215        /*
216         * If there is no IRQ handler or it was disabled, exit early.
217         * Since we set PENDING, if another processor is handling
218         * a different instance of this same irq, the other processor
219         * will take care of it.
220         */
221        if (unlikely(!action))
222                goto out;
223
224        /*
225         * Edge triggered interrupts need to remember
226         * pending events.
227         * This applies to any hw interrupts that allow a second
228         * instance of the same irq to arrive while we are in do_IRQ
229         * or in the handler. But the code here only handles the _second_
230         * instance of the irq, not the third or fourth. So it is mostly
231         * useful for irq hardware that does not mask cleanly in an
232         * SMP environment.
233         */
234        for (;;) {
235                irqreturn_t action_ret;
236
237                spin_unlock(&desc->lock);
238
239                action_ret = handle_IRQ_event(irq, action);
240                if (!noirqdebug)
241                        note_interrupt(irq, desc, action_ret);
242
243                spin_lock(&desc->lock);
244                if (likely(!(desc->status & IRQ_PENDING)))
245                        break;
246                desc->status &= ~IRQ_PENDING;
247        }
248        desc->status &= ~IRQ_INPROGRESS;
249
250out:
251        /*
252         * The ->end() handler has to deal with interrupts which got
253         * disabled while the handler was running.
254         */
255        desc->chip->end(irq);
256        spin_unlock(&desc->lock);
257
258        return 1;
259}
260#endif
261
262
263#ifdef CONFIG_TRACE_IRQFLAGS
264/*
265 * lockdep: we want to handle all irq_desc locks as a single lock-class:
266 */
267static struct lock_class_key irq_desc_lock_class;
268
269void early_init_irq_lock_class(void)
270{
271        struct irq_desc *desc;
272        int i;
273
274        for_each_irq_desc(i, desc)
275                lockdep_set_class(&desc->lock, &irq_desc_lock_class);
276}
277#endif