Restore basic kmalloc/network functionality which was broken with the merge.
authorPaul Pearce <pearce@eecs.berkeley.edu>
Wed, 5 Aug 2009 01:36:25 +0000 (18:36 -0700)
committerPaul Pearce <pearce@eecs.berkeley.edu>
Wed, 5 Aug 2009 01:36:25 +0000 (18:36 -0700)
Fixed a bug in env_setup_vm that was causing kmalloc to crash. A page ref
was not being increased nor page_inserted(). This is a quick hack until Kevin
finishes channels.

Rewrote parts of the nic interrupt / rx packet handler to deal with multiple
packet receptions at bad times. The use of interrupts on a different core
uncovered a bug in which data could be written after an interrupt flag was raised,
the driver now clears the interrupt bit immediately, loops until totally clear,
and does an extra 1 off check for new data incase more data came in between
our clear and our check.

run_remote_binary support is still broken from the merge.

kern/include/rl8168.h
kern/src/Makefrag
kern/src/env.c
kern/src/manager.c
kern/src/rl8168.c

index c5d9a63..2bf3c75 100644 (file)
@@ -6,7 +6,7 @@
 #include <pmap.h>
 
 #define nic_debug(...)  //cprintf(__VA_ARGS__)  
-#define nic_interrupt_debug(...) cprintf(__VA_ARGS__)  
+#define nic_interrupt_debug(...) //cprintf(__VA_ARGS__)  
 #define nic_frame_debug(...)  //cprintf(__VA_ARGS__)  
 
 #define NIC_IRQ_CPU                    5
index 17ebaaa..4b8f8b4 100644 (file)
@@ -50,6 +50,7 @@ KERN_APPFILES := \
                     $(USER_APPS_PARLIB_DIR)/draw_nanwan_standalone \
                     $(USER_APPS_PARLIB_DIR)/channel_test_client \
                     $(USER_APPS_PARLIB_DIR)/channel_test_server \
+                    $(USER_APPS_PARLIB_DIR)/matrix \
                     $(USER_APPS_ROSLIB_DIR)/measurements
 #                    $(USER_APPS_PARLIB_DIR)/draw_nanwan
 #                    $(USER_APPS_PARLIB_DIR)/open_read \
index 89a8013..f71c2ab 100644 (file)
@@ -235,6 +235,10 @@ WRITES(e->env_pgdir, e->env_cr3, e->env_procinfo, e->env_syscallring,
 
        // Inserted into every process's address space at UGDATA
        page_insert(e->env_pgdir, shared_page, (void*SNT)UGDATA, PTE_USER_RW);
+       
+       // THIS IS A HACK. ONLY HERE UNTIL KEVIN FINISHES CHANNEL IMPLIMENTATION
+       // THIS IS NEEDED TO KEEP KMALLOC FROM DYING POST ENV CREATE.
+       pgsyseventring->pp_ref++;
 
        return 0;
 }
index f76eb0e..9e92511 100644 (file)
@@ -26,6 +26,9 @@ void manager(void)
 {
        static uint8_t progress = 0;
        env_t *envs[256];
+       
+       env_run(ENV_CREATE(parlib_matrix));
+       
 
        switch (progress++) {
                case 0:
index 97653ec..84f49fb 100644 (file)
@@ -358,66 +358,82 @@ void nic_interrupt_handler(trapframe_t *tf, void* data) {
        // Read the offending interrupt(s)
        uint16_t interrupt_status = inw(io_base_addr + RL_IS_REG);
 
-       // We can have multiple interrupts fire at once. I've personally seen this.
-       // This means we need to handle this as a series of independent if's
-       if (interrupt_status & RL_INT_ROK) {
-               nic_interrupt_debug("-->RX OK\n");
-               nic_handle_rx_packet();
-       }       
-       
-       if (interrupt_status & RL_INT_RERR) {
-               nic_interrupt_debug("-->RX ERR\n");
-       }
+       // Clear interrupts immediately so we can get the flag raised again.
+       outw(io_base_addr + RL_IS_REG, interrupt_status);
+       
+       // Loop to deal with TOCTOU 
+       while (interrupt_status != 0x0000) {
+               // We can have multiple interrupts fire at once. I've personally seen this.
+               // This means we need to handle this as a series of independent if's
+               if (interrupt_status & RL_INT_ROK) {
+                       nic_interrupt_debug("-->RX OK\n");
+                       nic_handle_rx_packet();
+               }       
+       
+               if (interrupt_status & RL_INT_RERR) {
+                       nic_interrupt_debug("-->RX ERR\n");                     
+               }
        
-       if (interrupt_status & RL_INT_TOK) {
-               nic_interrupt_debug("-->TX OK\n");
-       }
+               if (interrupt_status & RL_INT_TOK) {
+                       nic_interrupt_debug("-->TX OK\n");
+               }
        
-       if (interrupt_status & RL_INT_TERR) {
-               nic_interrupt_debug("-->TX ERR\n");
-       }
+               if (interrupt_status & RL_INT_TERR) {
+                       nic_interrupt_debug("-->TX ERR\n");                     
+               }
        
-       if (interrupt_status & RL_INT_RDU) {
-               nic_interrupt_debug("-->RX Descriptor Unavailable\n");
-       }
+               if (interrupt_status & RL_INT_RDU) {
+                       nic_interrupt_debug("-->RX Descriptor Unavailable\n");                  
+               }
        
-       if (interrupt_status & RL_INT_LINKCHG) {
-               nic_interrupt_debug("-->Link Status Changed\n");
-       }
+               if (interrupt_status & RL_INT_LINKCHG) {
+                       nic_interrupt_debug("-->Link Status Changed\n");                        
+               }
        
-       if (interrupt_status & RL_INT_FOVW) {
-               nic_interrupt_debug("-->RX Fifo Overflow\n");
-       }
+               if (interrupt_status & RL_INT_FOVW) {
+                       nic_interrupt_debug("-->RX Fifo Overflow\n");                   
+               }
        
-       if (interrupt_status & RL_INT_TDU) {
-               nic_interrupt_debug("-->TX Descriptor Unavailable\n");
-       }
+               if (interrupt_status & RL_INT_TDU) {
+                       nic_interrupt_debug("-->TX Descriptor Unavailable\n");                  
+               }
        
-       if (interrupt_status & RL_INT_SWINT) {
-               nic_interrupt_debug("-->Software Generated Interrupt\n");
-       }
+               if (interrupt_status & RL_INT_SWINT) {
+                       nic_interrupt_debug("-->Software Generated Interrupt\n");
+               }
        
-       if (interrupt_status & RL_INT_TIMEOUT) {
-               nic_interrupt_debug("-->Timer Expired\n");
-       }
+               if (interrupt_status & RL_INT_TIMEOUT) {
+                       nic_interrupt_debug("-->Timer Expired\n");
+               }
        
-       if (interrupt_status & RL_INT_SERR) {
-               nic_interrupt_debug("-->PCI Bus System Error\n");
-       }
+               if (interrupt_status & RL_INT_SERR) {
+                       nic_interrupt_debug("-->PCI Bus System Error\n");                       
+               }
        
-       nic_interrupt_debug("\n");
+               nic_interrupt_debug("\n");
                
-       // Clear interrupts     
-       outw(io_base_addr + RL_IS_REG, RL_INTRRUPT_CLEAR);
+               // Clear interrupts     
+               interrupt_status = inw(io_base_addr + RL_IS_REG);
+               outw(io_base_addr + RL_IS_REG, interrupt_status);
+       }
        
+       // In the event that we got really unlucky and more data arrived after we set 
+       //  set the bit last, try one more check
+       nic_handle_rx_packet();
        return;
 }
 
 // TODO: Does a packet too large get dropped or just set the error bits in the descriptor? Find out.
+// TODO: Should we move on to look for the next descriptor? is it safe? TOCTOU
 void nic_handle_rx_packet() {
        
        uint32_t current_command = rx_des_kva[rx_des_cur].command;
        uint16_t packet_size;
+       
+       if (current_command & DES_OWN_MASK) {
+               nic_frame_debug("-->Nothing to process. Returning.");
+               return;
+       }
                
        nic_frame_debug("-->RX Des: %u\n", rx_des_cur);