/* * test control mbuf */ static int test_one_ctrlmbuf(void) { struct rte_mbuf *m = NULL; char message[] = "This is a message carried by a ctrlmbuf"; printf("Test ctrlmbuf API\n"); /* alloc a mbuf */ m = rte_ctrlmbuf_alloc(ctrlmbuf_pool); if (m == NULL) GOTO_FAIL("Cannot allocate mbuf"); if (rte_ctrlmbuf_len(m) != 0) GOTO_FAIL("Bad length"); /* set data */ rte_ctrlmbuf_data(m) = &message; rte_ctrlmbuf_len(m) = sizeof(message); /* read data */ if (rte_ctrlmbuf_data(m) != message) GOTO_FAIL("Invalid data pointer"); if (rte_ctrlmbuf_len(m) != sizeof(message)) GOTO_FAIL("Invalid len"); rte_mbuf_sanity_check(m, RTE_MBUF_CTRL, 0); /* free mbuf */ rte_ctrlmbuf_free(m); m = NULL; return 0; fail: if (m) rte_ctrlmbuf_free(m); return -1; }
/* * Send a reply message to the vswitchd */ static void send_reply_to_vswitchd(struct dpdk_message *reply) { int rslt = 0; struct rte_mbuf *mbuf = NULL; void *ctrlmbuf_data = NULL; struct client *vswd = NULL; struct statistics *vswd_stat = NULL; vswd = &clients[VSWITCHD]; vswd_stat = &vport_stats[VSWITCHD]; /* Preparing the buffer to send */ mbuf = rte_ctrlmbuf_alloc(pktmbuf_pool); if (!mbuf) { RTE_LOG(WARNING, APP, "Error : Unable to allocate an mbuf : %s : %d", __FUNCTION__, __LINE__); switch_tx_drop++; vswd_stat->rx_drop++; return; } ctrlmbuf_data = rte_ctrlmbuf_data(mbuf); rte_memcpy(ctrlmbuf_data, reply, sizeof(*reply)); rte_ctrlmbuf_len(mbuf) = sizeof(*reply); /* Sending the buffer to vswitchd */ rslt = rte_ring_sp_enqueue(vswd->rx_q, mbuf); if (rslt < 0) { if (rslt == -ENOBUFS) { rte_ctrlmbuf_free(mbuf); switch_tx_drop++; vswd_stat->rx_drop++; } else { overruns++; } } vswd_stat->tx++; }
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); } } }