pub struct MemInfo {
    pub receive_queue: u32,
    pub receive_queue_max: u32,
    pub send_queue: u32,
    pub send_queue_max: u32,
    pub bottom_send_queues: u32,
    pub cache: u32,
    pub options: u32,
    pub backlog_queue_length: u32,
    pub drops: u32,
}
Expand description

Socket memory information. To understand this information, one must understand how the memory allocated for the send and receive queues of a socket is managed.

§Warning

This data structure is not well documented. The explanations given here are the results of my personal research on this topic, but I am by no mean an expert in Linux networking, so take this documentation with a huge grain of salt. Please report any error you may notice. Here are the references I used:

§Linux networking in a nutshell

The network stack uses multiple queues, both for sending an receiving data. Let’s start with the simplest case: packet receptions.

When data is received, it is first handled by the device driver and put in the device driver queue. The kernel then move the packet to the socket receive queue (also called receive buffer). Finally, this application reads it (with recv, read or recvfrom) and the packet is dequeued.

Sending packet it slightly more complicated and the exact workflow may differ from one protocol to the other so we’ll just give a high level overview. When an application sends data, a packet is created and stored in the socket send queue (also called send buffer). It is then passed down to the QDisc (Queuing Disciplines) queue. The QDisc facility enables quality of service: if some data is more urgent to transmit than other, QDisc will make sure it is sent in priority. Finally, the data is put on the device driver queue to be sent out.

Fields§

§receive_queue: u32

Memory currently allocated for the socket’s receive queue. This attribute is known as sk_rmem_alloc in the kernel.

§receive_queue_max: u32

Maximum amount of memory that can be allocated for the socket’s receive queue. This is set by SO_RCVBUF. This is not the amount of memory currently allocated. This attribute is known as sk_rcvbuf in the kernel.

§send_queue: u32

Memory currently allocated for the socket send queue. This attribute is known as sk_wmem_queued in the kernel. This does does not account for data that have been passed down the network stack (i.e. to the QDisc and device driver queues), which is reported by the bottow_send_queue (known as sk_wmem_alloc in the kernel).

For a TCP socket, if the congestion window is small, the kernel will move the data fron the socket send queue to the QDisc queues more slowly. Thus, if the process sends of lot of data, the socket send queue (which memory is tracked by sk_wmem_queued) will grow while sk_wmem_alloc will remain small.

§send_queue_max: u32

Maximum amount of memory (in bytes) that can be allocated for this socket’s send queue. This is set by SO_SNDBUF. This is not the amount of memory currently allocated. This attribute is known as sk_sndbuf in the kernel.

§bottom_send_queues: u32

Memory used for packets that have been passed down the network stack, i.e. that are either in the QDisc or device driver queues. This attribute is known as sk_wmem_alloc in the kernel. See also [send_queue].

§cache: u32

The amount of memory already allocated for this socket but currently unused. When more memory is needed either for sending or for receiving data, it will be taken from this pool. This attribute is known as sk_fwd_alloc in the kernel.

§options: u32

The amount of memory allocated for storing socket options, for instance the key for TCP MD5 signature. This attribute is known as sk_optmem in the kernel.

§backlog_queue_length: u32

The length of the backlog queue. When the process is using the socket, the socket is locked so the kernel cannot enqueue new packets in the receive queue. To avoid blocking the bottom half of network stack waiting for the process to release the socket, the packets are enqueued in the backlog queue. Upon releasing the socket, those packets are processed and put in the regular receive queue.

§drops: u32

The amount of packets dropped. Depending on the kernel version, this field may not be present.

Trait Implementations§

source§

impl Clone for MemInfo

source§

fn clone(&self) -> MemInfo

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for MemInfo

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Emitable for MemInfo

source§

fn buffer_len(&self) -> usize

Return the length of the serialized data.
source§

fn emit(&self, buf: &mut [u8])

Serialize this types and write the serialized data into the given buffer. Read more
source§

impl<T: AsRef<[u8]>> Parseable<MemInfoBuffer<T>> for MemInfo

§

type Error = DecodeError

source§

fn parse(buf: &MemInfoBuffer<T>) -> Result<Self, DecodeError>

Deserialize the current type.
source§

impl PartialEq for MemInfo

source§

fn eq(&self, other: &MemInfo) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Eq for MemInfo

source§

impl StructuralPartialEq for MemInfo

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.