Linux Kernel Development——中斷

來源:互聯網
上載者:User
中斷的上半部和下半部

中斷是系統硬體與處理器通訊的一種機制。當硬體裝置發生中斷的時候,核心會被打斷,並執行中斷對應的處理函數。在執行中斷服務程式的時候,核心處於中斷上下文。此時,如果不禁止中斷,該中斷處理常式仍有可能被其他中斷事件所打斷。因此,我們希望中斷服務程式執行的越快越好。而通常一個中斷服務程式要做很多的事情,比如網卡中斷髮生時,不僅要對網卡作應答,還要將網路資料包拷貝到系統記憶體,並作相應處理後交給合適的協議棧。這樣,既想速度快,又要完成大量的工作,兩者必須作出取捨。

核心對這個問題的處理比較巧妙:核心將整個的中斷處理流程分為了上半部和下半部。上半部的功能是"登記中斷",當一個中斷髮生時,它進行相應地硬體讀寫後就把中斷常式的下半部掛到該裝置的下半部執行隊列中去。因此,上半部執行的速度就會很快,可以服務更多的插斷要求。但是,僅有"登記中斷"是遠遠不夠的,因為中斷的事件可能很複雜。因此,Linux引入了一個下半部,來完成中斷事件的絕大多數使命。下半部和上半部最大的不同是下半部是可中斷的,而上半部是不可中斷的,下半部幾乎做了中斷處理常式所有的事情,而且可以被新的中斷打斷!下半部則相對來說並不是非常緊急的,通常還是比較耗時的,因此由系統自行安排運行時機,不在中斷服務上下文中執行。 核心提供了很多下半部執行的機制,如非強制中斷、tasklet和等待隊列等。

拿網卡來舉例,在linux核心中,當網卡一旦接受到資料,網卡會通過中斷告訴核心處理資料,核心會在網卡的中斷處理函數(也就是上半部)執行一些網卡硬體的必要設定,因為這是在中斷響應後急切要乾的事情。接著,核心調用對應的下半部函數來處理網卡接收到的資料,因為資料處理沒必要在中斷處理函數裡面馬上執行,可以將中斷讓出來做更緊迫的事情。

中斷處理函數

中斷處理常式使用硬體裝置驅動程式的組成部分,驅動程式通過request_irq()註冊並啟用一個中斷處理函數。而在驅動程式卸載時,通過free_irq()登出中斷處理函數,並釋放中斷線。需要注意的是,request_irq()可能會睡眠,因此不能在中斷上下文或者不允許阻塞的代碼中使用;必須在進程上下文中調用free_irq()。

中斷處理函數的原型為:

   1:  /**
   2:   * enum irqreturn
   3:   * @IRQ_NONE            interrupt was not from this device
   4:   * @IRQ_HANDLED         interrupt was handled by this device
   5:   * @IRQ_WAKE_THREAD     handler requests to wake the handler thread
   6:   */
   7:  enum irqreturn {
   8:          IRQ_NONE                = (0 << 0),
   9:          IRQ_HANDLED             = (1 << 0),
  10:          IRQ_WAKE_THREAD         = (1 << 1),
  11:  };
  12:   
  13:  typedef enum irqreturn irqreturn_t;
  14:   
  15:  typedef irqreturn_t (*irq_handler_t)(int, void *);

中斷處理函數是無需重入的,因為當一個中斷處理函數在執行時,該中斷線上的其他中斷都會被屏蔽掉,以防止在同一個中斷線上接收另一個中斷。

一個典型的中斷處理函數執行個體:RTC中斷處理函數

   1:  /*
   2:   *    A very tiny interrupt handler. It runs with IRQF_DISABLED set,
   3:   *    but there is possibility of conflicting with the set_rtc_mmss()
   4:   *    call (the rtc irq and the timer irq can easily run at the same
   5:   *    time in two different CPUs). So we need to serialize
   6:   *    accesses to the chip with the rtc_lock spinlock that each
   7:   *    architecture should implement in the timer code.
   8:   *    (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.)
   9:   */
  10:   
  11:  static irqreturn_t rtc_interrupt(int irq, void *dev_id)
  12:  {
  13:      /*
  14:       *    Can be an alarm interrupt, update complete interrupt,
  15:       *    or a periodic interrupt. We store the status in the
  16:       *    low byte and the number of interrupts received since
  17:       *    the last read in the remainder of rtc_irq_data.
  18:       */
  19:   
  20:      spin_lock(&rtc_lock);
  21:      rtc_irq_data += 0x100;
  22:      rtc_irq_data &= ~0xff;
  23:      if (is_hpet_enabled()) {
  24:          /*
  25:           * In this case it is HPET RTC interrupt handler
  26:           * calling us, with the interrupt information
  27:           * passed as arg1, instead of irq.
  28:           */
  29:          rtc_irq_data |= (unsigned long)irq & 0xF0;
  30:      } else {
  31:          rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
  32:      }
  33:   
  34:      if (rtc_status & RTC_TIMER_ON)
  35:          mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
  36:   
  37:      spin_unlock(&rtc_lock);
  38:   
  39:      /* Now do the rest of the actions */
  40:      spin_lock(&rtc_task_lock);
  41:      if (rtc_callback)
  42:          rtc_callback->func(rtc_callback->private_data);
  43:      spin_unlock(&rtc_task_lock);
  44:      wake_up_interruptible(&rtc_wait);
  45:   
  46:      kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
  47:   
  48:      return IRQ_HANDLED;
  49:  }
  50:  #endif

中斷上下文

與進程上下文不同(核心代表進程執行操作,通過current宏關聯當前進程,可以睡眠,也可以調用發送器),當執行中斷處理常式或下半部時,核心處於中斷上下文中。中斷上下文與進程沒有什麼瓜葛,因此中斷上下文不可睡眠。中斷處理函數具有較嚴格的時間限制,因為它打斷了其他的代碼。應當盡量將工作從中斷處理常式中分離開來,放到下半部中執行,因為下半部可以在更合適的時間運行。

中斷處理機制

圖 中斷從硬體到核心的路由

  • 中斷髮生時根據中斷控制器找到中斷號
  • 中斷上半部執行:調用do_IRQ(),儲存目前狀態old_regs = set_irq_regs(regs),irq_enter(),調用中斷處理函數,最後irq_exit(),恢複原來狀態set_irq_regs(old_regs)
  • 中斷下半部執行:非強制中斷和tasklet
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.