int main (/*int argc, char **argv*/) { hptl_config confhptl; confhptl.precision = 9; confhptl.clockspeed = 0; hptl_init (&confhptl); unsigned long i = 0, j = 0; uint64_t tmp = 0; char sign = '+'; struct timespec cmtime, rt, df; printf ("[Precised] Deviation Test started [resolution = %lu]...[%lu]\n", hptl_getres (), hptl_get ()); for (j = 0; j < TESTREPEAT; j++) { printf ("Test #%lu of %lu...", j + 1, TESTREPEAT); fflush (stdin); for (i = 0; i < TESTTIME; i++) { tmp = hptl_get (); } if (clock_gettime (CLOCK_REALTIME, &cmtime) == -1) { perror ("clock gettime"); return -1; } rt = hptl_timespec (tmp); df = diff (rt, cmtime, &sign); printf ( " Deviation of %c %lu s, %3lu ms, %3lu us, %3lu ns from " "clock_gettime(CLOCK_REALTIME).\n", sign, df.tv_sec, (df.tv_nsec / 1000000000L) % 1000L, (df.tv_nsec / 1000L) % 1000L, df.tv_nsec % 1000L); } return 0; }
static inline void app_lcore_io_tx (struct app_lcore_params_io *lp) { uint32_t i; for (i = 0; i < lp->tx.n_nic_queues; i++) { uint8_t port = lp->tx.nic_queues[i].port; uint8_t queue = lp->tx.nic_queues[i].queue; uint32_t n_mbufs, n_pkts; n_mbufs = 1; struct rte_mbuf *tmpbuf = rte_ctrlmbuf_alloc (app.pools[0]); if (!tmpbuf) { continue; } tmpbuf->pkt_len = sndpktlen; tmpbuf->data_len = sndpktlen; tmpbuf->port = port; if (autoIncNum) { (*((uint16_t *)(icmppkt + icmpStart + 2 + 2 + 2)))++; } memcpy (rte_ctrlmbuf_data (tmpbuf), icmppkt, icmppktlen - 8); *((hptl_t *)(rte_ctrlmbuf_data (tmpbuf) + tsoffset)) = hptl_get (); if (doChecksum) { uint16_t cksum; cksum = rte_raw_cksum (rte_ctrlmbuf_data (tmpbuf) + icmpStart, sndpktlen - icmpStart); *((uint16_t *)(rte_ctrlmbuf_data (tmpbuf) + icmpStart + 2)) = ((cksum == 0xffff) ? cksum : ~cksum); } n_pkts = rte_eth_tx_burst (port, queue, &tmpbuf, n_mbufs); if (trainSleep) { hptl_waitns (trainSleep); } if (unlikely (n_pkts < n_mbufs)) { rte_ctrlmbuf_free (tmpbuf); } else { lp->tx.mbuf_out[port].n_mbufs++; if (trainLen && lp->tx.mbuf_out[port].n_mbufs >= trainLen) { hptl_waitns (waitTime); continueRX = 0; hptl_waitns (waitTime); exit (1); } } } }
static inline void app_lcore_io_tx_sts (struct app_lcore_params_io *lp, uint32_t bsz_wr) { uint32_t i; uint32_t k; for (i = 0; i < lp->tx.n_nic_queues; i++) { uint8_t port = lp->tx.nic_queues[i].port; uint8_t queue = lp->tx.nic_queues[i].queue; uint32_t n_mbufs, n_pkts; n_mbufs = bsz_wr; for (k = 0; k < n_mbufs; k++) { lp->tx.mbuf_out[port].array[k] = rte_ctrlmbuf_alloc (app.pools[0]); if (lp->tx.mbuf_out[port].array[k] == NULL) { n_mbufs = k; break; } lp->tx.mbuf_out[port].array[k]->pkt_len = sndpktlen; lp->tx.mbuf_out[port].array[k]->data_len = sndpktlen; lp->tx.mbuf_out[port].array[k]->port = port; memcpy (rte_ctrlmbuf_data (lp->tx.mbuf_out[port].array[k]), icmppkt, icmppktlen > sndpktlen ? sndpktlen : icmppktlen); } if (queue == 0) { *((uint16_t *)(rte_ctrlmbuf_data (lp->tx.mbuf_out[port].array[0]) + idoffset)) = (TSIDTYPE)tspacketId; if (autoIncNum) { *((uint16_t *)(rte_ctrlmbuf_data (lp->tx.mbuf_out[port].array[0]) + cntroffset)) = pktcounter++; if (pktcounter > trainLen) { hptl_waitns (waitTime); continueRX = 0; hptl_waitns (waitTime); exit (1); } } *(hptl_t *)(rte_ctrlmbuf_data (lp->tx.mbuf_out[port].array[0]) + tsoffset) = hptl_get (); } if (doChecksum) { uint16_t cksum; cksum = rte_raw_cksum (rte_ctrlmbuf_data (lp->tx.mbuf_out[port].array[0]) + icmpStart, sndpktlen - icmpStart); *((uint16_t *)(rte_ctrlmbuf_data (lp->tx.mbuf_out[port].array[0]) + icmpStart + 2)) = ((cksum == 0xffff) ? cksum : ~cksum); } n_pkts = rte_eth_tx_burst (port, queue, lp->tx.mbuf_out[port].array, n_mbufs); if (n_pkts == 0) { pktcounter--; for (k = n_pkts; k < n_mbufs; k++) { struct rte_mbuf *pkt_to_free = lp->tx.mbuf_out[port].array[k]; rte_ctrlmbuf_free (pkt_to_free); } } else { while (unlikely (n_pkts < n_mbufs)) { uint64_t tmp; tmp = rte_eth_tx_burst ( port, queue, lp->tx.mbuf_out[port].array + n_pkts, n_mbufs - n_pkts); n_pkts += tmp; } } } }
static inline void app_lcore_io_rx_sts (struct app_lcore_params_io *lp, uint32_t bsz_rd, uint32_t stsw) { uint32_t i; static uint32_t counter = 0; for (i = 0; i < lp->rx.n_nic_queues; i++) { uint8_t port = lp->rx.nic_queues[i].port; uint8_t queue = lp->rx.nic_queues[i].queue; uint32_t n_mbufs, i, j; n_mbufs = rte_eth_rx_burst (port, queue, lp->rx.mbuf_in.array, (uint16_t)bsz_rd); if (unlikely (continueRX == 0)) { uint32_t k; uint64_t totalBytes = 0; hptl_t firstTime = 0, lastTime = 0; uint64_t ignored = 0; uint64_t sumLatency = 0; struct timespec hwRelation = {0, 0}; struct timespec hwDelta; for (k = 0; k < trainLen; k++) { if (latencyStats[k].recved) { uint64_t currentLatency = latencyStats[k].recvTime - latencyStats[k].sentTime; uint64_t fixedLatency = currentLatency - (stsw - 1) * (latencyStats[k].pktLen * 8 + 24) / 10.; printf ("%d: Latency %lu ns", k + 1, currentLatency); printf (" Estimated %lu ns", fixedLatency); sumLatency += currentLatency; if (hwTimeTest) { // fpga time conversion uint64_t fpgatime = ntohl (latencyStats[k].hwTime.tv_sec) * 1000000000 + ntohl (latencyStats[k].hwTime.tv_nsec); fpgatime /= fpgaConvRate; latencyStats[k].hwTime.tv_sec = fpgatime / 1000000000; latencyStats[k].hwTime.tv_nsec = fpgatime % 1000000000; printf (" hwTime %lu.%lu", latencyStats[k].hwTime.tv_sec, latencyStats[k].hwTime.tv_nsec); if (lastTime != 0) { printf (" hwDeltaLatency %lu.%lu", latencyStats[k].hwTime.tv_sec - hwDelta.tv_sec, latencyStats[k].hwTime.tv_nsec - hwDelta.tv_nsec); } hwDelta = latencyStats[k].hwTime; } if (lastTime != 0) { printf (" insta-BandWidth %lf Gbps", (latencyStats[k].totalBytes * 8 / 1000000000.) / (((double)latencyStats[k].recvTime - lastTime) / 1000000000.)); } else { if (hwTimeTest) { hwRelation = hptl_timespec (latencyStats[k].recvTime); hwRelation.tv_sec -= latencyStats[k].hwTime.tv_sec; hwRelation.tv_nsec -= latencyStats[k].hwTime.tv_nsec; } firstTime = latencyStats[k].recvTime; } lastTime = latencyStats[k].recvTime; totalBytes += latencyStats[k].totalBytes; printf ("\n"); } else { printf ("%d: Pkt has not been seen\n", k + 1); ignored++; } } printf ( "Mean-BandWidth %lf Gbps\n", (totalBytes * 8 / 1000000000.) / (((double)lastTime - firstTime) / 1000000000.)); printf ("Mean-Latency %lf ns\n", sumLatency / (((double)trainLen - ignored))); // Ignored / Dropped stats if (ignored > 0) { printf ("%ld TS-Packets lost\n", ignored); } struct rte_eth_stats stats; rte_eth_stats_get (port, &stats); if (stats.ierrors > 0) { printf ("%ld Packets errored/dropped\n", stats.ierrors); } if (stats.oerrors > 0) { printf ("%ld Packets errored in TX\n", stats.oerrors); } printf ("Port %d stats: %lu/%lu/%lu/%lu Pkts sent/recv/ierror/imissed\n", port, stats.opackets, stats.ipackets, stats.ierrors, stats.imissed); printf (" %lu/%lu Bytes sent/recv\n", stats.obytes, stats.ibytes); printf (" %lu/%lu Queue error sent/recv\n", stats.q_errors[0], stats.rx_nombuf); // DEBUG, MUST REMOVE IN RELEASE port = 1 - port; rte_eth_stats_get (port, &stats); printf ("Port %d stats: %lu/%lu/%lu Pkts sent/recv/oerrors\n", port, stats.opackets, stats.ipackets, stats.oerrors); printf (" %lu/%lu Bytes sent/recv\n", stats.obytes, stats.ibytes); printf (" %lu/%lu Queue error sent/recv\n", stats.q_errors[0], stats.rx_nombuf); exit (0); } if (unlikely (n_mbufs == 0)) { continue; } for (i = 0; i < n_mbufs; i++) { uint8_t *data = (uint8_t *)rte_ctrlmbuf_data (lp->rx.mbuf_in.array[i]); uint32_t len = rte_ctrlmbuf_len (lp->rx.mbuf_in.array[i]); bytecounter += len; if (*(uint16_t *)(data + idoffset) == (TSIDTYPE)tspacketId) { // paquete marcado if (autoIncNum) { counter = *(uint16_t *)(data + cntroffset); if (counter >= trainLen) { continueRX = 0; continue; } } // Latency ounters latencyStats[counter].recvTime = hptl_get (); latencyStats[counter].sentTime = (*(hptl_t *)(data + tsoffset)); latencyStats[counter].pktLen = len; latencyStats[counter].totalBytes = bytecounter; latencyStats[counter].recved = 1; bytecounter = 0; // reset counter if (hwTimeTest) { latencyStats[counter].hwTime.tv_sec = *(uint32_t *)(data + 50); latencyStats[counter].hwTime.tv_nsec = *(uint32_t *)(data + 54); } // end if all packets have been recved counter++; if (counter == trainLen) continueRX = 0; } } for (j = 0; j < n_mbufs; j++) { struct rte_mbuf *pkt = lp->rx.mbuf_in.array[j]; rte_pktmbuf_free (pkt); } } }
static inline void app_lcore_io_rx (struct app_lcore_params_io *lp, uint32_t bsz_rd) { uint32_t i; static uint32_t counter = 0; for (i = 0; i < lp->rx.n_nic_queues; i++) { uint8_t port = lp->rx.nic_queues[i].port; uint8_t queue = lp->rx.nic_queues[i].queue; uint32_t n_mbufs, j; n_mbufs = rte_eth_rx_burst (port, queue, lp->rx.mbuf_in.array, (uint16_t)bsz_rd); if (unlikely (continueRX == 0)) { uint32_t k; uint64_t totalBytes = 0; hptl_t firstTime = 0, lastTime = 0; uint64_t ignored = 0; uint64_t sumLatency = 0; struct timespec hwRelation = {0, 0}; struct timespec hwDelta; for (k = 0; k < trainLen; k++) { if (latencyStats[k].recved) { uint64_t currentLatency = latencyStats[k].recvTime - latencyStats[k].sentTime; printf ("%d: Latency %lu ns", k + 1, currentLatency); sumLatency += currentLatency; if (hwTimeTest) { // fpga time conversion uint64_t fpgatime = ntohl (latencyStats[k].hwTime.tv_sec) * 1000000000 + ntohl (latencyStats[k].hwTime.tv_nsec); fpgatime /= fpgaConvRate; latencyStats[k].hwTime.tv_sec = fpgatime / 1000000000; latencyStats[k].hwTime.tv_nsec = fpgatime % 1000000000; printf (" hwTime %lu.%lu", latencyStats[k].hwTime.tv_sec, latencyStats[k].hwTime.tv_nsec); if (lastTime != 0) { printf (" hwDeltaLatency %lu.%lu", latencyStats[k].hwTime.tv_sec - hwDelta.tv_sec, latencyStats[k].hwTime.tv_nsec - hwDelta.tv_nsec); } hwDelta = latencyStats[k].hwTime; } if (lastTime != 0) { printf (" insta-BandWidth %lf Gbps", (latencyStats[k].pktLen * 8 / 1000000000.) / (((double)latencyStats[k].recvTime - lastTime) / 1000000000.)); } else { if (hwTimeTest) { hwRelation = hptl_timespec (latencyStats[k].recvTime); hwRelation.tv_sec -= latencyStats[k].hwTime.tv_sec; hwRelation.tv_nsec -= latencyStats[k].hwTime.tv_nsec; } firstTime = latencyStats[k].recvTime; } lastTime = latencyStats[k].recvTime; totalBytes += latencyStats[k].pktLen; printf ("\n"); } else { printf ("%d: Recved but ignored\n", k + 1); ignored++; } } printf ( "Mean-BandWidth %lf Gbps\n", (totalBytes * 8 / 1000000000.) / (((double)lastTime - firstTime) / 1000000000.)); printf ("Mean-Latency %lf ns\n", sumLatency / (((double)trainLen - ignored))); // Ignored / Dropped stats if (ignored > 0) { printf ("%ld Packets ignored\n", ignored); } struct rte_eth_stats stats; rte_eth_stats_get (port, &stats); if (stats.ierrors > 0) { printf ("%ld Packets errored/dropped\n", stats.ierrors); } exit (0); } if (unlikely (n_mbufs == 0)) { continue; } if (trainLen && (*(uint16_t *)(rte_ctrlmbuf_data (lp->rx.mbuf_in.array[n_mbufs - 1]) + idoffset)) == (*(uint16_t *)(icmppkt + idoffset))) { // Add counter #recvPkts-1, so the data is saved in the structure as "the last packet of // the bulk, instead of the first one" counter += n_mbufs - 1; // Latency ounters latencyStats[counter].recvTime = hptl_get (); latencyStats[counter].sentTime = *(hptl_t *)(rte_ctrlmbuf_data (lp->rx.mbuf_in.array[n_mbufs - 1]) + tsoffset); latencyStats[counter].pktLen = rte_ctrlmbuf_len (lp->rx.mbuf_in.array[n_mbufs - 1]); latencyStats[counter].recved = 1; if (hwTimeTest) { latencyStats[counter].hwTime.tv_sec = *(uint32_t *)(rte_ctrlmbuf_data (lp->rx.mbuf_in.array[n_mbufs - 1]) + 50); latencyStats[counter].hwTime.tv_nsec = *(uint32_t *)(rte_ctrlmbuf_data (lp->rx.mbuf_in.array[n_mbufs - 1]) + 54); } // end if all packets have been recved counter++; if (counter == trainLen) continueRX = 0; } // Drop all packets for (j = 0; j < n_mbufs; j++) { struct rte_mbuf *pkt = lp->rx.mbuf_in.array[j]; rte_pktmbuf_free (pkt); } } }