void counter_register_pkt(void *arg, struct rte_mbuf **buffer, int nb_rx) { if (nb_rx == 0) return; struct counter_t *counter = (struct counter_t *) arg; uint64_t start_a = rte_get_tsc_cycles(), diff_a; if (nb_rx > rte_ring_free_count(counter->ring)) { RTE_LOG(ERR, COUNTER, "Not enough free entries in ring!\n"); } // enqueue packet in ring // this methode must be thread safe struct rte_mbuf *bulk[nb_rx]; unsigned nb_registered = 0; for (unsigned i = 0; i < nb_rx; ++i) { struct ether_hdr *eth = rte_pktmbuf_mtod(buffer[i], struct ether_hdr *); if (!is_same_ether_addr(&counter->rx_register->mac, ð->d_addr)) { continue; } bulk[nb_registered] = rte_pktmbuf_clone(buffer[i], counter->clone_pool); if (bulk[nb_registered] == NULL) { RTE_LOG(ERR, COUNTER, "Could not clone mbuf!\n"); continue; } nb_registered += 1; } int n = rte_ring_enqueue_burst(counter->ring,(void * const*) &bulk, nb_registered); if (n < nb_rx) { RTE_LOG(ERR, COUNTER, "Could not enqueue every new packtes for registration! " "(%"PRIu32"/%"PRIu32") free: %"PRIu32"\n", n, nb_rx, rte_ring_free_count(counter->ring)); } diff_a = rte_get_tsc_cycles() - start_a; counter->aTime += diff_a;//* 1000.0 / rte_get_tsc_hz(); counter->nb_measurements_a += nb_rx; }
/* dump the status of the ring on the console */ void rte_ring_dump(FILE *f, const struct rte_ring *r) { #ifdef RTE_LIBRTE_RING_DEBUG struct rte_ring_debug_stats sum; unsigned lcore_id; #endif fprintf(f, "ring <%s>@%p\n", r->name, r); fprintf(f, " flags=%x\n", r->flags); fprintf(f, " size=%"PRIu32"\n", r->prod.size); fprintf(f, " ct=%"PRIu32"\n", r->cons.tail); fprintf(f, " ch=%"PRIu32"\n", r->cons.head); fprintf(f, " pt=%"PRIu32"\n", r->prod.tail); fprintf(f, " ph=%"PRIu32"\n", r->prod.head); fprintf(f, " used=%u\n", rte_ring_count(r)); fprintf(f, " avail=%u\n", rte_ring_free_count(r)); if (r->prod.watermark == r->prod.size) fprintf(f, " watermark=0\n"); else fprintf(f, " watermark=%"PRIu32"\n", r->prod.watermark); /* sum and dump statistics */ #ifdef RTE_LIBRTE_RING_DEBUG memset(&sum, 0, sizeof(sum)); for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { sum.enq_success_bulk += r->stats[lcore_id].enq_success_bulk; sum.enq_success_objs += r->stats[lcore_id].enq_success_objs; sum.enq_quota_bulk += r->stats[lcore_id].enq_quota_bulk; sum.enq_quota_objs += r->stats[lcore_id].enq_quota_objs; sum.enq_fail_bulk += r->stats[lcore_id].enq_fail_bulk; sum.enq_fail_objs += r->stats[lcore_id].enq_fail_objs; sum.deq_success_bulk += r->stats[lcore_id].deq_success_bulk; sum.deq_success_objs += r->stats[lcore_id].deq_success_objs; sum.deq_fail_bulk += r->stats[lcore_id].deq_fail_bulk; sum.deq_fail_objs += r->stats[lcore_id].deq_fail_objs; } fprintf(f, " size=%"PRIu32"\n", r->prod.size); fprintf(f, " enq_success_bulk=%"PRIu64"\n", sum.enq_success_bulk); fprintf(f, " enq_success_objs=%"PRIu64"\n", sum.enq_success_objs); fprintf(f, " enq_quota_bulk=%"PRIu64"\n", sum.enq_quota_bulk); fprintf(f, " enq_quota_objs=%"PRIu64"\n", sum.enq_quota_objs); fprintf(f, " enq_fail_bulk=%"PRIu64"\n", sum.enq_fail_bulk); fprintf(f, " enq_fail_objs=%"PRIu64"\n", sum.enq_fail_objs); fprintf(f, " deq_success_bulk=%"PRIu64"\n", sum.deq_success_bulk); fprintf(f, " deq_success_objs=%"PRIu64"\n", sum.deq_success_objs); fprintf(f, " deq_fail_bulk=%"PRIu64"\n", sum.deq_fail_bulk); fprintf(f, " deq_fail_objs=%"PRIu64"\n", sum.deq_fail_objs); #else fprintf(f, " no statistics available\n"); #endif }
int main(int argc, char *argv[]) { setlocale(LC_NUMERIC, "en_US.utf-8"); int retval = 0; if ((retval = rte_eal_init(argc, argv)) < 0) return -1; argc -= retval; argv += retval; if(argc < 1) { RTE_LOG(INFO, APP, "usage: -- port\n"); return 0; } char rx_ring_name[RTE_RING_NAMESIZE]; char tx_ring_name[RTE_RING_NAMESIZE]; /* be aware that ring name is in ovs point of view */ sprintf(rx_ring_name, "%s_tx", argv[1]); sprintf(tx_ring_name, "%s_rx", argv[1]); init(tx_ring_name, rx_ring_name); printf("Free count in tx: %d\n", rte_ring_free_count(tx_ring)); signal(SIGALRM, ALARMhandler); alarm(PRINT_INTERVAL); RTE_LOG(INFO, APP, "Finished Process Init.\n"); #ifdef USE_BURST RTE_LOG(INFO, APP, "Burst Enabled.\n"); #else RTE_LOG(INFO, APP, "Burst Disabled.\n"); #endif #if ALLOC_METHOD == ALLOC_OVS RTE_LOG(INFO, APP, "Alloc method is OVS.\n"); #elif ALLOC_METHOD == ALLOC_APP RTE_LOG(INFO, APP, "Alloc method is APP.\n"); #endif send_loop(); RTE_LOG(INFO, APP, "Done\n"); return 0; }
/* This function will perform re-ordering of packets, and injecting into * the appropriate QID IQ. As LB and DIR QIDs are in the same array, but *NOT* * contiguous in that array, this function accepts a "range" of QIDs to scan. */ static uint16_t sw_schedule_reorder(struct sw_evdev *sw, int qid_start, int qid_end) { /* Perform egress reordering */ struct rte_event *qe; uint32_t pkts_iter = 0; for (; qid_start < qid_end; qid_start++) { struct sw_qid *qid = &sw->qids[qid_start]; int i, num_entries_in_use; if (qid->type != RTE_SCHED_TYPE_ORDERED) continue; num_entries_in_use = rte_ring_free_count( qid->reorder_buffer_freelist); for (i = 0; i < num_entries_in_use; i++) { struct reorder_buffer_entry *entry; int j; entry = &qid->reorder_buffer[qid->reorder_buffer_index]; if (!entry->ready) break; for (j = 0; j < entry->num_fragments; j++) { uint16_t dest_qid; uint16_t dest_iq; int idx = entry->fragment_index + j; qe = &entry->fragments[idx]; dest_qid = qe->queue_id; dest_iq = PRIO_TO_IQ(qe->priority); if (dest_qid >= sw->qid_count) { sw->stats.rx_dropped++; continue; } struct sw_qid *dest_qid_ptr = &sw->qids[dest_qid]; const struct iq_ring *dest_iq_ptr = dest_qid_ptr->iq[dest_iq]; if (iq_ring_free_count(dest_iq_ptr) == 0) break; pkts_iter++; struct sw_qid *q = &sw->qids[dest_qid]; struct iq_ring *r = q->iq[dest_iq]; /* we checked for space above, so enqueue must * succeed */ iq_ring_enqueue(r, qe); q->iq_pkt_mask |= (1 << (dest_iq)); q->iq_pkt_count[dest_iq]++; q->stats.rx_pkts++; } entry->ready = (j != entry->num_fragments); entry->num_fragments -= j; entry->fragment_index += j; if (!entry->ready) { entry->fragment_index = 0; rte_ring_sp_enqueue( qid->reorder_buffer_freelist, entry); qid->reorder_buffer_index++; qid->reorder_buffer_index %= qid->window_size; } } } return pkts_iter; }
int QUEUE::Run() { char szBuffer[DEF_MEM_BUF_128]; map<string, RESOURCE_ATTR *>::iterator it; RESOURCE_ATTR *pstRsc = NULL; QUEUE_VALUE *pstData = NULL; float fUsage = 0; struct rte_ring *arrRing[RTE_MAX_MEMZONE]; memset(arrRing, 0x00, sizeof(arrRing)); m_pclsCLQ->GetRingList(arrRing); for(int i = 1; i < RTE_MAX_MEMZONE ; i++) { if(arrRing[i] == NULL) break; if( strncmp(arrRing[i]->name, "MP", 2) == 0 ) { fUsage = rte_ring_free_count(arrRing[i]) / (float)arrRing[i]->prod.size * 100; m_pclsLog->DEBUG("Memory Pool : %25s / Usage %3.2f", arrRing[i]->name, fUsage); } else { fUsage = rte_ring_count(arrRing[i]) / (float)arrRing[i]->prod.size * 100; m_pclsLog->DEBUG("Queue : %25s / Usage %3.2f", arrRing[i]->name, fUsage); } snprintf(szBuffer, sizeof(szBuffer), "%.2f", fUsage); it = m_pmapRsc->find( arrRing[i]->name ); if(it != m_pmapRsc->end()) { pstRsc = it->second; pstData = (QUEUE_VALUE*)pstRsc->pData; pstData->vecStringValue[IDX_QUEUE_USAGE].assign(szBuffer); } else { pstRsc = new RESOURCE_ATTR; memset(pstRsc, 0x00, sizeof(RESOURCE_ATTR)); pstRsc->pData = (void*)new QUEUE_VALUE; pstData = (QUEUE_VALUE*)pstRsc->pData; snprintf(pstRsc->szName, sizeof(pstRsc->szName), "%s", arrRing[i]->name); pstData->vecStringValue.assign(MAX_QUEUE_IDX, ""); pstData->vecStringValue[IDX_QUEUE_USAGE].assign(szBuffer); m_pmapRsc->insert( std::pair<string, RESOURCE_ATTR*>(arrRing[i]->name, pstRsc) ); } m_pclsEvent->SendTrap( DEF_ALM_CODE_QUEUE_OVER, pstRsc->szName, Rounding(fUsage,2), NULL, NULL ); } return 0; }
/** * Set up the DPDK rings which will be used to pass packets, via * pointers, between the multi-process server and client processes. * Each client needs one RX queue. */ static int init_shm_rings(void) { unsigned i; unsigned socket_id; const char * q_name; #ifdef INTERRUPT_FIFO const char * fifo_name; #endif #ifdef INTERRUPT_SEM const char * sem_name; sem_t *mutex; #endif #if defined(INTERRUPT_FIFO) || defined(INTERRUPT_SEM) #ifdef DPDK_FLAG const char *irq_flag_name; const unsigned flagsize = 4; #else key_t key; int shmid; char *shm; #endif #endif const unsigned ringsize = CLIENT_QUEUE_RINGSIZE; clients = rte_malloc("client details", sizeof(*clients) * num_clients, 0); if (clients == NULL) rte_exit(EXIT_FAILURE, "Cannot allocate memory for client program details\n"); for (i = 0; i < num_clients; i++) { /* Create an RX queue for each client */ socket_id = rte_socket_id(); q_name = get_rx_queue_name(i); clients[i].rx_q = rte_ring_create(q_name, ringsize, socket_id, RING_F_SP_ENQ | RING_F_SC_DEQ ); /* single prod, single cons */ //verify two functions uint16_t ring_cur_entries = rte_ring_count(clients[i].rx_q); uint16_t ring_free_entries = rte_ring_free_count(clients[i].rx_q); fprintf(stderr, "ring_cur_entries=%d, ring_free_entries=%d\n", ring_cur_entries, ring_free_entries); if (clients[i].rx_q == NULL) rte_exit(EXIT_FAILURE, "Cannot create rx ring queue for client %u\n", i); //add by wei, create FIFO pipe #ifdef INTERRUPT_FIFO umask(0); fifo_name = get_fifo_name(i); clients[i].fifo_name = fifo_name; mknod(fifo_name, S_IFIFO|0666, 0); clients[i].fifo_fp = fopen(fifo_name, "w"); if(clients[i].fifo_fp == NULL) { fprintf(stderr, "can not create FIFO for client %d\n", i); exit(1); } #endif #ifdef INTERRUPT_SEM sem_name = get_sem_name(i); clients[i].sem_name = sem_name; fprintf(stderr, "sem_name=%s for client %d\n", sem_name, i); mutex = sem_open(sem_name, O_CREAT, 06666, 0); if(mutex == SEM_FAILED) { fprintf(stderr, "can not create semaphore for client %d\n", i); sem_unlink(sem_name); exit(1); } clients[i].mutex = mutex; #endif #if defined(INTERRUPT_FIFO) || defined(INTERRUPT_SEM) #ifdef DPDK_FLAG irq_flag_name = get_irq_flag_name(i); clients[i].irq_flag = (int *)rte_ring_create(irq_flag_name, flagsize, socket_id, RING_F_SP_ENQ | RING_F_SC_DEQ ); /* single prod, single cons */ #else key = get_rx_shmkey(i); if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) { fprintf(stderr, "can not create the shared memory segment for client %d\n", i); exit(1); } if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { fprintf(stderr, "can not attach the shared segment to the server space for client %d\n", i); exit(1); } clients[i].shm_server = (int *)shm; #endif #endif } return 0; }
void stats_ring_update(void) { for (uint16_t r_id = 0; r_id < rsm->n_rings; ++r_id) { rsm->ring_stats[r_id].free = rte_ring_free_count(rsm->ring_stats[r_id].ring); } }