szedata2: add scattered Rx
Add new RX function for handling scattered packets. Signed-off-by: Matej Vido <matejvido@gmail.com>
This commit is contained in:
parent
906cea82aa
commit
d992985ff3
@ -358,6 +358,338 @@ eth_szedata2_rx(void *queue,
|
||||
return num_rx;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
eth_szedata2_rx_scattered(void *queue,
|
||||
struct rte_mbuf **bufs,
|
||||
uint16_t nb_pkts)
|
||||
{
|
||||
unsigned int i;
|
||||
struct rte_mbuf *mbuf;
|
||||
struct szedata2_rx_queue *sze_q = queue;
|
||||
struct rte_pktmbuf_pool_private *mbp_priv;
|
||||
uint16_t num_rx = 0;
|
||||
uint16_t buf_size;
|
||||
uint16_t sg_size;
|
||||
uint16_t hw_size;
|
||||
uint16_t packet_size;
|
||||
uint64_t num_bytes = 0;
|
||||
struct szedata *sze = sze_q->sze;
|
||||
uint8_t *header_ptr = NULL; /* header of packet */
|
||||
uint8_t *packet_ptr1 = NULL;
|
||||
uint8_t *packet_ptr2 = NULL;
|
||||
uint16_t packet_len1 = 0;
|
||||
uint16_t packet_len2 = 0;
|
||||
uint16_t hw_data_align;
|
||||
|
||||
if (unlikely(sze_q->sze == NULL || nb_pkts == 0))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Reads the given number of packets from szedata2 channel given
|
||||
* by queue and copies the packet data into a newly allocated mbuf
|
||||
* to return.
|
||||
*/
|
||||
for (i = 0; i < nb_pkts; i++) {
|
||||
const struct szedata_lock *ct_rx_lck_backup;
|
||||
unsigned int ct_rx_rem_bytes_backup;
|
||||
unsigned char *ct_rx_cur_ptr_backup;
|
||||
|
||||
/* get the next sze packet */
|
||||
if (sze->ct_rx_lck != NULL && !sze->ct_rx_rem_bytes &&
|
||||
sze->ct_rx_lck->next == NULL) {
|
||||
/* unlock old data */
|
||||
szedata_rx_unlock_data(sze_q->sze, sze->ct_rx_lck_orig);
|
||||
sze->ct_rx_lck_orig = NULL;
|
||||
sze->ct_rx_lck = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store items from sze structure which can be changed
|
||||
* before mbuf allocating. Use these items in case of mbuf
|
||||
* allocating failure.
|
||||
*/
|
||||
ct_rx_lck_backup = sze->ct_rx_lck;
|
||||
ct_rx_rem_bytes_backup = sze->ct_rx_rem_bytes;
|
||||
ct_rx_cur_ptr_backup = sze->ct_rx_cur_ptr;
|
||||
|
||||
if (!sze->ct_rx_rem_bytes && sze->ct_rx_lck_orig == NULL) {
|
||||
/* nothing to read, lock new data */
|
||||
sze->ct_rx_lck = szedata_rx_lock_data(sze_q->sze, ~0U);
|
||||
sze->ct_rx_lck_orig = sze->ct_rx_lck;
|
||||
|
||||
/*
|
||||
* Backup items from sze structure must be updated
|
||||
* after locking to contain pointers to new locks.
|
||||
*/
|
||||
ct_rx_lck_backup = sze->ct_rx_lck;
|
||||
ct_rx_rem_bytes_backup = sze->ct_rx_rem_bytes;
|
||||
ct_rx_cur_ptr_backup = sze->ct_rx_cur_ptr;
|
||||
|
||||
if (sze->ct_rx_lck == NULL)
|
||||
/* nothing to lock */
|
||||
break;
|
||||
|
||||
sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
|
||||
sze->ct_rx_rem_bytes = sze->ct_rx_lck->len;
|
||||
|
||||
if (!sze->ct_rx_rem_bytes)
|
||||
break;
|
||||
}
|
||||
|
||||
if (sze->ct_rx_rem_bytes < RTE_SZE2_PACKET_HEADER_SIZE) {
|
||||
/*
|
||||
* cut in header - copy parts of header to merge buffer
|
||||
*/
|
||||
if (sze->ct_rx_lck->next == NULL)
|
||||
break;
|
||||
|
||||
/* copy first part of header */
|
||||
rte_memcpy(sze->ct_rx_buffer, sze->ct_rx_cur_ptr,
|
||||
sze->ct_rx_rem_bytes);
|
||||
|
||||
/* copy second part of header */
|
||||
sze->ct_rx_lck = sze->ct_rx_lck->next;
|
||||
sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
|
||||
rte_memcpy(sze->ct_rx_buffer + sze->ct_rx_rem_bytes,
|
||||
sze->ct_rx_cur_ptr,
|
||||
RTE_SZE2_PACKET_HEADER_SIZE -
|
||||
sze->ct_rx_rem_bytes);
|
||||
|
||||
sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE -
|
||||
sze->ct_rx_rem_bytes;
|
||||
sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
|
||||
RTE_SZE2_PACKET_HEADER_SIZE +
|
||||
sze->ct_rx_rem_bytes;
|
||||
|
||||
header_ptr = (uint8_t *)sze->ct_rx_buffer;
|
||||
} else {
|
||||
/* not cut */
|
||||
header_ptr = (uint8_t *)sze->ct_rx_cur_ptr;
|
||||
sze->ct_rx_cur_ptr += RTE_SZE2_PACKET_HEADER_SIZE;
|
||||
sze->ct_rx_rem_bytes -= RTE_SZE2_PACKET_HEADER_SIZE;
|
||||
}
|
||||
|
||||
sg_size = le16toh(*((uint16_t *)header_ptr));
|
||||
hw_size = le16toh(*(((uint16_t *)header_ptr) + 1));
|
||||
packet_size = sg_size -
|
||||
RTE_SZE2_ALIGN8(RTE_SZE2_PACKET_HEADER_SIZE + hw_size);
|
||||
|
||||
|
||||
/* checks if packet all right */
|
||||
if (!sg_size)
|
||||
errx(5, "Zero segsize");
|
||||
|
||||
/* check sg_size and hwsize */
|
||||
if (hw_size > sg_size - RTE_SZE2_PACKET_HEADER_SIZE) {
|
||||
errx(10, "Hwsize bigger than expected. Segsize: %d, "
|
||||
"hwsize: %d", sg_size, hw_size);
|
||||
}
|
||||
|
||||
hw_data_align =
|
||||
RTE_SZE2_ALIGN8((RTE_SZE2_PACKET_HEADER_SIZE +
|
||||
hw_size)) - RTE_SZE2_PACKET_HEADER_SIZE;
|
||||
|
||||
if (sze->ct_rx_rem_bytes >=
|
||||
(uint16_t)(sg_size -
|
||||
RTE_SZE2_PACKET_HEADER_SIZE)) {
|
||||
/* no cut */
|
||||
/* one packet ready - go to another */
|
||||
packet_ptr1 = sze->ct_rx_cur_ptr + hw_data_align;
|
||||
packet_len1 = packet_size;
|
||||
packet_ptr2 = NULL;
|
||||
packet_len2 = 0;
|
||||
|
||||
sze->ct_rx_cur_ptr += RTE_SZE2_ALIGN8(sg_size) -
|
||||
RTE_SZE2_PACKET_HEADER_SIZE;
|
||||
sze->ct_rx_rem_bytes -= RTE_SZE2_ALIGN8(sg_size) -
|
||||
RTE_SZE2_PACKET_HEADER_SIZE;
|
||||
} else {
|
||||
/* cut in data */
|
||||
if (sze->ct_rx_lck->next == NULL) {
|
||||
errx(6, "Need \"next\" lock, but it is "
|
||||
"missing: %u", sze->ct_rx_rem_bytes);
|
||||
}
|
||||
|
||||
/* skip hw data */
|
||||
if (sze->ct_rx_rem_bytes <= hw_data_align) {
|
||||
uint16_t rem_size = hw_data_align -
|
||||
sze->ct_rx_rem_bytes;
|
||||
|
||||
/* MOVE to next lock */
|
||||
sze->ct_rx_lck = sze->ct_rx_lck->next;
|
||||
sze->ct_rx_cur_ptr =
|
||||
(void *)(((uint8_t *)
|
||||
(sze->ct_rx_lck->start)) + rem_size);
|
||||
|
||||
packet_ptr1 = sze->ct_rx_cur_ptr;
|
||||
packet_len1 = packet_size;
|
||||
packet_ptr2 = NULL;
|
||||
packet_len2 = 0;
|
||||
|
||||
sze->ct_rx_cur_ptr +=
|
||||
RTE_SZE2_ALIGN8(packet_size);
|
||||
sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
|
||||
rem_size - RTE_SZE2_ALIGN8(packet_size);
|
||||
} else {
|
||||
/* get pointer and length from first part */
|
||||
packet_ptr1 = sze->ct_rx_cur_ptr +
|
||||
hw_data_align;
|
||||
packet_len1 = sze->ct_rx_rem_bytes -
|
||||
hw_data_align;
|
||||
|
||||
/* MOVE to next lock */
|
||||
sze->ct_rx_lck = sze->ct_rx_lck->next;
|
||||
sze->ct_rx_cur_ptr = sze->ct_rx_lck->start;
|
||||
|
||||
/* get pointer and length from second part */
|
||||
packet_ptr2 = sze->ct_rx_cur_ptr;
|
||||
packet_len2 = packet_size - packet_len1;
|
||||
|
||||
sze->ct_rx_cur_ptr +=
|
||||
RTE_SZE2_ALIGN8(packet_size) -
|
||||
packet_len1;
|
||||
sze->ct_rx_rem_bytes = sze->ct_rx_lck->len -
|
||||
(RTE_SZE2_ALIGN8(packet_size) -
|
||||
packet_len1);
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(packet_ptr1 == NULL))
|
||||
break;
|
||||
|
||||
mbuf = rte_pktmbuf_alloc(sze_q->mb_pool);
|
||||
|
||||
if (unlikely(mbuf == NULL)) {
|
||||
/*
|
||||
* Restore items from sze structure to state after
|
||||
* unlocking (eventually locking).
|
||||
*/
|
||||
sze->ct_rx_lck = ct_rx_lck_backup;
|
||||
sze->ct_rx_rem_bytes = ct_rx_rem_bytes_backup;
|
||||
sze->ct_rx_cur_ptr = ct_rx_cur_ptr_backup;
|
||||
break;
|
||||
}
|
||||
|
||||
/* get the space available for data in the mbuf */
|
||||
mbp_priv = rte_mempool_get_priv(sze_q->mb_pool);
|
||||
buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
|
||||
RTE_PKTMBUF_HEADROOM);
|
||||
|
||||
if (packet_size <= buf_size) {
|
||||
/* sze packet will fit in one mbuf, go ahead and copy */
|
||||
rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
|
||||
packet_ptr1, packet_len1);
|
||||
if (packet_ptr2 != NULL) {
|
||||
rte_memcpy((void *)
|
||||
(rte_pktmbuf_mtod(mbuf, uint8_t *) +
|
||||
packet_len1), packet_ptr2, packet_len2);
|
||||
}
|
||||
mbuf->data_len = (uint16_t)packet_size;
|
||||
} else {
|
||||
/*
|
||||
* sze packet will not fit in one mbuf,
|
||||
* scatter packet into more mbufs
|
||||
*/
|
||||
struct rte_mbuf *m = mbuf;
|
||||
uint16_t len = rte_pktmbuf_tailroom(mbuf);
|
||||
|
||||
/* copy first part of packet */
|
||||
/* fill first mbuf */
|
||||
rte_memcpy(rte_pktmbuf_append(mbuf, len), packet_ptr1,
|
||||
len);
|
||||
packet_len1 -= len;
|
||||
packet_ptr1 = ((uint8_t *)packet_ptr1) + len;
|
||||
|
||||
while (packet_len1 > 0) {
|
||||
/* fill new mbufs */
|
||||
m->next = rte_pktmbuf_alloc(sze_q->mb_pool);
|
||||
|
||||
if (unlikely(m->next == NULL)) {
|
||||
rte_pktmbuf_free(mbuf);
|
||||
/*
|
||||
* Restore items from sze structure
|
||||
* to state after unlocking (eventually
|
||||
* locking).
|
||||
*/
|
||||
sze->ct_rx_lck = ct_rx_lck_backup;
|
||||
sze->ct_rx_rem_bytes =
|
||||
ct_rx_rem_bytes_backup;
|
||||
sze->ct_rx_cur_ptr =
|
||||
ct_rx_cur_ptr_backup;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
m = m->next;
|
||||
|
||||
len = RTE_MIN(rte_pktmbuf_tailroom(m),
|
||||
packet_len1);
|
||||
rte_memcpy(rte_pktmbuf_append(mbuf, len),
|
||||
packet_ptr1, len);
|
||||
|
||||
(mbuf->nb_segs)++;
|
||||
packet_len1 -= len;
|
||||
packet_ptr1 = ((uint8_t *)packet_ptr1) + len;
|
||||
}
|
||||
|
||||
if (packet_ptr2 != NULL) {
|
||||
/* copy second part of packet, if exists */
|
||||
/* fill the rest of currently last mbuf */
|
||||
len = rte_pktmbuf_tailroom(m);
|
||||
rte_memcpy(rte_pktmbuf_append(mbuf, len),
|
||||
packet_ptr2, len);
|
||||
packet_len2 -= len;
|
||||
packet_ptr2 = ((uint8_t *)packet_ptr2) + len;
|
||||
|
||||
while (packet_len2 > 0) {
|
||||
/* fill new mbufs */
|
||||
m->next = rte_pktmbuf_alloc(
|
||||
sze_q->mb_pool);
|
||||
|
||||
if (unlikely(m->next == NULL)) {
|
||||
rte_pktmbuf_free(mbuf);
|
||||
/*
|
||||
* Restore items from sze
|
||||
* structure to state after
|
||||
* unlocking (eventually
|
||||
* locking).
|
||||
*/
|
||||
sze->ct_rx_lck =
|
||||
ct_rx_lck_backup;
|
||||
sze->ct_rx_rem_bytes =
|
||||
ct_rx_rem_bytes_backup;
|
||||
sze->ct_rx_cur_ptr =
|
||||
ct_rx_cur_ptr_backup;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
m = m->next;
|
||||
|
||||
len = RTE_MIN(rte_pktmbuf_tailroom(m),
|
||||
packet_len2);
|
||||
rte_memcpy(
|
||||
rte_pktmbuf_append(mbuf, len),
|
||||
packet_ptr2, len);
|
||||
|
||||
(mbuf->nb_segs)++;
|
||||
packet_len2 -= len;
|
||||
packet_ptr2 = ((uint8_t *)packet_ptr2) +
|
||||
len;
|
||||
}
|
||||
}
|
||||
}
|
||||
mbuf->pkt_len = packet_size;
|
||||
mbuf->port = sze_q->in_port;
|
||||
bufs[num_rx] = mbuf;
|
||||
num_rx++;
|
||||
num_bytes += packet_size;
|
||||
}
|
||||
|
||||
finish:
|
||||
sze_q->rx_pkts += num_rx;
|
||||
sze_q->rx_bytes += num_bytes;
|
||||
return num_rx;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
eth_szedata2_tx(void *queue,
|
||||
struct rte_mbuf **bufs,
|
||||
@ -860,8 +1192,16 @@ eth_dev_stop(struct rte_eth_dev *dev)
|
||||
}
|
||||
|
||||
static int
|
||||
eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
|
||||
eth_dev_configure(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct rte_eth_dev_data *data = dev->data;
|
||||
if (data->dev_conf.rxmode.enable_scatter == 1) {
|
||||
dev->rx_pkt_burst = eth_szedata2_rx_scattered;
|
||||
data->scattered_rx = 1;
|
||||
} else {
|
||||
dev->rx_pkt_burst = eth_szedata2_rx;
|
||||
data->scattered_rx = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1141,12 +1481,15 @@ rte_eth_from_szedata2(const char *name,
|
||||
{
|
||||
struct pmd_internals *internals = NULL;
|
||||
struct rte_eth_dev *eth_dev = NULL;
|
||||
struct rte_eth_dev_data *data = NULL;
|
||||
int ret;
|
||||
|
||||
if (rte_pmd_init_internals(name, 0, 0, numa_node,
|
||||
&internals, ð_dev) < 0)
|
||||
return -1;
|
||||
|
||||
data = eth_dev->data;
|
||||
|
||||
internals->sze_dev = szedata2->sze_dev;
|
||||
internals->sze_rx_req = szedata2->sze_rx_mask_req;
|
||||
internals->sze_tx_req = szedata2->sze_tx_mask_req;
|
||||
@ -1171,7 +1514,14 @@ rte_eth_from_szedata2(const char *name,
|
||||
return -1;
|
||||
}
|
||||
|
||||
eth_dev->rx_pkt_burst = eth_szedata2_rx;
|
||||
if (data->dev_conf.rxmode.enable_scatter == 1 ||
|
||||
data->scattered_rx == 1) {
|
||||
eth_dev->rx_pkt_burst = eth_szedata2_rx_scattered;
|
||||
data->scattered_rx = 1;
|
||||
} else {
|
||||
eth_dev->rx_pkt_burst = eth_szedata2_rx;
|
||||
data->scattered_rx = 0;
|
||||
}
|
||||
eth_dev->tx_pkt_burst = eth_szedata2_tx;
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user