Exemple #1
0
/*
 * Initialize a pool of keys
 * These are unique tokens that can be obtained by threads
 * calling lthread_key_create()
 */
void _lthread_key_pool_init(void)
{
	static struct rte_ring *pool;
	struct lthread_key *new_key;
	char name[MAX_LTHREAD_NAME_SIZE];

	bzero(key_table, sizeof(key_table));

	/* only one lcore should do this */
	if (rte_atomic64_cmpset(&key_pool_init, 0, 1)) {

		snprintf(name,
			MAX_LTHREAD_NAME_SIZE,
			"lthread_key_pool_%d",
			getpid());

		pool = rte_ring_create(name,
					LTHREAD_MAX_KEYS, 0, 0);
		LTHREAD_ASSERT(pool);

		int i;

		for (i = 1; i < LTHREAD_MAX_KEYS; i++) {
			new_key = &key_table[i];
			rte_ring_mp_enqueue((struct rte_ring *)pool,
						(void *)new_key);
		}
		key_pool = pool;
	}
	/* other lcores wait here till done */
	while (key_pool == NULL) {
		rte_compiler_barrier();
		sched_yield();
	};
}
Exemple #2
0
/*
 * Enqueue single packet to a port
 */
static void
send_to_port(uint8_t vportid, struct rte_mbuf *buf)
{
	struct port_queue *pq = &port_queues[vportid & PORT_MASK];

	if (rte_ring_mp_enqueue(pq->tx_q, (void *)buf) < 0) {
		rte_pktmbuf_free(buf);
	}
}
Exemple #3
0
/*
 * Delete a key
 */
int lthread_key_delete(unsigned int k)
{
	struct lthread_key *key;

	key = (struct lthread_key *) &key_table[k];

	if (k > LTHREAD_MAX_KEYS)
		return POSIX_ERRNO(EINVAL);

	key->destructor = NULL;
	rte_ring_mp_enqueue((struct rte_ring *)key_pool,
					(void *)key);
	return 0;
}
Exemple #4
0
/*
 * Function sends unmatched packets to vswitchd.
 */
void
send_packet_to_vswitchd(struct rte_mbuf *mbuf, struct dpdk_upcall *info)
{
	int rslt = 0;
	void *mbuf_ptr = NULL;
	const uint64_t dpif_send_tsc =
		(rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * DPIF_SEND_US;
	uint64_t cur_tsc = 0;
	uint64_t diff_tsc = 0;
	static uint64_t prev_tsc = 0;

	/* send one packet, delete information about segments */
	rte_pktmbuf_pkt_len(mbuf) = rte_pktmbuf_data_len(mbuf);

	/* allocate space before the packet for the upcall info */
	mbuf_ptr = rte_pktmbuf_prepend(mbuf, sizeof(*info));

	if (mbuf_ptr == NULL) {
		printf("Cannot prepend upcall info\n");
		rte_pktmbuf_free(mbuf);
		stats_vswitch_tx_drop_increment(INC_BY_1);
		stats_vport_tx_drop_increment(VSWITCHD, INC_BY_1);
		return;
	}

	rte_memcpy(mbuf_ptr, info, sizeof(*info));

	/* send the packet and the upcall info to the daemon */
	rslt = rte_ring_mp_enqueue(vswitchd_packet_ring, mbuf);
	if (rslt < 0) {
		if (rslt == -ENOBUFS) {
			rte_pktmbuf_free(mbuf);
			stats_vswitch_tx_drop_increment(INC_BY_1);
			stats_vport_tx_drop_increment(VSWITCHD, INC_BY_1);
			return;
		} else {
			stats_vport_overrun_increment(VSWITCHD, INC_BY_1);
		}
	}

	stats_vport_tx_increment(VSWITCHD, INC_BY_1);

	cur_tsc = rte_rdtsc();
	diff_tsc = cur_tsc - prev_tsc;
	prev_tsc = cur_tsc;
	/* Only signal the daemon after 100 milliseconds */
	if (unlikely(diff_tsc > dpif_send_tsc))
		send_signal_to_dpif();
}
int sched_module_action(struct rte_mbuf*pktbuf,struct sched_stat_str*lpstat)
{
	int rc;
	#if 0
	if(lpstat->iFlowIdx==-1)
		return -1;
	#endif
	if(lpstat->iDiscard==TRUE)
		return -1;
	switch(lpstat->tc_color)
	{
		case TC_GREEN://enqueue pkt into queue with higher priority
			rc=EnqueueIntoPortByQueueID(lpstat->iport_out,0,pktbuf);
			if(!rc)
				lpstat->iDiscard=TRUE;
			break;
		case TC_YELLOW://enqueue pkt into queue with less priority
			rc=EnqueueIntoPortByQueueID(lpstat->iport_out,(gPortParaConf[lpstat->iport_out].inb_tx_ring>=2)?1:0,pktbuf);
			if(!rc)
				lpstat->iDiscard=TRUE;
			break;
		case TC_RED:
			switch(lpstat->iPhaze)
			{
				case PHAZE_PRIMARY://re-enqueue into secondary sched queue
					rc=rte_ring_mp_enqueue(sched_mod_list[lpstat->isched_mod_id].rrSecLev,pktbuf);
					if(rc==-ENOBUFS)
						lpstat->iDiscard=TRUE;
					break;
				case PHAZE_SECONDARY://discard re-metred and red-colored pkts 
					lpstat->iDiscard=TRUE;
					break;
				default://may this case will never occur
					lpstat->iDiscard=TRUE;
					break;
			}
			break;
		case TC_UNDEF:
			lpstat->iDiscard=TRUE;
			break;
	}
	return 0;
}
Exemple #6
0
/*
 * Send a reply message to the vswitchd
 */
static void
send_reply_to_vswitchd(struct dpdk_message *reply)
{
	struct rte_mbuf *mbuf = NULL;
	void *pktmbuf_data = NULL;
	int rslt = 0;

	/* Preparing the buffer to send */
	mbuf = rte_pktmbuf_alloc(pktmbuf_pool);

	if (!mbuf) {
		RTE_LOG(WARNING, APP, "Error : Unable to allocate an mbuf "
		        ": %s : %d", __FUNCTION__, __LINE__);
		stats_vswitch_tx_drop_increment(INC_BY_1);
		stats_vport_rx_drop_increment(VSWITCHD, INC_BY_1);
		return;
	}

	pktmbuf_data = rte_pktmbuf_mtod(mbuf, void *);
	rte_memcpy(pktmbuf_data, reply, sizeof(*reply));
	rte_pktmbuf_data_len(mbuf) = sizeof(*reply);

	/* Sending the buffer to vswitchd */
	rslt = rte_ring_mp_enqueue(vswitchd_reply_ring, (void *)mbuf);
	if (rslt < 0) {
		if (rslt == -ENOBUFS) {
			rte_pktmbuf_free(mbuf);
			stats_vswitch_tx_drop_increment(INC_BY_1);
			stats_vport_rx_drop_increment(VSWITCHD, INC_BY_1);
		} else {
			stats_vport_overrun_increment(VSWITCHD, INC_BY_1);
			stats_vport_rx_increment(VSWITCHD, INC_BY_1);
		}
	} else {
		stats_vport_rx_increment(VSWITCHD, INC_BY_1);
	}
}
Exemple #7
0
int app_func(void *arg)
{
    struct rte_ring *ring1, *ring2;
    static struct message *msg1, *msg2;
    static struct message *msg3, *msg4;
    static struct message out_msg1, out_msg2;
    unsigned long long int t1 = 0, t2 = 0;
    int i = 0;
    out_msg1.message_id = 2;
    out_msg1.payload1 = 0;
    out_msg2.message_id = 2;
    out_msg2.payload1 = 0;

#ifndef __baremetal__
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(1, &cpuset);
pthread_t current_thread = pthread_self();
pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
#endif

    if (*(int*)arg == 0) {
        ring1 = app1; ring2 = app2; // Only this branch is used for now, for 3 threads
    } else {
        ring1 = app3; ring2 = app3;
    }

    // Simple round robin message parser/scheduler
    for (i = 0; i < N; i++)
    {
        int received1 = 0, received2 = 0;
        int received3 = 0, received4 = 0;
        // Scan the command queue, barrier
        while (!(received1 && received2 && received3 && received4))
        {
/*#ifdef DEBUG
#ifdef __baremetal__
kprintf
#else
printf
#endif
("app spin %d %d %d %d\n", received1, received2, received3, received4);
#endif*/
          if(!received1)
          {
            if(!rte_ring_mc_dequeue(ring1, (void **)&msg1))
	    {
#ifdef DEBUG
#ifdef __baremetal__
kprintf
#else
printf
#endif
("packet from io ring 1 %d %d\n", msg1->message_id, msg1->payload1);
#endif
                received1 = -1;
            }
          }
          if(!received2)
          {
            if(!rte_ring_mc_dequeue(ring2, (void **)&msg2))
            {
                received2 = -1;
#ifdef DEBUG
#ifdef __baremetal__
kprintf
#else
printf
#endif
("packet from io ring 2 %d %d\n", msg2->message_id, msg2->payload1);
#endif
            }
	  }
          if(!received3)
          {
            if(!rte_ring_mc_dequeue(ring1, (void **)&msg3))
            {
                received3 = -1;
#ifdef DEBUG
#ifdef __baremetal__
kprintf
#else
printf
#endif
("packet from io ring 12 %d %d\n", msg3->message_id, msg3->payload1);
#endif
            }
	  }
          if(!received4)
          {
            if(!rte_ring_mc_dequeue(ring2, (void **)&msg4))
            {
                received4 = -1;
#ifdef DEBUG
#ifdef __baremetal__
kprintf
#else
printf
#endif
("packet from io ring 22 %d %d\n", msg4->message_id, msg4->payload1);
#endif
            }
          }
        }
    	        if (t1 == 0) t1 = getticks();
		else
		{
#ifdef DEBUG
#ifdef __baremetal__
kprintf
#else
printf
#endif
("next iteration %d\n", (unsigned int)(getticks() - t1));
#endif
		}
        // Send stuff back, use mp function in case
        out_msg1.payload1++;
        int sent = rte_ring_mp_enqueue(out1, &out_msg1);
        out_msg2.payload1++;
        sent     = rte_ring_mp_enqueue(out2, &out_msg2);
    }
    t2 = getticks();
#ifndef __baremetal__
    printf
#else
    kprintf
#endif
    ("%d\n", ((unsigned int)(t2 - t1))/N);

#ifndef __baremetal__
    return 0;
#else
    return ((unsigned int)(t2 - t1))/N;
#endif
}
Exemple #8
0
// 2 pinned comms threads, processing 2out and 4in buffers.
int io_func(void *arg)
{
    struct rte_ring *ring1, *ring2;
    static struct message *out_msg1, *out_msg2;
    static struct message msg1, msg2;
#ifndef __baremetal__
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
pthread_t current_thread = pthread_self();
#endif
    msg1.payload1 = 0;
    msg2.payload1 = 0;

    if (*(int*)arg == 0) {
        msg1.message_id = 1;
        ring1 = out1;
#ifndef __baremetal__
CPU_SET(2, &cpuset);
pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
#endif
    } else {
        msg2.message_id = 3;
        ring1 = out2;
#ifndef __baremetal__
CPU_SET(3, &cpuset);
pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
#endif
    }

    // Simple round robin message sender/receiver
    while (1)
    {
        int received1 = 0, received2 = 0;
        unsigned long long t1 = getticks();
        // Try sending
        msg1.payload1++;
        int sent = rte_ring_mp_enqueue(app1, &msg1);

        if (-1 == sent)
        {// FIXME to handle the error
        }
        msg2.payload1++;
        sent = rte_ring_mp_enqueue(app2, &msg2);

        // receive output, barrier
        while (!received1)
        {
/*#ifdef DEBUG
#ifdef __baremetal__
kprintf
#else
printf
#endif
("io spin %d %d \n", received1, received2);
#endif*/
          if(!received1)
          {
            if(!rte_ring_mc_dequeue(ring1, (void **)&out_msg1))
            {
#ifdef DEBUG
#ifdef __baremetal__
kprintf
#else
printf
#endif
("packet from app ring 1 %d %d\n", out_msg1->message_id, out_msg1->payload1);
#endif
		if (out_msg1->payload1 == N)
			return 0;
                received1 = -1;
            }
          }
        }
    }

    return 0;
}
Exemple #9
0
/*
functional description:
packet forward(enqueue) module,we push packet into QoS queue or TX queue
input mod:
	RX_MOD_FORWARD
output mod:
	RX_MOD_DROP
	RX_MOD_IDLE
module stack pos:
	as 1st action ,before drop module,and below any policy module
*/
dbg_local enum RX_MOD_INDEX rx_module_forward(dbg_local struct  rte_mbuf*pktbuf,dbg_local enum RX_MOD_INDEX imodid)
{
	dbg_local int iPortIn;
	dbg_local int iPortOut;
	dbg_local int iFlowIdx;
	dbg_local int iDstIdx;
	dbg_local int uiSIP;
	dbg_local int uiDIP;
	dbg_local int idx;
	dbg_local int rc;
	dbg_local int iUsed;
	dbg_local int iMod;
	dbg_local struct ether_hdr *eh;
	dbg_local struct ether_arp *ea;
	dbg_local struct iphdr *iph;
	dbg_local int iPortForwardFlag[MAX_PORT_NB];
	dbg_local struct rte_mbuf*rmPortForwardMbuf[MAX_PORT_NB];
	
	dbg_local enum RX_MOD_INDEX nextmodid=imodid;
	
	if(imodid!=RX_MOD_FORWARD)
		goto local_ret;
	//phaze 1,we filter  packet with illegal l2 and l3 address,and drop it

	//printf("input port:%d\n",(int)pktbuf->pkt.in_port);
	eh=rte_pktmbuf_mtod(pktbuf,struct ether_hdr*);
	uiSIP=0xffffffff;
	switch(HTONS(eh->ether_type))
	{
		case ETH_TYPE_ARP:
			ea=(struct ether_arp *)(sizeof(struct ether_hdr)+(char*)eh);
			uiSIP=HTONL(MAKEUINT32FROMUINT8ARR(ea->arp_spa));
			uiDIP=HTONL(MAKEUINT32FROMUINT8ARR(ea->arp_tpa));
			break;
		case ETH_TYPE_IP:
			iph=(struct iphdr *)(sizeof(struct ether_hdr)+(char*)eh);
			uiSIP=HTONL(iph->ip_src);
			uiDIP=HTONL(iph->ip_dst);
			break;
		default:
			goto exception_tag;
			break;
	}
	
	iFlowIdx=find_net_entry(uiSIP,TRUE);
	//pkt source legality checking
	if(iFlowIdx==-1)
		goto exception_tag;
	if(gFlow[iFlowIdx].b_mac_learned==FALSE)
		goto exception_tag;
	if(gFlow[iFlowIdx].b_flow_enabled==FALSE)
		goto exception_tag;
	if(gFlow[iFlowIdx].portid!=pktbuf->pkt.in_port)
		goto exception_tag;
	if(!IS_MAC_EQUAL(eh->s_addr.addr_bytes,gFlow[iFlowIdx].eaHostMAC.addr_bytes))
		goto exception_tag;

	iDstIdx=find_net_entry(uiDIP,TRUE);

		/*printf("%02x,%02x,%02x,%02x,%02x,%02x,\n",eh->d_addr.addr_bytes[0]
			,eh->d_addr.addr_bytes[1]
			,eh->d_addr.addr_bytes[2]
			,eh->d_addr.addr_bytes[3]
			,eh->d_addr.addr_bytes[4]
			,eh->d_addr.addr_bytes[5]
			);*/
	if(IS_MAC_BROADCAST(eh->d_addr.addr_bytes)){//link broadcast
		
		iUsed=FALSE;
		for(idx=0;idx<gNBPort;idx++)
			if(port_brdcst_map[(int)pktbuf->pkt.in_port][idx]==TRUE){
				iPortForwardFlag[idx]=1;
				if(iUsed==FALSE){
					rmPortForwardMbuf[idx]=pktbuf;
					iUsed=TRUE;
			 	}else{
			 		rmPortForwardMbuf[idx]=rte_pktmbuf_clone(pktbuf,gmempool);
					if(!rmPortForwardMbuf[idx])
						iPortForwardFlag[idx]=0;
			 	}	
			}else iPortForwardFlag[idx]=0;
				
	}else{//link uicast
		for(idx=0;idx<gNBPort;idx++)
			iPortForwardFlag[idx]=0;
		if(iDstIdx!=-1){
		//	printf(".......idstidx!=-1.%08x\n",gFlow[iDstIdx].uiInnerIP);
			
			if(gFlow[iDstIdx].b_mac_learned==FALSE)
				goto exception_tag;
		//	printf("Heror1\n");
			if(gFlow[iDstIdx].b_flow_enabled==FALSE)
				goto exception_tag;
		//	printf("Heror2\n");
			iPortForwardFlag[(int)gFlow[iDstIdx].portid]=1;
			rmPortForwardMbuf[(int)gFlow[iDstIdx].portid]=pktbuf;
		}
		else {
		//	printf(".......idstidx==-1\n");
			if(port_def_frd_map[(int)pktbuf->pkt.in_port]!=-1){
				iPortForwardFlag[port_def_frd_map[(int)pktbuf->pkt.in_port]]=1;
				rmPortForwardMbuf[port_def_frd_map[(int)pktbuf->pkt.in_port]]=pktbuf;
			}
			else goto exception_tag;
		}
	}
	//mirror--pkt--cloning
		
	for(idx=0;idx<gNBPort;idx++)
	{
		if(!iPortForwardFlag[idx])continue;
		switch(port_policy_map[(int)pktbuf->pkt.in_port][idx])
		{
			case PORT_POLICY_MAP_DIRECT:
				//printf("...direct:%d->%d\n",(int)pktbuf->pkt.in_port,idx);
				rc=EnqueueIntoPortQueue(idx,&rmPortForwardMbuf[idx],1);
				//printf("...rc:%d\n",rc);
				if(!rc) goto exception_tag;
				break;
			case PORT_POLICY_MAP_QOS:
				
				//high nibble:dst port
				//low nibble :src port
				iMod=sched_mod_map[(int)rmPortForwardMbuf[idx]->pkt.in_port][idx];
				rmPortForwardMbuf[idx]->pkt.in_port=MAKEBYTE(idx,rmPortForwardMbuf[idx]->pkt.in_port);
				rc=rte_ring_mp_enqueue(sched_mod_list[iMod].rrFirLev,rmPortForwardMbuf[idx]);
				if(rc==-ENOBUFS){
					goto exception_tag;
				}
				break;
			case PORT_POLICY_MAP_UNDEFINE:
				goto exception_tag;
				break;
		}
	}

		
	
	local_ret:
	return nextmodid;
	exception_tag:
	nextmodid=RX_MOD_DROP;
	goto local_ret;
}