我目前正在構建一個內核模塊,我想以一種非常優化的方式來面對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]);
}
的問題是:如何保證
- 沒有CPU在
cpu
作業和do_some_work_with
之間切換? do_some_work_with()
只會在cpu
上運行?
當時,我想到的解決辦法是:使用
- 禁止搶佔自旋鎖
- 獲取CPU與
smp_processor_id
- 設置當前任務的處理器親和力,使其堅持與當前的CPU
- 啓用搶先再次釋放鎖
- 做的工作
do_some_work_with()
- 重置親和力到以前的狀態
對我來說這是很野蠻的,我想知道是否有更聰明和更輕的方式做到這一點。
在此先感謝。
編輯: 正如評論所說,我編輯解釋爲什麼我覺得我需要這樣的功能。 我必須在檔案系統級別上執行即時加密。
爲此,我將使用內核內置的加密支持(struct crypto_tfm
和朋友)。這是原始問題...
在多核機器上,可以同時執行多個R/W操作。普通的fs圖層做到了,做得很好。但是,在這裏我來把事情搞得一團糟:
- 一個
struct crypto_tfm
樣的對象是負責爲加密操作 - 一個相同的轉換不能在同一時間使用對象,因爲某些參數會改變(私人密鑰和初始化向量),並擰緊所有過程
- 由於密碼中內置了複雜的密碼分配系統,以下描述的幼稚解決方案完全不存在問題。
- 分配
crypto_tfm
改造 - 執行加密操作
- 免費改造對象
- 分配
- 一個經典的方案,其中只有一轉換可避免多個併發讀/寫操作,因爲一個任務就必須等待另一個釋放鎖來保護轉換對象。
由於這些原因,我需要處理多個轉換對象。我必須找到一個允許併發R/W的高效方案。我覺得我的「Y」在這裏是「簡單,整潔......錯誤的解決方案」。 任何建議將不勝感激。
注意:如果我使用類似於原始問題中提供的解決方案,我將其限制爲非常短的部分以避免對CPU負載平衡造成嚴重影響。
爲什麼你看到需要鍛鍊這種控制水平?如果你不這樣做,你的模塊會有問題嗎? – 2013-02-13 13:33:06
我非常強烈地感覺到你的整體方法是錯誤的。強制內核在特定CPU上運行內核線程肯定是不對的。我確實相信你描述的方法可行,但看起來很不對。 – 2013-02-13 13:34:00
@MatsPetersson我有同樣的感覺......但我無法弄清楚如何保證我需要運行的任務內的平滑SMP。我可以編輯來解釋導致我考慮這種可怕事情的上下文 – Rerito 2013-02-13 13:42:09