Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Data Fields
__netio_buffer_queue_t Struct Reference

#include <drv_xgbe_impl.h>

Data Fields

volatile uint32_t __buffer_write
 
uint32_t __last_buffer
 

Detailed Description

A queue of buffers.

This structure partially defines a queue of empty buffers which have been obtained via requests to the IPP. (The elements of the queue are packet handles, which are transformed into a full netio_pkt_t when the buffer is retrieved.) The queue as a whole is written to by an interrupt handler and read by non-interrupt code; this data structure is what's touched by the interrupt handler. The other parts of the queue state, the read offset and requested write offset, are kept in user space, not in hypervisor space, so they are in a separate data structure.

The read offset (__buffer_read in the user part of the queue structure) points to the next buffer to be read. When the read offset is equal to the write offset, the queue is empty; therefore the queue must contain one more slot than the required maximum queue size.

The requested write offset (__buffer_requested_write in the user part of the queue structure) points to the slot which will hold the next buffer we request from the IPP, once we get around to sending such a request. When the requested write offset is equal to the write offset, no requests for new buffers are outstanding; when the requested write offset is one greater than the read offset, no more requests may be sent.

Note that, unlike the packet_queue, the buffer_queue places incoming buffers at decreasing addresses. This makes the check for "is it time to wrap the buffer pointer" cheaper in the assembly code which receives new buffers, and means that the value which defines the queue size, __last_buffer, is different than in the packet queue. Also, the offset used in the packet_queue is already scaled by the size of a packet; here we use unscaled slot indices for the offsets. (These differences are historical, and in the future it's possible that the packet_queue will look more like this queue.)

Here's an example of all 4 state variables and what they mean. Remember:
all pointers move right to left.
V V V I I R R V V V
0 1 2 3 4 5 6 7 8 9
^ ^ ^ ^
| | | |
| | | __last_buffer
| | __buffer_write
| __buffer_requested_write
__buffer_read

This queue has 10 slots, and thus can hold 9 buffers (_last_buffer = 9). The read pointer is at 2, and the write pointer is at 6; thus, there are valid, unread buffers in slots 2, 1, 0, 9, 8, and 7. The requested write pointer is at 4; thus, requests have been made to the IPP for buffers which will be placed in slots 6 and 5 when they arrive. Finally, the remaining slots are invalid (do not contain a buffer).

Definition at line 178 of file drv_xgbe_impl.h.

Field Documentation

volatile uint32_t __buffer_write

Ordinal number of the next buffer to be written: 0 for the first slot in the queue, 1 for the second slot in the queue, etc.

Definition at line 182 of file drv_xgbe_impl.h.

uint32_t __last_buffer

Ordinal number of the last buffer (i.e., when any pointer is decremented below zero, it is reloaded with this value).

Definition at line 186 of file drv_xgbe_impl.h.


The documentation for this struct was generated from the following file: