sock->sk_wmem_alloc 和 sock->sk_wmem_queued 有什麼區別
中定義的
sock
結構sock.h
有兩個看起來非常相似的屬性:
sk_wmem_alloc
,定義為“送出的傳輸隊列字節數”sk_wmem_queued
,定義為“持久隊列大小”對我來說,這
sk_wmem_alloc
是目前分配給發送隊列的記憶體量。但是,什麼是sk_wmem_queued
?參考
wmem_queued:傳輸隊列中排隊的套接字發送緩衝區使用的記憶體量,並且尚未發送出去或尚未確認。
- 該
ss
人還給出了定義,但並沒有真正啟發我(我不明白 IP 層與此有什麼關係):wmem_alloc:用於發送數據包的記憶體(已發送到第 3 層) wmem_queued:分配用於發送數據包的記憶體(尚未發送到第 3 層)
- 有人已經在 LKML 上問過類似的問題,但沒有得到答案
- 手冊頁也對這些
sock_diag(7)
屬性有自己的定義:SK_MEMINFO_WMEM_ALLOC:發送隊列中的數據量。 SK_MEMINFO_WMEM_QUEUED:TCP 排隊但尚未發送的數據量。
所有這些定義都是不同的,沒有一個能清楚地解釋
_alloc
和_queued
變體的不同之處。
我給 Linux 網路堆棧貢獻者 Eric Dumazet 發了電子郵件,答案如下:
sk_wmem_alloc
跟踪傳輸堆棧後排隊的 skb 的字節數:qdisc 層和 NIC TX 環形緩衝區。如果您有 1 MB 的數據位於 TCP 寫入隊列中,尚未發送(cwnd 限制),
sk_wmem_queue
大約為 1 MB,但sk_wmem_alloc
大約為 0了解這三種類型的隊列(socket 緩衝區、qdisc 隊列和設備隊列)是什麼的一個很好的文件是這篇文章(相當長)。簡而言之,套接字首先將數據包直接推送到 qdisc 隊列,然後將它們轉發到設備隊列。當 qdisc 隊列已滿時,套接字開始在自己的寫入隊列中緩衝數據。
網路堆棧將數據包直接放入隊列規則中,或者如果隊列已滿,則將數據包推回上層(例如套接字緩衝區)
所以基本上:
sk_wmem_queues
是套接字緩衝區(sock.sk_write_queue
)sk_wmem_alloc
使用的記憶體,而是 qdisc 和設備隊列中的數據包使用的記憶體。