Linux

sock->sk_wmem_alloc 和 sock->sk_wmem_queued 有什麼區別

  • November 12, 2019

中定義的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 層)

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_queuesk_wmem_alloc使用的記憶體,而是 qdisc 和設備隊列中的數據包使用的記憶體。

引用自:https://unix.stackexchange.com/questions/551444