3,830 瀏覽數

Linux daemon – irqbalance

本來是要查 irqbalance 是做什麼用的?? 下面是 RedHat 的官方文件.

This daemon is enabled by default and periodically forces interrupts to be handled by CPUs in an even, fair manner. However in realtime deployments, applications are typically dedicated and bound to specific CPUs, so the irqbalance daemon is not required.

irqbalance 這個服務預設是啟動的,他會定期強制中斷應用程式,讓每個應用程式能更公平的方式分享 CPU 的資源,但在 realtime 即時環境下,應用程序通常是專用的,並綁定到特定的 CPU,所以不需要 irqbalance 這個服務守護.

恩!! 在 Linux 下 CPU 是用哪一種排程?? 從大學摸過恐龍書(作業系統導論)後就沒有詳細探討過現在作業系統下的 CPU 排程.還好在 RedHat Document 都可以查到.

排程有兩類:
即時 real time 的執行緒會先被執行,而一般 Regular 的執行緒會在即時 real time 執行緒後才排進去執行,至於哪些是即時的哪些是一般的執行緒這是由系統決定,我們可以透過 ps -la 來檢視

root@ubuntu:/proc# ps -la
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  3112  3075  0  80   0 - 17810 poll_s pts/13   00:00:00 sudo
4 S     0  3114  3112  0  80   0 - 17705 wait   pts/13   00:00:00 su
4 S     0  3115  3114  0  80   0 -  6797 wait   pts/13   00:00:01 bash

即時 real time 政策

  • SCHED_FIFO
    這政策也稱為「靜態優先順序排程」(static priority scheduling),因為此政策為每個執行緒定義了固定的優先順序(介於 1 到 99)。這個排程器會以優先順序掃描 SCHED_FIFO 執行緒清單,並排程擁有最高執行順序的執行續以執行之。這個執行緒會一直執行,直到被阻絕、退出、或被擁有更高優先順序的執行緒所取代為止。即使是最低權限的即時執行緒,也比非即時的執行緒擁有更高的權限;如果只有一個即時執行緒,那麼 SCHED_FIFO 的優先值就無關緊要。(轉貼 RedHat)
  • SCHED_RR
    這是源自 SCHED_FIFO 政策的一種輪詢(round-robin)政策。SCHED_RR 執行緒也會被賦予固定的權限值,介於 1 到 99。然而,擁有同樣權限值的執行續會以一固定時間量,又稱「時間配量」(time slice)。(轉貼 RedHat)

一般 Regular 政策

  • SCHED_OTHER
    預設的排程政策。此政策使用了 CFS(完全公平排程器,Completely Fair Scheduler)好為使用此政策的所有執行續提供完全公平的存取時間。CFS 會建立動態的優先順序清單,部分根據每個執行續的 niceness 值。這能給使用者一些非直接的控制等級,以控制程序的優先順序;但動態優先順序清單可以由 CFS 直接改變。(轉貼 RedHat)
  • SCHED_BATCH
  • SCHED_IDLE

優先執行序 (priority, PRI) 是由核心動態調整的,我們無法直接調整 PRI ,我們最多能透過 nice 與 renice 改變其優先執行序 PRI(new) = PRI(old) + nice (PRI 越小優先順序越高)

Nice 的使用時機為一開始執行程式,如果是要調整某個已經存在的的執行程式則需要用 renice 指令.

現在回到 irqbalance ,如果我需要即時 real time 的系統建議是關閉它.

關閉 irqbalance 服務

# service irqbalance status
irqbalance (pid PID) is running...

如果 irqbalance 是在執行階段可以透過指令立即關閉它

# /etc/init.d/irqbalance stop
Stopping irqbalance:             [  OK  ]

不想要開機就執行可以透過 chkconfig (System V 可以用這方式但 Upstart 則不適用,請參考 System V 與 Upstart

# chkconfig irqbalance off

關閉部份的 irqbalance 服務
設定檔位於 /etc/default/irqbalance ,我也沒有設定過就先不討論了.

root@ubuntu:/proc# cat /etc/default/irqbalance 
#Configuration for the irqbalance daemon

#Should irqbalance be enabled?
ENABLED="1"
#Balance the IRQs only once?
ONESHOT="0"

CPU Affinity

每個 I/O 會有各自的 IRQ (中斷) 透過設定我們可以將個別的 IRQ 指定給特定的 CPU 來處理 ,先檢查對應的 IRQ 檔案 /proc/interrupts (每個 IRQ 對應到每個 I/O 裝置)

# cat /proc/interrupts |grep -i eth
  16:      35502      13732   IO-APIC-fasteoi   vmwgfx, snd_ens1371, eth1
  19:      20253      51673   IO-APIC-fasteoi   eth0

你可以看到 eth0 的 irq 是 19 所以我們可以指定他使用哪一個 CPU 核心來處理.接下來就是要如何指定,我們可以透過設定 /proc/irq/IRQ_NUMBER/smp_affinity ,檔案裡的參數可以用來指定 IRQ 中斷 與 CPU 的關聯 (一個或是多個 CPU 核心).

目前我的系統是 64 位元 雙核心,而 eth0 的 irq 是 19

# cat echo 1 > /proc/irq/19/smp_affinity
00000000,00000002

00000000,00000002 <- 這是?? 這是 64 位元處理器的表示方式,00000000,00000002 是 16 位元進制 2(16 位元進制) -> 0010(2 位元進制) -> 2(10 位元進制)
0000 (2 位元進制)-> 0(16 位元進制)
0001 (2 位元進制)-> 1(16 位元進制)
0010 (2 位元進制)-> 2(16 位元進制)
0011 (2 位元進制)-> 3(16 位元進制)
0100 (2 位元進制)-> 4(16 位元進制)
0101 (2 位元進制)-> 5(16 位元進制)
0110 (2 位元進制)-> 6(16 位元進制)
0111 (2 位元進制)-> 7(16 位元進制)
1000 (2 位元進制)-> 8(16 位元進制)
1001 (2 位元進制)-> 9(16 位元進制)
1010 (2 位元進制)-> A(16 位元進制)
1011 (2 位元進制)-> B(16 位元進制)
1100 (2 位元進制)-> C(16 位元進制)
1101 (2 位元進制)-> D(16 位元進制)
1110 (2 位元進制)-> E(16 位元進制)
1111 (2 位元進制)-> F(16 位元進制)
00000000,00000002 <- 這是由第二顆核心來處理,00000000,00000001 <- 這是由第一顆核心來處理,如果要同是由兩個核心來處理可以下 00000000,00000003 ...以此類推. [php] # echo 00000000,00000003 > /proc/irq/19/smp_affinity [/php] 也有些系統不是顯示這麼一長串的數字 [php] # cat /proc/irq/32/smp_affinity f [/php] smp_affinity f 表示 IRQ 可以接受所有系統上的 CPU 的服務,設定 為 1 則表示只有 CPU 0 可以服務此中斷 ,2 -> CPU 1 , 3 CPU 0 + CPU 1 .

# echo 1 >/proc/irq/32/smp_affinity
# cat /proc/irq/32/smp_affinity
1

透過 taskset utility 來設定 process ID (PID) 與 CPUs 的關係

前面的 smp_affinity 是透過 irq 來指定 CPU ,我們也是可以透過 taskset 工具指定 process ID (PID) 與 CPUs 的關係.

假如某一程式 my_embedded_process 要指定給 CPU 3 來處理 (需要用 16 位元進制來表示,CPU 0 -> 1 , CPU -> 2 , CPU->4 , CPU->8 ).

# taskset 8 /usr/local/bin/my_embedded_process

如果是已經在執行的程式也是可以再指定的 ,只要使用參數 -p (–pid) 即可,假設 PID 是 7013 要將他指定給 CPU 0.

# taskset -p 1 7013

note:taskset 工具只能使用在沒有啟動 Non-Uniform Memory Access (NUMA) 功能的系統,關於 NUMA 又是要寫一篇文章了.

2 個網友的想法 “Linux daemon – irqbalance

  1. 自動參照通知: Network 效能測試與調整 | Benjr.tw

  2. 自動參照通知: 限制 Process 的 CPU 使用率 | Benjr.tw

發表迴響