Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


VNET code clean and rearrangement
Lei Xia [Wed, 17 Nov 2010 18:58:10 +0000 (12:58 -0600)]
Kconfig
palacios/include/palacios/vmm_vnet.h
palacios/src/devices/lnx_virtio_nic.c
palacios/src/devices/lnx_virtio_vnet.c
palacios/src/devices/lnx_vnet_brg.c [deleted file]
palacios/src/devices/vnet_nic.c
palacios/src/palacios/vmm_vnet_core.c

diff --git a/Kconfig b/Kconfig
index bb241ee..4f899fe 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -161,13 +161,6 @@ config DEBUG_VNET
         help
           Enable the Vnet debug in Palacios
 
-config VNET_PROFILE
-       depends on EXPERIMENTAL && VNET
-       bool "Enable Vnet Profiling in Palacios"
-       default n
-       help
-          Enable the Vnet performance profiling in Palacios
-
 config LINUX_VIRTIO_VNET
         bool "Enable Virtio VNET interface"
         default n
@@ -182,20 +175,6 @@ config DEBUG_LINUX_VIRTIO_VNET
         help
           Enable debugging for the VNET Virtio Device
 
-config LINUX_VNET_BRIDGE
-        bool "Enable VNET Bridge for Linux host"
-        default n
-        depends on PCI && EXPERIMENTAL && VNET && LINUX
-        help
-          Enable the VNET Bridge for Linux host
-
-config DEBUG_LINUX_VNET_BRIDGE
-        bool "VNET Host Linux Bridge Debug"
-        default n
-        depends on LINUX_VNET_BRIDGE && DEBUG_ON && LINUX
-        help
-          Enable debugging for the VNET Host Linux Bridge
-
 endmenu
 
 
index d990880..b8a2d00 100644 (file)
 
 #include <palacios/vmm.h>
 
-
-#define V3_VNET_POLLING_VECTOR 50
-
 typedef enum {MAC_ANY=0, MAC_NOT, MAC_NONE, MAC_ADDR} mac_type_t; //for 'src_mac_qual' and 'dst_mac_qual'
 typedef enum {LINK_INTERFACE=0, LINK_EDGE, LINK_ANY} link_type_t; //for 'type' and 'src_type' in struct routing
 
-
 #define VNET_HASH_SIZE 17
 #define ETHERNET_HEADER_LEN 14
 #define ETHERNET_MTU   1500
 #define ETHERNET_PACKET_LEN (ETHERNET_HEADER_LEN + ETHERNET_MTU)
 
+#define VMM_DRIVERN 1
+#define GUEST_DRIVERN 0
+
+#define HOST_LNX_BRIDGE 1
+#define CTL_VM_BRIDGE 2
+
 //routing table entry
 struct v3_vnet_route {
     uint8_t src_mac[6];
@@ -76,41 +78,11 @@ struct v3_vnet_pkt {
 } __attribute__((packed));
 
 
-#ifdef CONFIG_VNET_PROFILE
-struct v3_vnet_profile{
-    uint64_t  time_copy_from_guest;
-    uint64_t  time_route_lookup;
-    uint64_t  time_mallocfree;
-    uint64_t  time_copy_to_guest;
-    uint64_t  total_handle_time;
-    uint64_t  memcpy_time;
-
-    uint64_t  total_exit_time;
-    bool print;
-
-    uint64_t virtio_handle_start;
-};
-#endif
-
-
-struct v3_vnet_bridge_xcall_args{
-    struct v3_vm_info * vm;
-    struct v3_vnet_pkt *vnet_pkts; 
-    uint16_t pkt_num;
-    void * private_data;
-};
-
-struct v3_vnet_dev_xcall_args{
-    struct v3_vm_info * vm;
-    void * private_data;
-};
-
 struct v3_vnet_dev_ops {
     int (*input)(struct v3_vm_info * vm, 
                struct v3_vnet_pkt * pkt, 
                void * dev_data);
     void (*poll) (struct v3_vm_info * vm, void * dev_data);
-    void (*poll_xcall)(void *arg);
 
     void (*start_tx)(void * dev_data);
     void (*stop_tx)(void * dev_data);
@@ -120,32 +92,23 @@ struct v3_vnet_bridge_ops {
     int (*input)(struct v3_vm_info * vm, 
                struct v3_vnet_pkt * pkt,
                void * private_data);
-    int (*xcall_input)(void * data);
-    void (*polling_pkt)(struct v3_vm_info * vm,  
+    void (*poll)(struct v3_vm_info * vm,  
                void * private_data);
 };
-       
 
+int v3_init_vnet();    
 int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void *private_data);
+void v3_vnet_poll(struct v3_vm_info *vm);
 
 int v3_vnet_add_route(struct v3_vnet_route route);
-
-int v3_init_vnet();
-
 int v3_vnet_add_bridge(struct v3_vm_info * vm,
                struct v3_vnet_bridge_ops *ops,
+               uint8_t type,
                void * priv_data);
-
 int v3_vnet_add_dev(struct v3_vm_info *info, uint8_t mac[6], 
                    struct v3_vnet_dev_ops *ops,
                    void * priv_data);
 
-void v3_vnet_poll(struct v3_vm_info *vm);
-
-int v3_vnet_enable_device(int dev_id);
-
-int v3_vnet_disable_device(int dev_id);
-
 #endif
 
 #endif
index ca492fb..3ef9509 100644 (file)
@@ -95,10 +95,8 @@ struct virtio_net_state {
 
     int buffed_rx;
     int tx_disabled;                   /* stop TX pkts from guest */
-    uint16_t cur_notify_tx_idx;        /*for used in update_tx_queue */
 
     uint64_t pkt_sent, pkt_recv, pkt_drop;
-    uint64_t tx_stop_times, rx_stop_times, tx_poll_times, rx_ipi_num;
 
     struct v3_dev_net_ops * net_ops;
     v3_lock_t rx_lock, tx_lock;
@@ -162,7 +160,7 @@ static int virtio_init_state(struct virtio_net_state * virtio)
     return 0;
 }
 
-static int pkt_tx(struct guest_info *core, struct virtio_net_state * virtio, struct vring_desc * buf_desc) 
+static int pkt_tx(struct guest_info * core, struct virtio_net_state * virtio, struct vring_desc * buf_desc) 
 {
     uint8_t * buf = NULL;
     uint32_t len = buf_desc->length;
@@ -176,7 +174,7 @@ static int pkt_tx(struct guest_info *core, struct virtio_net_state * virtio, str
 }
 
 
-static int copy_data_to_desc(struct guest_info *core, 
+static int copy_data_to_desc(struct guest_info * core, 
                                        struct virtio_net_state * virtio_state, 
                                        struct vring_desc * desc, 
                                        uchar_t * buf, 
@@ -217,6 +215,7 @@ static inline void disable_cb(struct virtio_queue *queue) {
     queue->used->flags |= VRING_NO_NOTIFY_FLAG;
 }
 
+
 /* interrupt the guest, so the guest core get EXIT to Palacios
  * this happens when there are either incoming pkts for the guest
  * or the guest can start TX pkts again */
@@ -240,20 +239,6 @@ static int handle_rx_kick(struct guest_info *core, struct virtio_net_state * vir
     return 0;
 }
 
-#ifdef CONFIG_VNET_PROFILE
-static void print_profile_info(struct virtio_net_state *virtio){
-    PrintError("Virtio NIC: %p,  sent: %lld, rxed: %lld, dropped: %lld, \
-                       tx_stop: %lld, rx_stop: %lld, poll_time: %lld, rx_ipi: %lld\n",
-                       virtio,
-                       virtio->pkt_sent,
-                       virtio->pkt_recv,
-                       virtio->pkt_drop, 
-                       virtio->tx_stop_times,
-                       virtio->rx_stop_times,
-                       virtio->tx_poll_times,
-                       virtio->rx_ipi_num);
-}
-#endif
 
 static int handle_ctrl(struct guest_info *core, struct virtio_net_state * virtio) {
        
@@ -327,24 +312,6 @@ static int handle_pkt_tx(struct guest_info *core, struct virtio_net_state * virt
        virtio_state->virtio_cfg.pci_isr = 0x1;
     }
 
-
-#ifdef CONFIG_VNET_PROFILE
-       static long min = 1024, max = 0, total=0;
-       static int i=0;
-       total += recved;
-       i ++;
-       if(recved > max) max = recved;
-       if(recved < min) min = recved;
-       if(total > 100000) {
-               PrintError("VNIC: TX polling: %ld, min %ld, max %ld, avg: %ld pkts\n", total, min, max, total/i);
-               min = 1024;
-               max = 0;
-               i = 1; 
-               total = 0;
-       }
-#endif
-
-
     return 0;
 
 exit_error:
@@ -642,7 +609,6 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) {
            (q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
            if(virtio->virtio_dev->vm->cores[0].cpu_id != V3_Get_CPU()){
                  notify_guest(virtio);
-                 virtio->rx_ipi_num ++;
            }
            virtio->buffed_rx = 0;
        }
@@ -651,8 +617,6 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) {
        /* RX queue is full,  tell backend to stop RX on this device */
        virtio->net_ops->stop_rx(virtio->backend_data);
        enable_cb(&virtio->rx_vq);
-
-       virtio->rx_stop_times ++;
        
        ret_val = -ERR_VIRTIO_RXQ_FULL;
        goto exit;
@@ -683,48 +647,39 @@ static struct v3_device_ops dev_ops = {
 
 
 /* TODO: Issue here: which vm info it needs? calling VM or the device's own VM? */
-static void virtio_nic_poll(struct v3_vm_info *vm, void *data){
-    struct virtio_net_state *virtio = (struct virtio_net_state *)data;
+static void virtio_nic_poll(struct v3_vm_info * vm, void * data){
+    struct virtio_net_state * virtio = (struct virtio_net_state *)data;
        
     handle_pkt_tx(&(vm->cores[0]), virtio);
-
-    virtio->tx_poll_times ++;
-
-#ifdef CONFIG_VNET_PROFILE
-    static uint64_t last_time = 0;
-    uint64_t time;
-    rdtscll(time);
-    if((time - last_time) > 5000000000){
-       last_time = time;
-       print_profile_info(virtio);
-    }
-#endif
 }
 
-static void virtio_start_tx(void *data){
+static void virtio_start_tx(void * data){
     struct virtio_net_state * virtio = (struct virtio_net_state *)data;
+    unsigned long flags;
 
-    /* do we need a lock here? */
+    flags = v3_lock_irqsave(virtio->tx_lock);
     virtio->tx_disabled = 0;
 
-    /* notify the device's guest it can start sending pkt */
+    /* notify the device's guest to start sending pkt */
     if(virtio->virtio_dev->vm->cores[0].cpu_id != V3_Get_CPU()){
        notify_guest(virtio);
     }
+    v3_unlock_irqrestore(virtio->tx_lock, flags);      
 }
 
-static void virtio_stop_tx(void *data){
+static void virtio_stop_tx(void * data){
     struct virtio_net_state * virtio = (struct virtio_net_state *)data;
+    unsigned long flags;
 
-    /* do we need a lock here? */
+    flags = v3_lock_irqsave(virtio->tx_lock);
     virtio->tx_disabled = 1;
 
-    /* how do we stop the guest to exit to palacios for sending pkt? */
+    /* stop the guest to exit to palacios for sending pkt? */
     if(virtio->virtio_dev->vm->cores[0].cpu_id != V3_Get_CPU()){
        disable_cb(&virtio->tx_vq);
     }
 
-    virtio->tx_stop_times ++;
+    v3_unlock_irqrestore(virtio->tx_lock, flags);
 }
 
        
@@ -797,11 +752,6 @@ static int register_dev(struct virtio_dev_state * virtio, struct virtio_net_stat
     
     virtio_init_state(net_state);
 
-#if 0 //temporary hacking LX
-    vnic_states[num_vnic ++] = net_state;
-    PrintError("VNIC: num of vnic %d\n", num_vnic);
-#endif
-
     return 0;
 }
 
index 74164c9..f164855 100644 (file)
@@ -222,7 +222,9 @@ static int handle_cmd_kick(struct guest_info * core, struct virtio_vnet_state *
 }
 
 
-static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt *pkt, void * private_data){
+static int vnet_pkt_input_cb(struct v3_vm_info * vm,  
+                                                       struct v3_vnet_pkt * pkt, 
+                                                       void * private_data){
     struct virtio_vnet_state * vnet_state = (struct virtio_vnet_state *)private_data;
     struct virtio_queue * q = &(vnet_state->queue[RECV_QUEUE]);
     int ret_val = -1;
@@ -279,17 +281,6 @@ exit:
     return ret_val;
 }
 
-static int vnet_pkt_input_xcall(void *data){
-    struct v3_vnet_bridge_xcall_args *args = (struct v3_vnet_bridge_xcall_args *)data;
-    int i = 0;
-
-    for(i = 0; i < args->pkt_num; i++) {
-       vnet_pkt_input_cb(args->vm, &(args->vnet_pkts[i]), args->private_data);
-    }
-       
-    return 0;
-}
-
 static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state) 
 {
     struct virtio_queue * q = &(vnet_state->queue[XMIT_QUEUE]);
@@ -658,11 +649,10 @@ static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     struct v3_vnet_bridge_ops brg_ops;
     brg_ops.input = vnet_pkt_input_cb;
-    brg_ops.polling_pkt = vnet_virtio_poll;
-    brg_ops.xcall_input = vnet_pkt_input_xcall;
+    brg_ops.poll = vnet_virtio_poll;
 
     V3_Print("Registering Virtio device as vnet bridge\n");
-    v3_vnet_add_bridge(vm, &brg_ops, (void *)vnet_state);
+    v3_vnet_add_bridge(vm, &brg_ops, CTL_VM_BRIDGE, (void *)vnet_state);
 
     return 0;
 }
diff --git a/palacios/src/devices/lnx_vnet_brg.c b/palacios/src/devices/lnx_vnet_brg.c
deleted file mode 100644 (file)
index c4f7272..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/* 
- * This file is part of the Palacios Virtual Machine Monitor developed
- * by the V3VEE Project with funding from the United States National 
- * Science Foundation and the Department of Energy.  
- *
- * The V3VEE Project is a joint project between Northwestern University
- * and the University of New Mexico.  You can find out more at 
- * http://www.v3vee.org
- *
- * Copyright (c) 2010, Lei Xia <lxia@cs.northwestern.edu>
- * Copyright (c) 2010, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Lei Xia <lxia@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
- /* VNET backend bridge for Linux host
- */
-#include <palacios/vmm.h>
-#include <palacios/vmm_dev_mgr.h>
-#include <palacios/vm_guest_mem.h>
-#include <palacios/vmm_vnet.h>
-#include <palacios/vmm_sprintf.h>
-#include <palacios/vmm_socket.h>
-
-#ifndef CONFIG_DEBUG_VNET_LNX_BRIGE
-#undef PrintDebug
-#define PrintDebug(fmt, args...)
-#endif
-
-typedef enum {SOCK_UDP, SOCK_TCP, SOCK_OTHER} sock_type_t; 
-
-const uint16_t vnet_udp_port = 20003;
-
-struct vnet_link {
-    uint32_t dst_ip;
-    uint16_t dst_port;
-    
-    int socket;
-    sock_type_t type;
-
-    int link_idx;
-
-    struct list_head node;
-};
-
-struct vnet_brg_state {
-    uint32_t num_links; 
-    struct list_head link_list;
-
-    int serv_sock;
-    sock_type_t serv_sock_type;
-    int serv_port;
-
-    v3_lock_t lock;
-
-    unsigned long pkt_sent, pkt_recv, pkt_drop;
-};
-
-
-static int vnet_lnxbrg_reset(struct vnet_brg_state * state) {
-    memset(state, 0, sizeof(struct vnet_brg_state));
-
-    state->num_links = 0;
-    state->serv_sock = -1;
-    state->serv_port = vnet_udp_port;
-    state->serv_sock_type = SOCK_UDP;
-
-    if(v3_lock_init(&(state->lock)) < 0){
-       PrintError("VNET Linux Bridge: error to initiate vnet lock\n");
-    }
-
-    return 0;
-}
-
-
-struct vnet_link * link_by_ip(struct vnet_brg_state * state, uint32_t ip) {
-    struct vnet_link * link = NULL;
-
-    list_for_each_entry(link, &(state->link_list), node) {
-       if (link->dst_ip == ip) {
-           return link;
-       }
-    }
-
-    return NULL;
-}
-
-struct vnet_link * link_by_idx(struct vnet_brg_state * state, int idx) {
-    struct vnet_link * link = NULL;
-
-    list_for_each_entry(link, &(state->link_list), node) {
-       if (link->link_idx == idx) {
-           return link;
-       }
-    }
-    return NULL;
-}
-
-static int
-udp_send(int sockid, uint32_t dst_ip, 
-                       uint16_t dst_port, uchar_t * pkt, 
-                       uint16_t len){
-    if(dst_ip > 0 && dst_port > 0){
-       return V3_SendTo_IP(sockid, dst_ip, dst_port, pkt, len);
-    }
-
-    return V3_Send(sockid, pkt, len);
-}
-
-
-static int 
-udp_recv(int sockid, uint32_t * src_ip, 
-                       uint16_t * src_port, uchar_t *buf, 
-                       uint16_t len) {
-
-    return V3_Recv(sockid, buf, len);
-}
-
-
-
-static int 
-brg_send(      struct v3_vm_info * vm,  
-                       struct v3_vnet_pkt * vnet_pkt, 
-                       void * private_data){
-    struct vnet_brg_state * state = (struct vnet_brg_state *)private_data;
-    struct vnet_link * link = NULL;
-       
-    #ifdef CONFIG_DEBUG_VNET_LNX_BRIGE
-    {
-       PrintDebug("vnet_brg_send... pkt size: %d, link: %d, struct len: %d\n",
-                       vnet_pkt->size,
-                       vnet_pkt->dst_id,
-                       sizeof(struct v3_vnet_pkt));
-    }
-    #endif
-
-    state->pkt_recv ++;
-    link = link_by_idx(state, vnet_pkt->dst_id);
-    if (link != NULL) {
-       if(link->type == SOCK_UDP){
-           udp_send(link->socket, 0, 0, vnet_pkt->data, vnet_pkt->size);
-           state->pkt_sent ++;
-       }else {
-           PrintError("VNET Linux Bridge: wrong link type\n"); 
-           return -1;
-       }
-    } else {
-       PrintDebug("VNET Linux Bridge: wrong dst link, idx: %d, discards the packet\n", vnet_pkt->dst_id);
-       state->pkt_drop ++;
-    }
-
-    return 0;
-}
-
-
-static int init_serv(struct vnet_brg_state * state) {
-    int sock, err;
-
-    if(state->serv_sock_type == SOCK_UDP){
-       sock = V3_Create_UDP_Socket();
-       if (sock < 0) {
-           PrintError("Could not create socket, Initiate VNET server error\n");
-           return -1;
-       }
-
-       err = V3_Bind_Socket(sock, state->serv_port);
-       if(err < 0){
-           PrintError("Error to bind VNET Linux bridge receiving UDP socket\n");
-           return -1;
-       }
-       state->serv_sock = sock;
-    }
-
-    return 0;
-}
-
-static int vnet_server(void * arg) {
-    struct v3_vnet_pkt pkt;
-    struct vnet_link *link;
-    struct vnet_brg_state * state = (struct vnet_brg_state *)arg;
-    uchar_t buf[ETHERNET_MTU];
-    uint32_t ip = 0;
-    uint16_t port = 0;
-    int len;
-
-    while (1) {
-       len = udp_recv(state->serv_sock, &ip, &port, buf, ETHERNET_MTU);
-       if(len < 0) {
-           PrintError("VNET Linux Bridge: receive error\n");
-           continue;
-       }
-
-       link = link_by_ip(state, ip);
-       if (link != NULL) {
-           pkt.src_id= link->link_idx;
-       }
-       else { 
-           pkt.src_id= -1;
-       }
-
-       pkt.size = len;
-       pkt.src_type = LINK_EDGE;
-       memcpy(pkt.header, buf, ETHERNET_HEADER_LEN);
-       pkt.data = buf;
-       
-       #ifdef CONFIG_DEBUG_VNET_LNX_BRIGE
-       {
-           PrintDebug("VNET Linux Bridge: recv pkt size: %d, pkt src_id: %d\n", 
-                       len,  pkt.src_id);
-           v3_hexdump(buf, len, NULL, 0);
-       }
-       #endif
-
-       v3_vnet_send_pkt(&pkt, NULL);
-       
-       state->pkt_recv ++;
-    }
-
-    return 0;
-}
-
-
-static int vnet_lnxbrg_init() {
-    struct v3_vnet_bridge_ops brg_ops;
-    struct vnet_brg_state * state;
-       
-    state = (struct vnet_brg_state *)V3_Malloc(sizeof(struct vnet_brg_state));
-    V3_ASSERT(state != NULL);
-
-    vnet_lnxbrg_reset(state);
-
-    brg_ops.input = brg_send;
-
-    v3_vnet_add_bridge(NULL, &brg_ops, state);
-
-    init_serv(state);
-    V3_CREATE_THREAD(vnet_server, state, "VNET_LNX_BRIDGE");
-
-    PrintDebug("VNET Linux Bridge initiated\n");
-
-    return 0;
-}
-
-
-device_register("LNX_VNET_BRIDGE", vnet_lnxbrg_init)
index ff039e2..8e7d026 100644 (file)
@@ -42,22 +42,24 @@ struct vnet_nic_state {
 
 /* called by frontend device, 
   * tell the VNET can start sending pkt to it */
-static void start_rx(void *private_data){
-    struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
+static void start_rx(void * private_data){
+    //struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
 
-    v3_vnet_enable_device(vnetnic->vnet_dev_id);
+    //v3_vnet_enable_device(vnetnic->vnet_dev_id);
 }
 
 /* called by frontend device, 
   * tell the VNET stop sending pkt to it */
-static void stop_rx(void *private_data){
-    struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
+static void stop_rx(void * private_data){
+    //struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
 
-    v3_vnet_disable_device(vnetnic->vnet_dev_id);
+    //v3_vnet_disable_device(vnetnic->vnet_dev_id);
 }
 
 /* called by frontend, send pkt to VNET */
-static int vnet_nic_send(uint8_t * buf, uint32_t len, void * private_data, struct vm_device *dest_dev){
+static int vnet_nic_send(uint8_t * buf, uint32_t len, 
+                                               void * private_data, 
+                                               struct vm_device * dest_dev){
     struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
 
     struct v3_vnet_pkt pkt;
@@ -79,9 +81,10 @@ static int vnet_nic_send(uint8_t * buf, uint32_t len, void * private_data, struc
 }
 
 
-/* called by VNET, 
-  * send pkt to frontend device */
-static int virtio_input(struct v3_vm_info *info, struct v3_vnet_pkt * pkt, void * private_data){
+/* send pkt to frontend device */
+static int virtio_input(struct v3_vm_info * info, 
+                                       struct v3_vnet_pkt * pkt, 
+                                       void * private_data){
     struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
        
     return vnetnic->net_ops.recv(pkt->data, 
@@ -89,33 +92,23 @@ static int virtio_input(struct v3_vm_info *info, struct v3_vnet_pkt * pkt, void
                                                        vnetnic->net_ops.frontend_data);
 }
 
-/* called by VNET, 
-  * tell frontend device to poll data from guest */
-static void virtio_poll(struct v3_vm_info *info, void * private_data){
+/* tell frontend device to poll data from guest */
+static void virtio_poll(struct v3_vm_info * info, 
+                                       void * private_data){
     struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
 
     vnetnic->net_ops.poll(info, vnetnic->net_ops.frontend_data);
 }
 
-/* called by VNET, from different processor */
-static void virtio_poll_xcall(void *data){
-    struct v3_vnet_dev_xcall_args *args = (struct v3_vnet_dev_xcall_args *)data;
-    struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)args->private_data;
-
-    if(args->vm == vnetnic->vm) /*only do polling on the same Virtual Machine */
-       virtio_poll(args->vm, args->private_data);
-}
 
-/* called by VNET, 
-  * tell the frontend to start sending pkt to VNET*/
+/* tell the frontend to start sending pkt to VNET*/
 static void start_tx(void *private_data){
     struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
 
     vnetnic->net_ops.start_tx(vnetnic->net_ops.frontend_data);
 }
 
-/* called by VNET 
-  * tell the frontend device to stop sending pkt to VNET*/
+/* tell the frontend device to stop sending pkt to VNET*/
 static void stop_tx(void *private_data){
     struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
 
@@ -137,7 +130,6 @@ static struct v3_device_ops dev_ops = {
 static struct v3_vnet_dev_ops vnet_dev_ops = {
     .input = virtio_input,
     .poll = virtio_poll,
-    .poll_xcall = virtio_poll_xcall,
     .start_tx = start_tx,
     .stop_tx = stop_tx,
 };
index e263735..3726c41 100644 (file)
 #define PrintDebug(fmt, args...)
 #endif
 
-
-/* for UDP encapuslation */
-struct eth_header {
-    uchar_t dest[6];
-    uchar_t src[6];
-    uint16_t type;
-}__attribute__((packed));
-
-struct ip_header {
-    uint8_t version: 4;
-    uint8_t hdr_len: 4;
-    uchar_t tos;
-    uint16_t total_len;
-    uint16_t id;
-    uint8_t flags:     3;
-    uint16_t offset: 13;
-    uchar_t ttl;
-    uchar_t proto;
-    uint16_t cksum;
-    uint32_t src_addr;
-    uint32_t dst_addr;
-}__attribute__((packed));
-
-struct udp_header {
-    uint16_t src_port;
-    uint16_t dst_port;
-    uint16_t len;
-    uint16_t csum;//set to zero, disable the xsum
-}__attribute__((packed));
-
-struct udp_link_header {
-    struct eth_header eth_hdr;
-    struct ip_header ip_hdr;
-    struct udp_header udp_hdr;
-}__attribute__((packed));
-/* end with UDP encapuslation structures */
-
-
-
-
 struct eth_hdr {
     uint8_t dst_mac[6];
     uint8_t src_mac[6];
@@ -84,7 +44,8 @@ struct vnet_dev {
     struct v3_vnet_dev_ops dev_ops;
     void * private_data;
 
-    int rx_disabled;
+    int active;
+    uint8_t mode;  //vmm_drivern or guest_drivern
     
     struct list_head node;
 } __attribute__((packed));
@@ -94,7 +55,9 @@ struct vnet_brg_dev {
     struct v3_vm_info * vm;
     struct v3_vnet_bridge_ops brg_ops;
 
-    int disabled;
+    uint8_t type;
+    uint8_t mode;
+    int active;
     void * private_data;
 } __attribute__((packed));
 
@@ -119,15 +82,6 @@ struct route_list {
 } __attribute__((packed));
 
 
-#define BUF_SIZE 4096
-struct pkts_buf {
-    int start, end;
-    int num; 
-    v3_lock_t lock;
-    struct v3_vnet_pkt pkts[BUF_SIZE];
-};
-
-
 static struct {
     struct list_head routes;
     struct list_head devs;
@@ -139,15 +93,11 @@ static struct {
 
     v3_lock_t lock;
 
-    uint8_t sidecores; /* 0 -vnet not running on sidecore, > 0, number of extra cores that can be used by VNET */
-    uint64_t cores_map; /* bitmaps for which cores can be used by VNET for sidecore, maxium 64 */
-
     struct hashtable * route_cache;
 } vnet_state;
 
 
 
-
 #ifdef CONFIG_DEBUG_VNET
 static inline void mac_to_string(char mac[6], char * buf) {
     snprintf(buf, 100, "%d:%d:%d:%d:%d:%d", 
@@ -442,65 +392,6 @@ static struct route_list * match_route(const struct v3_vnet_pkt * pkt) {
     return matches;
 }
 
-static int send_to_bridge(struct v3_vnet_pkt * pkt){
-    struct vnet_brg_dev *bridge = vnet_state.bridge;
-
-    if (bridge == NULL) {
-       PrintError("VNET: No bridge to sent data to links\n");
-       return -1;
-    }
-
-    return bridge->brg_ops.input(bridge->vm, pkt, bridge->private_data);
-}
-
-
-/* enable a vnet device, notify VNET it can send pkts to it */
-int v3_vnet_enable_device(int dev_id){
-    struct vnet_dev *dev = find_dev_by_id(dev_id);
-    unsigned long flags;
-
-    if(!dev)
-       return -1;
-
-    if(!dev->rx_disabled)
-       return 0;
-
-    flags = v3_lock_irqsave(vnet_state.lock);
-    dev->rx_disabled = 0;
-    v3_unlock_irqrestore(vnet_state.lock, flags);
-
-    /* TODO: Wake up all other guests who are trying to send pkts */
-    dev = NULL;
-    list_for_each_entry(dev, &(vnet_state.devs), node) {
-       if (dev->dev_id != dev_id)
-           dev->dev_ops.start_tx(dev->private_data);
-    }
-
-    return 0;
-}
-
-/* Notify VNET to stop sending pkts to it */
-int v3_vnet_disable_device(int dev_id){
-    struct vnet_dev *dev = find_dev_by_id(dev_id);
-    unsigned long flags;
-
-    if(!dev)
-       return -1;
-
-    flags = v3_lock_irqsave(vnet_state.lock);
-    dev->rx_disabled = 1;
-    v3_unlock_irqrestore(vnet_state.lock, flags);
-
-
-    /* TODO: Notify all other guests to stop send pkts */
-    dev = NULL;
-    list_for_each_entry(dev, &(vnet_state.devs), node) {
-       if (dev->dev_id != dev_id)
-           dev->dev_ops.stop_tx(dev->private_data);
-    }
-
-    return 0;
-}
 
 int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
     struct route_list * matched_routes = NULL;
@@ -545,23 +436,29 @@ int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
     for (i = 0; i < matched_routes->num_routes; i++) {
         struct vnet_route_info * route = matched_routes->routes[i];
        
-        if (route->route_def.dst_type == LINK_EDGE) {                  
+        if (route->route_def.dst_type == LINK_EDGE) {
+            struct vnet_brg_dev *bridge = vnet_state.bridge;
             pkt->dst_type = LINK_EDGE;
             pkt->dst_id = route->route_def.dst_id;
 
-            if (send_to_bridge(pkt) == -1) {
+            if (bridge == NULL || (bridge->active == 0)) {
+               PrintError("VNET: No active bridge to sent data to links\n");
+               continue;
+            }
+
+            if(bridge->brg_ops.input(bridge->vm, pkt, bridge->private_data) == -1){
                 PrintDebug("VNET: Packet not sent properly to bridge\n");
                 continue;
             }         
         } else if (route->route_def.dst_type == LINK_INTERFACE) {
-            if (!route->dst_dev->rx_disabled){ 
+            if (route->dst_dev && route->dst_dev->active){ 
                  if(route->dst_dev->dev_ops.input(route->dst_dev->vm, pkt, route->dst_dev->private_data) == -1) {
                        PrintDebug("VNET: Packet not sent properly\n");
                        continue;
                  }
             }
         } else {
-            PrintError("VNET: Wrong Edge type\n");
+            PrintError("VNET: Wrong dst type\n");
         }
 
         PrintDebug("VNET: Forward one packet according to Route %d\n", i);
@@ -611,37 +508,31 @@ int v3_vnet_add_dev(struct v3_vm_info *vm, uint8_t mac[6],
 }
 
 
-/* TODO: Still need to figure out how to handle this multicore part --Lei
-  */
-void  v3_vnet_poll(struct v3_vm_info *vm){
+void  v3_vnet_poll(struct v3_vm_info * vm){
     struct vnet_dev * dev = NULL; 
+    struct vnet_brg_dev *bridge = vnet_state.bridge;
 
-    switch (vnet_state.sidecores) {
-       case 0:
-               list_for_each_entry(dev, &(vnet_state.devs), node) {
-                   if(dev->vm == vm){
-                       dev->dev_ops.poll(vm, dev->private_data);
-                   }
-              }
-               break;
-       case 1:
-               break;
-       case 2:
-           list_for_each_entry(dev, &(vnet_state.devs), node) {
-               int cpu_id = vm->cores[0].cpu_id + 2; /* temporary here, should use vnet_state.cores_map */
-                struct v3_vnet_dev_xcall_args dev_args; /* could cause problem here -LX */
-                dev_args.vm = vm;
-               dev_args.private_data = dev->private_data;
-               V3_Call_On_CPU(cpu_id, dev->dev_ops.poll_xcall, (void *)&dev_args);
-           }
-           break;
-       default:
-           break;
+    list_for_each_entry(dev, &(vnet_state.devs), node) {
+       if(dev->mode == VMM_DRIVERN && 
+           dev->active && 
+           dev->vm == vm){
+           
+           dev->dev_ops.poll(vm, dev->private_data);
+       }
     }
+
+    if (bridge != NULL && 
+         bridge->active && 
+         bridge->mode == VMM_DRIVERN) {
+       
+       bridge->brg_ops.poll(bridge->vm, bridge->private_data);
+    }
+       
 }
 
 int v3_vnet_add_bridge(struct v3_vm_info * vm,
-                      struct v3_vnet_bridge_ops *ops,
+                      struct v3_vnet_bridge_ops * ops,
+                      uint8_t type,
                       void * priv_data) {
     unsigned long flags;
     int bridge_free = 0;
@@ -671,10 +562,11 @@ int v3_vnet_add_bridge(struct v3_vm_info * vm,
     
     tmp_bridge->vm = vm;
     tmp_bridge->brg_ops.input = ops->input;
-    tmp_bridge->brg_ops.xcall_input = ops->xcall_input;
-    tmp_bridge->brg_ops.polling_pkt = ops->polling_pkt;
+    tmp_bridge->brg_ops.poll = ops->poll;
     tmp_bridge->private_data = priv_data;
-    tmp_bridge->disabled = 0;
+    tmp_bridge->active = 1;
+    tmp_bridge->mode = GUEST_DRIVERN;
+    tmp_bridge->type = type;
        
     /* make this atomic to avoid possible race conditions */
     flags = v3_lock_irqsave(vnet_state.lock);
@@ -685,37 +577,6 @@ int v3_vnet_add_bridge(struct v3_vm_info * vm,
 }
 
 
-#if 0
-int v3_vnet_disable_bridge() {
-    unsigned long flags; 
-    
-    flags = v3_lock_irqsave(vnet_state.lock);
-
-    if (vnet_state.bridge != NULL) {
-       vnet_state.bridge->disabled = 1;
-    }
-
-    v3_unlock_irqrestore(vnet_state.lock, flags);
-
-    return 0;
-}
-
-
-int v3_vnet_enable_bridge() {
-    unsigned long flags; 
-    
-    flags = v3_lock_irqsave(vnet_state.lock);
-
-    if (vnet_state.bridge != NULL) {
-       vnet_state.bridge->disabled = 0;
-    }
-
-    v3_unlock_irqrestore(vnet_state.lock, flags);
-
-    return 0;
-}
-#endif
-
 int v3_init_vnet() {
     memset(&vnet_state, 0, sizeof(vnet_state));
        
@@ -739,9 +600,6 @@ int v3_init_vnet() {
         return -1;
     }
 
-    vnet_state.sidecores = 0;
-    vnet_state.cores_map = 0;
-
     PrintDebug("VNET: initiated\n");
 
     return 0;