added instant processing of packets && freeing resources properly
This commit is contained in:
parent
3fc8857304
commit
37ae969ae0
1 changed files with 54 additions and 45 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue