2013-02-13 38 views
0

我目前正在構建一個內核模塊,我想以一種非常優化的方式來面對SMP問題。如何防止任務從CPU移動到另一個?

目前,我有一組對象,並且每個對象都綁定到特定的CPU。下面的代碼說明了這一點:

struct my_object { 
    int a_field; 
}; 

struct my_object cpu_object[NR_CPUS]; 
/* 
* cpu_object[i] is "bound" to CPU number "i" ! 
*/ 

smp_processor_id()一個簡單的呼叫,然後給我上當前運行代碼的處理器。所以,如果我有一個函數foo,做使用上述CPU綁定的對象了一些工作,它可能看起來像:

void foo() 
{ 
    int cpu = smp_processor_id(); 
    do_some_work_with(cpu_object[cpu]); 
} 

的問題是:如何保證

  1. 沒有CPU在cpu作業和do_some_work_with之間切換?
  2. do_some_work_with()只會在cpu上運行?

當時,我想到的解決辦法是:使用

  1. 禁止搶佔自旋鎖
  2. 獲取CPU與smp_processor_id
  3. 設置當前任務的處理器親和力,使其堅持與當前的CPU
  4. 啓用搶先再次釋放鎖
  5. 做的工作do_some_work_with()
  6. 重置親和力到以前的狀態

對我來說這是很野蠻的,我想知道是否有更聰明和更輕的方式做到這一點。

在此先感謝。


編輯: 正如評論所說,我編輯解釋爲什麼我覺得我需要這樣的功能。 我必須在檔案系統級別上執行即時加密。
爲此,我將使用內核內置的加密支持(struct crypto_tfm和朋友)。這是原始問題...

在多核機器上,可以同時執行多個R/W操作。普通的fs圖層做到了,做得很好。但是,在這裏我來把事情搞得一團糟:

  • 一個struct crypto_tfm樣的對象是負責爲加密操作
  • 一個相同的轉換不能在同一時間使用對象,因爲某些參數會改變(私人密鑰和初始化向量),並擰緊所有過程
  • 由於密碼中內置了複雜的密碼分配系統,以下描述的幼稚解決方案完全不存在問題。
    1. 分配crypto_tfm改造
    2. 執行加密操作
    3. 免費改造對象
  • 一個經典的方案,其中只有一轉換可避免多個併發讀/寫操作,因爲一個任務就必須等待另一個釋放鎖來保護轉換對象。

由於這些原因,我需要處理多個轉換對象。我必須找到一個允許併發R/W的高效方案。我覺得我的「Y」在這裏是「簡單,整潔......錯誤的解決方案」。 任何建議將不勝感激。

注意:如果我使用類似於原始問題中提供的解決方案,我將其限制爲非常短的部分以避免對CPU負載平衡造成嚴重影響。

+2

爲什麼你看到需要鍛鍊這種控制水平?如果你不這樣做,你的模塊會有問題嗎? – 2013-02-13 13:33:06

+3

我非常強烈地感覺到你的整體方法是錯誤的。強制內核在特定CPU上運行內核線程肯定是不對的。我確實相信你描述的方法可行,但看起來很不對。 – 2013-02-13 13:34:00

+0

@MatsPetersson我有同樣的感覺......但我無法弄清楚如何保證我需要運行的任務內的平滑SMP。我可以編輯來解釋導致我考慮這種可怕事情的上下文 – Rerito 2013-02-13 13:42:09

回答

2

所以,根據你編輯的問題,我不得不說,我認爲你的解決方案是錯誤的。

正確的做法是在每個CPU之後執行「每個操作」crypto_tfm。使用「當前的CPU」在這裏不是正確的。 [如果這種情況發生在具有熱插拔CPU的系統上,並且有人斷開了你的任務正在運行的CPU,並且從未將其放回到它的位置,會發生什麼情況?]

如果分配crypto_tfm操作,那麼你必須找到一些方法來避免分配/釋放對象 - 有一個池,併爲當前操作分配一個可用的,並且當操作完成時,再次將其放回到可用列表中。

+0

除了兩個明顯的對象(分配一個新的對象或者簡單地等待一個現有的對象)之外,沒有對象可以使用的可用策略是什麼?變得可用)?從我目前閱讀的內容來看,如果一個任務不能被移動到另一個任務中,CPU不能被熱插拔 – Rerito 2013-02-13 14:25:37

+0

這些是我能想到的唯一兩個。那麼,第三個「混合」的,我想,基於'if(num_allocated_crypt_tfm 2013-02-13 14:28:30

相關問題