added instant processing of packets && freeing resources properly

This commit is contained in:
Carl-Benedikt Krger 2011-07-05 12:39:27 +02:00
parent 3fc8857304
commit 37ae969ae0

View file

@ -70,7 +70,10 @@ extern HANDLE hProc;
#define MMNIF_CORES 2
#define MMNIF_WORKER_BUDGET 5
#define MMNIF_WORKER_BUDGET 2
#define MMNIF_POLL_BUDGET 0x100000
#define MMNIF_WAIT_BUDGET 0x2
/* decide whether it's polling mode or not
*/
@ -84,6 +87,10 @@ static int active = 0;
*/
static int disable_locking = 0;
/* decide whether deliver work to a worker thread or instantly process all packets
*/
static int instant_process = 1;
/* IP address of the local core and the router core to get packets forwarded
*/
static unsigned int own_ip_address = 0xC0A80000; /* 192.168.0.0 */
@ -115,8 +122,6 @@ static int pulse_irq = 0;
#define RCK_INTR_MASK 0x00000002
#define RCK_NMI_MASK 0x00000001
/*
* the memory mapped network device
*/
@ -131,8 +136,10 @@ typedef struct mmnif_device_stats
/* device stats (granularity in packets):
* - recieve errors
* - recieve successes
* - recieved bytes
* - transmit errors
* - transmit successes
* - transmitted bytes
*/
unsigned int rx_err;
unsigned int rx;
@ -145,7 +152,10 @@ typedef struct mmnif_device_stats
unsigned int tx_bytes;
/* Heuristics :
*
* - how many times an budget overflow occured
* - how many times the polling thread polled without recieving a new message
* - how many messages are recieved via interrupt
* - how many messages are recieved via the polling thread
*/
unsigned int bdg_overflow;
unsigned int pll_empty;
@ -167,8 +177,8 @@ typedef struct mm_rx_buffer
* I won't use a single buffer the whole time. I think i will use an descripor table
* and a table which descriptor is in use and use the buffer space dynamically with
* descriptors
*
* And this buffer needs a lock as soon as more as cores are availible =/
* Also timeouts should be checked so if one core dies the buffer space is not blocked
* all the time
*/
uint8_t queued;
uint8_t pos;
@ -178,6 +188,9 @@ typedef struct mm_rx_buffer
sem_t lock;
// uint32_t timestamp[MMNIF_RX_QUEUELEN];
// uint32_t bitmap[MMNIF_RX_QUEUELEN];
// void* rx_desc[MMNIF_CORES * MMNIF_RX_QUEUELEN];
// uint8_t rx_inuse[MMNIF_CORES * MMNIF_RX_QUEUELEN]; /* bits 1: pending 2: finished 3: free ...*/
// uint8_t fin;
@ -502,11 +515,6 @@ __inline int mmnif_worker_schedule()
*/
__inline void* mmnif_shmalloc()
{
/* Right now every core has the same buffer for every incoming packet
* this will be removed and a buffer for each Core will be implemented
*
* but i'm first testing with two cores/processes.
*/
#ifdef WIN32
mpb_size = sizeof(mm_rx_buffer_t) + MMNIF_RX_QUEUELEN* MMNIF_RX_BUFFERLEN;
mpb_start_address = VirtualAlloc((char*)0x41000000 /*+
@ -516,15 +524,8 @@ __inline void* mmnif_shmalloc()
return (char*)0x41000000 + (mpb_size) * (own_ip_address - router_ip_address);
#else
mpb_size = (sizeof(mm_rx_buffer_t) + MMNIF_RX_QUEUELEN* MMNIF_RX_BUFFERLEN);
/* We choose a arbitrary address first
* until i know how to properly allocate shared memory
*/
// RCCE_shmalloc_init(0x80000000,48*8192);
mpb_start_address = RCCE_shmalloc(mpb_size*MMNIF_CORES);
//mpb_start_address = 0x8000000+ mpb_size * (own_ip_address - router_ip_address);
//SHMalloc(&mpb_start_address);
//mpb_start_address = kmalloc(mpb_size*MMNIF_CORES);
// mpb_start_address = 0xC0000000;
return mpb_start_address + (mpb_size) * (own_ip_address - router_ip_address);
#endif
}
@ -773,8 +774,6 @@ err_t mmnif_tx(struct netif* netif, struct pbuf* p)
else
mmnif_write_rx_buffl(dest_ip, pos, p->payload,p->tot_len);
// udelay(50000);
/* like above ensure we are the only ones editing the hdr */
mmnif_lock_rx_hdr(dest_ip);
@ -881,6 +880,9 @@ err_t mmnif_init(struct netif* netif)
*/
sem_init(&mmnif->com_poll,1);
/* since there is no possibilty to create a full semaphore we just block it manually
*/
sem_wait(&mmnif->com_poll);
/* inform via interrupt should be the dafault
@ -1085,20 +1087,23 @@ static int mmnif_wait(struct netif* netif, uint32_t poll, int budget)
quota = budget;
mmnif->stats.bdg_overflow++;
if (mmnif->stats.bdg_overflow >= 0x10)
if (mmnif->stats.bdg_overflow >= MMNIF_WAIT_BUDGET)
{
/* enable polling and disable interrupts
*
*/
mmnif_lock_rx_hdr(own_ip_address && 0xff);
mmnif->rx_buff->iv_intr = FALSE;
mmnif_unlock_rx_hdr(own_ip_address && 0xff);
* (only if polling isn't enabled anyways)
*/
if (mmnif->rx_buff->iv_intr == TRUE)
{
mmnif_lock_rx_hdr(own_ip_address && 0xff);
mmnif->rx_buff->iv_intr = FALSE;
mmnif_unlock_rx_hdr(own_ip_address && 0xff);
#ifdef DEBUG_MMNIF
DEBUGPRINTF("mmnif_wait(): heuristical polling enables\n");
DEBUGPRINTF("mmnif_wait(): heuristical polling enables\n");
#endif
sem_post(&mmnif->com_poll);
mmnif->stats.bdg_overflow = 0;
sem_post(&mmnif->com_poll);
}
mmnif->stats.bdg_overflow = 0;
}
}
@ -1109,7 +1114,7 @@ static int mmnif_wait(struct netif* netif, uint32_t poll, int budget)
/* fetch new data from mmnif_rx() if there is any */
if (poll)
{
/* if there is no data return immeadieatly*/
/* if there is no data return immeadieatly */
if (mailbox_ptr_tryfetch(&(mmnif->mbox), (void**) &p))
return err;
}
@ -1160,7 +1165,6 @@ int mmnif_poll(void* e)
{
mmnif_t* mmnif;
unsigned int diff = mmnif_timestamp();
unsigned int tmp32 = 0;
if (!mmnif_dev)
{
@ -1184,10 +1188,7 @@ int mmnif_poll(void* e)
{
while (!mmnif->rx_buff->queued)
{
tmp32 = mmnif_timestamp();
diff = diff - tmp32 > 0 ? diff - tmp32 : tmp32 - diff;
mmnif->stats.pll_empty++;
if (mmnif->stats.pll_empty >= 0x100000)
if (mmnif->stats.pll_empty >= MMNIF_POLL_BUDGET)
{
/* enable interrupts and suspend polling
*
@ -1203,9 +1204,10 @@ int mmnif_poll(void* e)
}
}
mmnif->stats.pll_empty--;
// udelay(30000);
mmnif_rx(mmnif_dev);
// mmnif_wait(mmnif_dev,0,MMNIF_WORKER_BUDGET);
if (instant_process)
mmnif_wait(mmnif_dev,0,MMNIF_WORKER_BUDGET);
}
return NULL;
@ -1227,7 +1229,12 @@ void mmnif_irqhandler()
mmnif = (mmnif_t*) mmnif_dev->state;
while (mmnif->rx_buff->queued)
{
mmnif_rx(mmnif_dev);
if (instant_process)
mmnif_wait(mmnif_dev,0,MMNIF_WORKER_BUDGET);
}
}
/*
@ -1244,7 +1251,7 @@ int mmnif_open()
*/
IP4_ADDR(&gw, 0,0,0,0);
IP4_ADDR(&ipaddr, 192,168,0,get_my_core_no() +1);
IP4_ADDR(&netmask, 255,0,0,0);
IP4_ADDR(&netmask, 255,255,255,0);
own_ip_address+= get_my_core_no() +1;
@ -1288,13 +1295,13 @@ int mmnif_open()
/* If interrupts are not used we immediately add the polling function
* to the queue which would otherwise be done through the IRQ handler.
*/
// if (no_irq)
mmnif_device_schedule();
mmnif_device_schedule();
/* Start the device worker thread wich actually processes the incoming
* packet's this is not done in the "interrupt handler" to shorten them up
*/
mmnif_worker_schedule();
if (!instant_process)
mmnif_worker_schedule();
#ifdef DEBUG_MMNIF
DEBUGPRINTF("mmnif_dev is open\n");
@ -1330,9 +1337,11 @@ int mmnif_close()
#ifdef WIN32
free(mmnif->tx_buff);
free(mmnif_dev);
VirtualFree(mpb_start_address,NULL,NULL);
#else
// kfree(mmnif->tx_buff);
// kfree(mmnif_dev);
kfree(mmnif->tx_buff[0],MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN);
kfree(mmnif_dev,sizeof(mmnif_t));
RCCE_shfree(mpb_start_address);
#endif
return NULL;
}