netmap: pkt-gen: init all slots of every tx ring
sender_body() uses OPT_COPY to copy the frame into the destination slot for the first 100,000 packets. Then it removes OPT_COPY to improve performance. The function always starts with the first tx ring. If multiple tx rings are in use, it is possible that the initial 100k packets will only use the first ring. After OPT_COPY is removed, there may come a time when the first ring is full and sender_body() will move to the next ring which was never initialized. As a result it will send all zero packets. (This was discovered when the receiving NIC reported rx errors.) Before any transmissions, step through every tx ring and set NS_BUF_CHANGED on every slot. That will force send_packets() to initialize the slot when first used. Since it only copies when necessary, it performs better than always setting OPT_COPY. With this change, there is no reason for the "drop copy" code. Submitted by: Brian Poole <brian90013@gmail.com> MFC after: 7 days
This commit is contained in:
parent
935b194ded
commit
506336f2cd
@ -1604,7 +1604,7 @@ sender_body(void *data)
|
|||||||
uint64_t n = targ->g->npackets / targ->g->nthreads;
|
uint64_t n = targ->g->npackets / targ->g->nthreads;
|
||||||
uint64_t sent = 0;
|
uint64_t sent = 0;
|
||||||
uint64_t event = 0;
|
uint64_t event = 0;
|
||||||
int options = targ->g->options | OPT_COPY;
|
int options = targ->g->options;
|
||||||
struct timespec nexttime = { 0, 0}; // XXX silence compiler
|
struct timespec nexttime = { 0, 0}; // XXX silence compiler
|
||||||
int rate_limit = targ->g->tx_rate;
|
int rate_limit = targ->g->tx_rate;
|
||||||
struct pkt *pkt = &targ->pkt;
|
struct pkt *pkt = &targ->pkt;
|
||||||
@ -1678,6 +1678,19 @@ sender_body(void *data)
|
|||||||
targ->frags++;
|
targ->frags++;
|
||||||
}
|
}
|
||||||
D("frags %u frag_size %u", targ->frags, targ->frag_size);
|
D("frags %u frag_size %u", targ->frags, targ->frag_size);
|
||||||
|
|
||||||
|
/* mark all slots of all rings as changed so initial copy will be done */
|
||||||
|
for (i = targ->nmd->first_tx_ring; i <= targ->nmd->last_tx_ring; i++) {
|
||||||
|
uint32_t j;
|
||||||
|
struct netmap_slot *slot;
|
||||||
|
|
||||||
|
txring = NETMAP_TXRING(nifp, i);
|
||||||
|
for (j = 0; j < txring->num_slots; j++) {
|
||||||
|
slot = &txring->slot[j];
|
||||||
|
slot->flags = NS_BUF_CHANGED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (!targ->cancel && (n == 0 || sent < n)) {
|
while (!targ->cancel && (n == 0 || sent < n)) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
@ -1714,10 +1727,6 @@ sender_body(void *data)
|
|||||||
/*
|
/*
|
||||||
* scan our queues and send on those with room
|
* scan our queues and send on those with room
|
||||||
*/
|
*/
|
||||||
if (options & OPT_COPY && sent > 100000 && !(targ->g->options & OPT_COPY) ) {
|
|
||||||
D("drop copy");
|
|
||||||
options &= ~OPT_COPY;
|
|
||||||
}
|
|
||||||
for (i = targ->nmd->first_tx_ring; i <= targ->nmd->last_tx_ring; i++) {
|
for (i = targ->nmd->first_tx_ring; i <= targ->nmd->last_tx_ring; i++) {
|
||||||
int m;
|
int m;
|
||||||
uint64_t limit = rate_limit ? tosend : targ->g->burst;
|
uint64_t limit = rate_limit ? tosend : targ->g->burst;
|
||||||
|
Loading…
Reference in New Issue
Block a user