Exemple #1
0
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);
		}
	}
}