• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            xiaoxiaoling

            C++博客 首頁 新隨筆 聯系 聚合 管理
              17 Posts :: 2 Stories :: 9 Comments :: 0 Trackbacks


            dpdk是通過許多不同的緯度來加速包處理的,其中主要包括:

             

            hugepage大頁內存(進程使用的是虛擬地址,一般頁表(4k)能映射的虛擬地址空間有限,使用大頁能減少換頁次數提高cache命中,通過mmap把大頁映射到用戶態的虛擬地址空間有用過mmap的都知道這是實現共享內存的手段,所以dpdk還支持多進程共享內存)

             

            cache預取 (每次預讀當前數據相鄰前后的數據),批量操作數據,cache line對齊(通過浪費一點內存將要操作的數據對齊)

             

            接管了網卡用戶態驅動使用輪詢而不是網卡中斷

             

            將網卡rx tx隊列映射到用戶態空間實現真正的零拷貝(傳統堆棧至少也得一次拷貝,因為隊列空間在內核而內核和用戶態使用不同的地址空間)(傳統堆棧為了支持通用性,例如ipx等其他網絡,將包處理過程分了很多層次,層之間的接口標準統一數據結構就需要轉換,無形中帶來了巨大的成本,如osi七層模型而實用的就是tcp/ip四層模型)

             

            線程綁定cpu

             

            支持NUMA,不同的core屬于不同的node,每個node有自己的mempool減少沖突

             

            無鎖環形隊列(沖突發生時也是一次cas的開銷)

             

            dpdk通過tools/dpdk-setup.sh的腳本,通過編譯、掛載內核模塊, 綁定網卡(先把網卡ifconfig down),設置hugepage后就可以使用了。

             

             

            在內核模塊igb加載時,會注冊pci設備驅動

            static struct pci_driver igbuio_pci_driver = {

            .name = "igb_uio",

            .id_table = NULL,

            .probe = igbuio_pci_probe,

            .remove = igbuio_pci_remove,

            };

             

            在綁定網卡時,會調用igbuio_pci_probe,使用用戶態驅動uio接管網卡(中斷處理、mmap映射設備內存到用戶空間)

            系統啟動時,bios會將設備總線地址信息記錄在/sys/bus/pci/devices,dpdk程序啟動時會去這里掃描pci設備,根據不同類型的NIC有對應的初始化流程。在后面配置隊列的時候會把用戶態的隊列內存地址通過硬件指令交給NIC,從而實現零拷貝。


             

            如果NIC收到包,會做標記,輪詢的時候通過標記取數據包

            while (nb_rx < nb_pkts) {

            /*

             * The order of operations here is important as the DD status

             * bit must not be read after any other descriptor fields.

             * rx_ring and rxdp are pointing to volatile data so the order

             * of accesses cannot be reordered by the compiler. If they were

             * not volatile, they could be reordered which could lead to

             * using invalid descriptor fields when read from rxd.

             */

            rxdp = &rx_ring[rx_id];

            staterr = rxdp->wb.upper.status_error;

            if (! (staterr & rte_cpu_to_le_32(E1000_RXD_STAT_DD)))

            break;

            rxd = *rxdp;

            發包的輪詢就是輪詢發包結束的硬件標志位,硬件發包完成會寫回標志位,驅動發現后再釋放對應的描述符和緩沖塊。

             

            KNI

            通過創建一個虛擬網卡,將收到的包丟給協議棧

             /* 發送skb到協議棧 */

                        /* Call netif interface */

                        netif_receive_skb(skb);

             

            POWER

            在負載小的時候沒有必要使用輪詢模式,這時可以打開網卡中斷 使用eventfd  epoll通知用戶層

             

            Ring

            無鎖環形隊列的核心就是操作頭尾索引,先將頭尾索引賦給臨時變量,再把尾索引往后跳n個位置,利用cas判斷頭如果還是在原來的位置就指向尾否則就重復這個過程,然后在操作中間跳過的n個元素就是安全的了,此時頭尾索引應該指向同一個位置,如果不同應該是有別的線程也在操作,重復等待即可。(這里有個細節,索引是只加不減的,因為是環形隊列索引又是unsigned 32bits,所以每次取數據前把索引模隊列長度-1, uint32_t mask;           /**< Mask (size-1) of ring. */即可)

             

            Windows下使用vmware虛擬機的時候出現EAL: Error reading from file descriptor,根據網上的說法打了patch還是不行,后來嘗試掛載內核模塊的時候不加載vfio模塊就可以了

             

            posted on 2017-02-05 14:08 clcl 閱讀(882) 評論(0)  編輯 收藏 引用
            精品人妻伦一二三区久久| 99久久做夜夜爱天天做精品| 一本久久久久久久| 久久精品免费大片国产大片| 久久国产色av免费看| 久久99中文字幕久久| 久久免费看黄a级毛片| 97久久精品人人澡人人爽| 亚洲中文久久精品无码| 久久e热在这里只有国产中文精品99| 亚洲国产精品无码久久久秋霞2| 日本福利片国产午夜久久| 亚洲中文字幕久久精品无码APP | 久久精品国产亚洲精品| 亚洲AV无码久久精品色欲| 欧美色综合久久久久久| 久久国产成人精品麻豆| 看久久久久久a级毛片| 亚洲精品国产第一综合99久久| 久久国产精品-久久精品| 久久人人爽人人爽人人AV东京热 | 久久精品国产亚洲精品| 国产精品99久久99久久久| 精品久久久久久国产| 无码任你躁久久久久久久| 国产精品青草久久久久福利99| 国产一级持黄大片99久久| 久久精品无码专区免费青青 | 国内精品久久久久久中文字幕| 国产精品久久久久jk制服| 国产亚洲色婷婷久久99精品| 亚洲国产精品无码久久98| 亚洲精品乱码久久久久66| 伊人久久综合无码成人网| 亚洲中文久久精品无码| 亚洲综合日韩久久成人AV| 久久婷婷五月综合成人D啪| 综合久久国产九一剧情麻豆| 一本一本久久aa综合精品| 久久久免费精品re6| AV色综合久久天堂AV色综合在 |