DPDK通過在多核設備上,創建多個線程,每個線程綁定到單獨的核上,減少線程調度的開銷,以提高性能。
DPDK的線程分為控制線程和數據線程,控制線程一般綁定到MASTER核上,主要是接受用戶配置,並傳遞配置參數給數據線程等;數據線程主要是處理數據包。
一、初始化
1、rte_eal_cpu_init()函數中,通過讀取/sys/devices/system/cpu/cpuX/下的相關信息,確定當前系統有哪些CPU核,已經每個核屬於哪個CPU Socket。
2、eal_parse_args()函數,解析-c參數,確認哪些CPU核是可以使用的,以及設置第一個核為MASTER。
3、為每一個SLAVE核創建線程,並調用eal_thread_set_affinity()綁定cpu。線程的執行體是eal_thread_loop()。eal_thread_loop()的主體是一個while死循環,調用不同模塊注冊到lcore_config[lcore_id].f的回調函數。
1 RTE_LCORE_FOREACH_SLAVE(i) { 2 3 /* 4 * create communication pipes between master thread 5 * and children 6 */ 7 if (pipe(lcore_config[i].pipe_master2slave) < 0) 8 rte_panic("Cannot create pipe\n"); 9 if (pipe(lcore_config[i].pipe_slave2master) < 0) 10 rte_panic("Cannot create pipe\n"); 11 12 lcore_config[i].state = WAIT; 13 14 /* create a thread for each lcore */ 15 ret = pthread_create(&lcore_config[i].thread_id, NULL, 16 eal_thread_loop, NULL); 17 if (ret != 0) 18 rte_panic("Cannot create thread\n"); 19 }
二、注冊
不同的模塊需要調用rte_eal_mp_remote_launch(),將自己的回調處理函數注冊到lcore_config[].f中。以l2fwd為例,注冊的回調處理函數是l2fwd_launch_on_lcore()。
1 rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, NULL, CALL_MASTER);
DPDK每個核上的線程最終會調用eal_thread_loop()--->l2fwd_launch_on_lcore(),調用到自己實現的處理函數。
錯誤之處,歡迎指出。