byte queue limits演算法試圖控制網絡卡傳送佇列的大小,如下intel的e1000驅動的網絡卡顯示當前傳送ring有256個,如果填滿256個1500位元組的報文,對於頻寬為1g的e1000完全傳送完成,需要256*1500/1g的時間,大約為3.84ms。意味值最後乙個報文要在本地經歷大約3.84ms的延遲,另一方面對於tcp協議,將對其rtt的估算等造成不利影響。
bql與tcp的tsq功能類似,但是tsq位於更高層的協議棧,來控制發往qdisc/device佇列中的報文的量。
$ sudo ethtool --show-ring ens33
ring parameters for ens33:
pre-set maximums:
rx: 4096
rx mini: 0
rx jumbo: 0
tx: 4096
current hardware settings:
rx: 256
rx mini: 0
rx jumbo: 0
tx: 256
對於bql,存在如何確定網絡卡傳送佇列大小限值的問題,首先,限值的表示方式,如果使用報文數量,有的報文可能包含很少的位元組,占用很少的傳送時間,而又存在比較大的報文,所以,採用報文數量進行控制造成不準確。bql最終使用的是位元組數量,但是其不是乙個固定的限值,將根據系統負荷而改變,因為對於負荷重的系統,傳送佇列的填充可能會延遲,造成網絡卡的閒置。相反,對於負荷輕的系統,使用較小的限值,傳送佇列填充及時的話,也可保持網絡卡的持續工作。核心中實現此功能的為dql(dynamic queue limits),bql實現在此功能之上。
bql在核心中增加了兩類介面,第乙個在網絡卡驅動程式中,當報文新增到網絡卡佇列中後,通知bql,其進行限值判斷。第二個是在網絡卡報文傳送完成之後,通知bql,進行相應處理,比如,之前停止的傳送佇列是否可開啟,以及更新bql的佇列限值。
核心函式為netdev_tx_sent_queue,如果dql判段達到限值,傳送佇列設定__queue_state_stack_xoff,停止傳送。dql演算法暫不介紹(不懂)。這裡,在再次檢查之前設定stack_off標誌位,是因為在bql的傳送完成處理函式netdev_tx_completed_queue中,完成空間的釋放之後(dql_completed),進行stack_off的檢查,如果為真,將再次進行傳送排程。所以這裡先將此標誌設定為真。
static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue, unsigned int bytes)
對於一些網絡卡驅動,目前主要是mellanox的mlx4驅動,以下封裝函式__netdev_tx_sent_queue用於在傳送batch型的skb報文時,僅在最後乙個skb處理時,進行是否要設定__queue_state_stack_xoff標誌的判斷。
static inline bool __netdev_tx_sent_queue(struct netdev_queue *dev_queue, unsigned int bytes, bool xmit_more)
netdev_tx_sent_queue(dev_queue, bytes);
return true;
}
對於intel網絡卡的i40e驅動,在傳送函式i40e_tx_map中,呼叫bql函式netdev_tx_sent_queue進行處理。
static inline int i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
struct i40e_tx_buffer *first, u32 tx_flags, const u8 hdr_len, u32 td_cmd, u32 td_offset)
仍然使用intel的i40e為例,在函式i40e_clean_tx_irq中,呼叫bql的函式netdev_tx_completed_queue。
static bool i40e_clean_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring, int napi_budget)
對於intel的i40e驅動,在函式i40e_clean_tx_ring中,呼叫bql系統的函式netdev_tx_reset_queue進行重置。
void i40e_clean_tx_ring(struct i40e_ring *tx_ring)
核心版本 5.0 shell佇列實現執行緒併發控制
請看原文 需求 併發檢測1000臺web伺服器狀態 或者併發為1000臺web伺服器分發檔案等 如何用shell實現?方案一 這應該是大多數人都第一時間想到的方法吧 思路 乙個for迴圈1000次,順序執行1000次任務。bin bash start time date s 定義指令碼執行的開始時間...
linux中斷控制之工作佇列
工作佇列是將工作推後執行的一種機制,並且可以睡眠。工作佇列結構 定義於 include核心3.1.4 原始碼位於kernel workqueue.c 先看工作佇列結構 struct work struct data的型別是atomic long t,只是個原子型別,相當於老版核心中的pending和...
activemq深入了解 佇列模式手動控制消費
相信經過了解,基本使用activemq後,大家一定知道佇列裡面有ack模式,他的型別有以下幾種 1 auto acknowledge 1 自動確認 2 client acknowledge 2 客戶端手動確認 3 dups ok acknowledge 3 自動批量確認 4 session tran...