| #include <common.h> |
| |
| int |
| responder (memif_conn_handle_t conn, void *private_ctx, uint16_t qid) |
| { |
| memif_connection_t *c = (memif_connection_t *) private_ctx; |
| int err, i; |
| uint16_t tx; |
| |
| /* receive packets from the shared memory */ |
| err = memif_rx_burst (conn, qid, c->rx_bufs, MAX_MEMIF_BUFS, &c->rx_buf_num); |
| if (err != MEMIF_ERR_SUCCESS) |
| { |
| INFO ("memif_rx_burst: %s", memif_strerror (err)); |
| return err; |
| } |
| |
| do |
| { |
| /* allocate tx buffers */ |
| err = memif_buffer_alloc (conn, qid, c->tx_bufs, c->rx_buf_num, |
| &c->tx_buf_num, 2048); |
| /* suppress full ring error MEMIF_ERR_NOBUF_RING */ |
| if (err != MEMIF_ERR_SUCCESS && err != MEMIF_ERR_NOBUF_RING) |
| { |
| INFO ("memif_buffer_alloc: %s", memif_strerror (err)); |
| goto error; |
| } |
| |
| /* Process the packets */ |
| if (c->packet_handler == NULL) |
| { |
| INFO ("Missing packet handler"); |
| goto error; |
| } |
| err = c->packet_handler (c); |
| if (err != 0) |
| { |
| INFO ("packet handler error: %d", err); |
| goto error; |
| } |
| /* Done processing packets */ |
| |
| /* refill the queue */ |
| err = memif_refill_queue (conn, qid, c->tx_buf_num, 0); |
| if (err != MEMIF_ERR_SUCCESS) |
| { |
| INFO ("memif_refill_queue: %s", memif_strerror (err)); |
| goto error; |
| } |
| c->rx_buf_num -= c->tx_buf_num; |
| |
| err = memif_tx_burst (conn, qid, c->tx_bufs, c->tx_buf_num, &tx); |
| if (err != MEMIF_ERR_SUCCESS) |
| { |
| INFO ("memif_tx_burst: %s", memif_strerror (err)); |
| goto error; |
| } |
| c->tx_buf_num -= tx; |
| |
| /* This should never happen */ |
| if (c->tx_buf_num != 0) |
| { |
| INFO ("memif_tx_burst failed to send all allocated buffers."); |
| goto error; |
| } |
| } |
| while (c->rx_buf_num > 0); |
| |
| return 0; |
| |
| error: |
| err = memif_refill_queue (conn, qid, c->rx_buf_num, 0); |
| if (err != MEMIF_ERR_SUCCESS) |
| { |
| INFO ("memif_refill_queue: %s", memif_strerror (err)); |
| return err; |
| } |
| c->rx_buf_num = 0; |
| |
| return -1; |
| } |
| |
| int |
| responder_zero_copy (memif_conn_handle_t conn, void *private_ctx, uint16_t qid) |
| { |
| memif_connection_t *c = (memif_connection_t *) private_ctx; |
| int err, i; |
| uint16_t tx, tx2; |
| |
| /* receive packets from the shared memory */ |
| err = memif_rx_burst (conn, qid, c->rx_bufs, MAX_MEMIF_BUFS, &c->rx_buf_num); |
| if (err != MEMIF_ERR_SUCCESS) |
| { |
| INFO ("memif_rx_burst: %s", memif_strerror (err)); |
| return err; |
| } |
| |
| do |
| { |
| /* Note that in zero copy memif_buffer_alloc is not part of respond |
| process, |
| * instead rx buffers are used directly using memif_buffer_enq_tx. |
| * / |
| |
| /* Process the packets */ |
| if (c->packet_handler == NULL) |
| { |
| INFO ("Missing packet handler"); |
| goto error; |
| } |
| err = c->packet_handler (c); |
| if (err != 0) |
| { |
| INFO ("packet handler error: %d", err); |
| goto error; |
| } |
| /* Done processing packets */ |
| |
| /* Swap rx and tx buffers, swapped tx buffers are considered allocated |
| * and are ready to be transmitted. Notice that the buffers are swapped |
| * only in memif driver and locally remain in rx_bufs queue. |
| */ |
| err = memif_buffer_enq_tx (conn, qid, c->rx_bufs, c->rx_buf_num, &tx); |
| /* suppress full ring error MEMIF_ERR_NOBUF_RING */ |
| if (err != MEMIF_ERR_SUCCESS && err != MEMIF_ERR_NOBUF_RING) |
| { |
| INFO ("memif_buffer_alloc: %s", memif_strerror (err)); |
| goto error; |
| } |
| |
| /* refill the queue */ |
| err = memif_refill_queue (conn, qid, tx, 0); |
| if (err != MEMIF_ERR_SUCCESS) |
| { |
| INFO ("memif_refill_queue: %s", memif_strerror (err)); |
| goto error; |
| } |
| c->rx_buf_num -= tx; |
| |
| /* Notice that we send from rx_bufs as the buffers were only swapped |
| * internally in memif driver */ |
| err = memif_tx_burst (conn, qid, c->rx_bufs, tx, &tx2); |
| if (err != MEMIF_ERR_SUCCESS) |
| { |
| INFO ("memif_tx_burst: %s", memif_strerror (err)); |
| goto error; |
| } |
| tx -= tx2; |
| |
| /* This should never happen */ |
| if (tx != 0) |
| { |
| INFO ("memif_tx_burst failed to send all allocated buffers."); |
| goto error; |
| } |
| } |
| while (c->rx_buf_num > 0); |
| |
| return 0; |
| |
| error: |
| err = memif_refill_queue (conn, qid, c->rx_buf_num, 0); |
| if (err != MEMIF_ERR_SUCCESS) |
| { |
| INFO ("memif_refill_queue: %s", memif_strerror (err)); |
| return err; |
| } |
| c->rx_buf_num = 0; |
| |
| return -1; |
| } |