"Go" interrupt processing function without DISABLE_IRQ and use Disable_irq_nosync reason

Source: Internet
Author: User

Original URL: http://blog.csdn.net/skyflying2012/article/details/8265869

Today, when writing a touchscreen driver, using the DISABLE_IRQ shutdown interrupt in the interrupt handling function found that the kernel hung up after the interrupt processing, and then discovered that the DISABLE_IRQ closed interrupt and waited for the interrupt to be processed and returned, and Disable_irq_ Nosync returns immediately. In the interrupt handler, you should use Disable_irq_nosync to turn off interrupts first look at Disable_irq_nosync, which is explained in the kernel code:

/**
* Disable_irq_nosync-disable an IRQ without waiting
* @irq: Interrupt to disable
*
* Disable the selected interrupt line. Disablesand enables is
* Nested.
* Unlike DISABLE_IRQ (), this function doesnot ensure existing
* Instances of the IRQ handler has completed before returning.
*
* This function is called from IRQ context.
*/
void Disable_irq_nosync (unsigned int IRQ)
{
struct Irq_desc *desc = Irq_to_desc (IRQ);
unsigned long flags;

if (!DESC)
Return

Chip_bus_lock (IRQ, DESC);
Spin_lock_irqsave (&desc->lock, flags);
__DISABLE_IRQ (DESC, IRQ, false);
Spin_unlock_irqrestore (&desc->lock, flags);
Chip_bus_sync_unlock (IRQ, DESC);
}

The program returns after the interrupt is closed, and if it is in the interrupt handler, the interrupt handler will continue to execute.


/**
* Disable_irq-disable an IRQ and wait for completion
* @irq: Interrupt to disable
*
* Disable the selected interrupt line. Enables and disables are
* Nested.
* This function waits-pending IRQ handlers for this interrupt
* to complete before returning. If You use the This function while
* Holding a resource the IRQ handler may need you'll deadlock.
*
* This function is Called-with care-from IRQ context.
*/
void Disable_irq (Unsignedint IRQ)
{
struct Irq_desc *desc = irq_desc + IRQ;
if (irq>= Nr_irqs)
Return
Disable_irq_nosync (IRQ);
if (desc->action)
SYNCHRONIZE_IRQ (IRQ);
}

Closes the interrupt and waits for the interrupt to be processed and returned. As you can see from the code, DISABLE_IRQ first called Disable_irq_nosync and then detects if Desc->action is 1. In the interrupt handler, the action is set to 1, so enter the SYNCHRONIZE_IRQ function.


/**
* Synchronize_irq-wait for pending IRQ handlers (on other CPUs)
* @irq: Interrupt number to wait for
*
* This function waits-pending IRQ handlers for this interrupt
* to complete before returning. If You use the This function while
* Holding a resource the IRQ handler may need you'll deadlock.
*
* This function is Called-with care-from IRQ context.
*/
void Synchronize_irq (Unsignedint IRQ)
{
struct Irq_desc *desc= irq_to_desc (IRQ);
unsigned int status;
if (!DESC)
Return
do {
unsigned long flags;
/*
* Wait until we ' re out of the A critical section. This might
* Give the wrong answer due to the lack of memory barriers.
*/
while (desc->status& irq_inprogress)
Cpu_relax ();
/* Ok, that's indicated we ' re done:double-check carefully. */
Spin_lock_irqsave (&desc->lock, flags);
Status = desc->status;
Spin_unlock_irqrestore (&desc->lock, flags);
/* Oops, that failed? */
} while (status & Irq_inprogress);
/*
* We made sure that no HARDIRQ handler is running. Now verify
* That's no threaded handlers is active.
*/
Wait_event (Desc->wait_for_threads,!atomic_read (&desc->threads_active));
}


Note that the function is waiting for the end of the interrupt handler, which is the main difference between DISABLE_IRQ and Disable_irq_nosync. But what happens when you call in an interrupt handler function? The irq_inprogress is set by __SETUP_IRQ before entering the interrupt handler, so the program is stuck in the while loop and the kernel is exclusive, which causes the system to die. Summary:
Because the SYNCHRONIZE_IRQ function is called in DISABLE_IRQ to wait for the interrupt to return, the DISABLE_IRQ cannot be used in the interrupt handler, which causes the CPU to be SYNCHRONIZE_IRQ exclusive and the system crashes.

"Go" interrupt processing function without DISABLE_IRQ and use Disable_irq_nosync reason

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.