> Many sample apps include internal buffering for single-packet-at-a-time > operation. Since this is such a common paradigm, this functionality is > better suited to being implemented in the ethdev API. > > The new APIs in the ethdev library are: > * rte_eth_tx_buffer_init - initialize buffer > * rte_eth_tx_buffer - buffer up a single packet for future transmission > * rte_eth_tx_buffer_flush - flush any unsent buffered packets > * rte_eth_tx_buffer_set_err_callback - set up a callback to be called in > case transmitting a buffered burst fails. By default, we just free the > unsent packets. > > As well as these, an additional reference callbacks are provided, which > frees the packets: > > * rte_eth_tx_buffer_drop_callback - silently drop packets (default > behavior) > * rte_eth_tx_buffer_count_callback - drop and update user-provided counter > to track the number of dropped packets > > Due to the feedback from mailing list, that buffer management facilities > in the user application are more preferable than API simplicity, we decided > to move internal buffer table, as well as callback functions and user data, > from rte_eth_dev/rte_eth_dev_data to the application space. > It prevents ABI breakage and gives some more flexibility in the buffer's > management such as allocation, dynamical size change, reuse buffers on many > ports or after fail, and so on. > > > The following steps illustrate how tx buffers can be used in application: > > 1) Initialization > > a) Allocate memory for a buffer > > struct rte_eth_dev_tx_buffer *buffer = rte_zmalloc_socket("tx_buffer", > RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, socket_id); > > RTE_ETH_TX_BUFFER_SIZE(size) macro computes memory required to store > "size" packets in buffer. > > b) Initialize allocated memory and set up default values. Threshold level > must be lower than or equal to the MAX_PKT_BURST from 1a) > > rte_eth_tx_buffer_init(buffer, threshold); > > > c) Set error callback (optional) > > rte_eth_tx_buffer_set_err_callback(buffer, callback_fn, userdata); > > > 2) Store packet "pkt" in buffer and send them all to the queue_id on > port_id when number of packets reaches threshold level set up in 1b) > > rte_eth_tx_buffer(port_id, queue_id, buffer, pkt); > > > 3) Send all stored packets to the queue_id on port_id > > rte_eth_tx_buffer_flush(port_id, queue_id, buffer); > > > 4) Flush buffer and free memory > > rte_eth_tx_buffer_flush(port_id, queue_id, buffer); > ... > rte_free(buffer); > > v3 changes: > - error counter removed from tx buffer structure, now default behavior is > silent drop of unsent packets > - some names was changed in tx buffer structure to be more descriptive > - two default calbacks are provided: rte_eth_tx_buffer_drop_callback and > rte_eth_tx_buffer_count_callback > > v2 changes: > - reworked to use new buffer model > - buffer data and callbacks are removed from rte_eth_dev/rte_eth_dev_data, > so this patch doesn't brake an ABI anymore > - introduced RTE_ETH_TX_BUFFER macro and rte_eth_tx_buffer_init > - buffers are not attached to the port-queue > - buffers can be allocated dynamically during application work > - size of buffer can be changed without port restart > > Tomasz Kulasek (2): > ethdev: add buffered tx api > examples: rework to use buffered tx > > examples/l2fwd-jobstats/main.c | 104 ++++------ > examples/l2fwd-keepalive/main.c | 100 ++++------ > examples/l2fwd/main.c | 104 ++++------ > examples/l3fwd-acl/main.c | 92 ++++----- > examples/l3fwd-power/main.c | 89 ++++----- > examples/link_status_interrupt/main.c | 107 ++++------ > .../client_server_mp/mp_client/client.c | 101 ++++++---- > examples/multi_process/l2fwd_fork/main.c | 97 ++++----- > examples/packet_ordering/main.c | 122 ++++++++---- > examples/qos_meter/main.c | 61 ++---- > lib/librte_ether/rte_ethdev.c | 46 +++++ > lib/librte_ether/rte_ethdev.h | 205 > +++++++++++++++++++- > lib/librte_ether/rte_ether_version.map | 10 + > 13 files changed, 696 insertions(+), 542 deletions(-) > > --
Acked-by: Konstantin Ananyev <konstantin.ananyev at intel.com> > 1.7.9.5