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.


Minimize the copies for vnet and Virtio bridge
Lei Xia [Mon, 15 Mar 2010 16:10:28 +0000 (11:10 -0500)]
palacios/include/palacios/vmm_vnet.h
palacios/src/devices/lnx_virtio_nic.c
palacios/src/devices/lnx_virtio_vnet.c
palacios/src/devices/vnet_nic.c
palacios/src/palacios/vmm_vnet.c

index 52fc932..7298918 100644 (file)
@@ -66,7 +66,8 @@ struct v3_vnet_pkt {
        struct {
            uint8_t src_type;
            uint32_t src_id;
-           uint8_t data[ETHERNET_PACKET_LEN];
+           uint8_t header[ETHERNET_HEADER_LEN];
+           uint8_t *data;
        } __attribute__((packed));
     } __attribute__((packed));
 } __attribute__((packed));
index c626708..7bcd9bb 100644 (file)
@@ -478,7 +478,7 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) {
     uint32_t data_len = size;
     uint32_t offset = 0;
     unsigned long flags;
-    int ret_val;
+    int ret_val = -1;
     int raw = 1;
 
     flags = v3_lock_irqsave(virtio->lock);
@@ -495,7 +495,6 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) {
 
     if (q->ring_avail_addr == 0) {
        PrintError("Queue is not set\n");
-       ret_val = -1;
        goto exit;
     }
 
index 4de1ab8..bfbc56c 100644 (file)
@@ -26,7 +26,7 @@
 #include <devices/pci.h>
 
 
-#ifndef CONFIG_LINUX_VIRTIO_VNET_DEBUG
+#ifndef CONFIG_DEBUG_LINUX_VIRTIO_VNET
 #undef PrintDebug
 #define PrintDebug(fmt, args...)
 #endif
@@ -78,8 +78,9 @@ struct vnet_ctrl_hdr {
 struct vnet_virtio_pkt {
     uint32_t link_id;
     uint32_t pkt_size;
-    uint8_t pkt[1500];
-};
+    uint8_t pkt[ETHERNET_PACKET_LEN];
+}__attribute__((packed));
+
 
 static int virtio_reset(struct virtio_vnet_state * vnet_state) {
 
@@ -222,8 +223,6 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt * pkt,
 
     flags = v3_lock_irqsave(vnet_state->lock);
        
-    PrintDebug("VNET Bridge: RX: pkt sent to guest size: %d\n, pkt_header_len: %d\n", data_len, pkt_head_len);
-
     if (q->ring_avail_addr == 0) {
        PrintError("Queue is not set\n");
        goto exit;
@@ -244,11 +243,12 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt * pkt,
            return -1;
        }
 
+       PrintDebug("VNET Bridge: RX: pkt sent to guest pkt size: %d, dst link: %d\n", pkt->size, pkt->dst_id);
+
        // Fill in dst packet buffer
        virtio_pkt->link_id = pkt->dst_id;
        virtio_pkt->pkt_size = pkt->size;
        memcpy(virtio_pkt->pkt, pkt->data, pkt->size);
-
        
        q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
        q->used->ring[q->used->index % q->queue_size].length = sizeof(struct vnet_virtio_pkt); // This should be the total length of data sent to guest (header+pkt_data)
@@ -256,7 +256,7 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt * pkt,
        q->used->index++;
        q->cur_avail_idx++;
     } else {
-       PrintError("Packet buffer overflow in the guest\n");
+       PrintError("Packet buffer overflow in the guest: cur_avai_idx %d, idx: %d\n", q->cur_avail_idx, q->avail->index);
     }
 
     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
@@ -265,7 +265,6 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt * pkt,
        PrintDebug("Raising IRQ %d\n",  vnet_state->pci_dev->config_header.intr_line);
     }
 
-
     ret_val = 0;
 
 exit:
@@ -278,8 +277,7 @@ exit:
 static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state) 
 {
     struct virtio_queue * q = &(vnet_state->queue[XMIT_QUEUE]);
-
-    PrintDebug("VNET Bridge Device: Handle TX\n");
+    struct v3_vnet_pkt pkt;
 
     while (q->cur_avail_idx != q->avail->index) {
        uint16_t desc_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
@@ -288,21 +286,33 @@ static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * v
 
        pkt_desc = &(q->desc[desc_idx]);
 
-       PrintDebug("VNET Bridge: Handle TX buf_len: %d\n", pkt_desc->length);
+       PrintDebug("VNET Bridge: Handle TX desc buf_len: %d\n", pkt_desc->length);
+
+       //PrintDebug("q: %p, %p, %p, %d\n", q, vnet_state->queue, &vnet_state->queue[XMIT_QUEUE], XMIT_QUEUE);
+       //PrintDebug("q->used: %p\n", q->used);
+       //PrintDebug("q->used->ring %p\n", q->used->ring);
 
        if (guest_pa_to_host_va(core, pkt_desc->addr_gpa, (addr_t *)&(virtio_pkt)) == -1) {
            PrintError("Could not translate buffer address\n");
            return -1;
        }
 
-       //TODO:  SETUP VNET PACKET data structure
+       PrintDebug("VNET Bridge: TX: pkt size: %d, dst link: %d\n", virtio_pkt->pkt_size, virtio_pkt->link_id);
 
-       /*
-         if (v3_vnet_send_pkt(pkt, (void *)core) == -1) {
-           PrintError("Error sending packet to vnet\n");
-           return -1;
-       }       
-       */
+       pkt.size = virtio_pkt->pkt_size;
+       pkt.src_id = virtio_pkt->link_id;
+       pkt.src_type = LINK_EDGE;
+       memcpy(pkt.header, virtio_pkt->pkt, ETHERNET_HEADER_LEN);
+       pkt.data = virtio_pkt->pkt;
+
+       v3_vnet_send_pkt(&pkt, NULL);
+
+       q = (struct virtio_queue *)((addr_t)vnet_state->queue + XMIT_QUEUE*sizeof(struct virtio_queue));
+
+       PrintDebug("After q: %p, , %p, %p, %d\n", q, vnet_state->queue, &(vnet_state->queue[XMIT_QUEUE]), XMIT_QUEUE);
+       //PrintDebug("After q->used: %p\n", q->used);
+       //PrintDebug("After q->used->ring %p\n", q->used->ring);
+       
        q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
        q->used->ring[q->used->index % q->queue_size].length = pkt_desc->length; // What do we set this to????
        q->used->index++;
index 86f5ba7..7290038 100644 (file)
@@ -49,7 +49,8 @@ static int vnet_send(uint8_t * buf, uint32_t len, void * private_data, struct vm
     pkt.size = len;
     pkt.src_type = LINK_INTERFACE;
     pkt.src_id = vnetnic->vnet_dev_id;
-    memcpy(pkt.data, buf, pkt.size);
+    memcpy(pkt.header, buf, ETHERNET_HEADER_LEN);
+    pkt.data = buf;
 
 #ifdef CONFIG_DEBUG_VNET_NIC
     {
index bdc4719..38a9087 100644 (file)
@@ -169,7 +169,7 @@ static inline int hash_eq(addr_t key1, addr_t key2) {
 }
 
 
-static int add_route_to_cache(struct v3_vnet_pkt * pkt, struct route_list * routes) {
+static int add_route_to_cache(const struct v3_vnet_pkt * pkt, struct route_list * routes) {
     memcpy(routes->hash_buf, pkt->hash_buf, VNET_HASH_SIZE);    
 
     if (v3_htable_insert(vnet_state.route_cache, (addr_t)routes->hash_buf, (addr_t)routes) == 0) {
@@ -188,7 +188,7 @@ static int clear_hash_cache() {
     return 0;
 }
 
-static int look_into_cache(struct v3_vnet_pkt * pkt, struct route_list ** routes) {
+static int look_into_cache(const struct v3_vnet_pkt * pkt, struct route_list ** routes) {
     
     *routes = (struct route_list *)v3_htable_search(vnet_state.route_cache, (addr_t)(pkt->hash_buf));
    
@@ -279,7 +279,7 @@ int v3_vnet_add_route(struct v3_vnet_route route) {
 
 // At the end allocate a route_list
 // This list will be inserted into the cache so we don't need to free it
-static struct route_list * match_route(struct v3_vnet_pkt * pkt) {
+static struct route_list * match_route(const struct v3_vnet_pkt * pkt) {
     struct vnet_route_info * route = NULL; 
     struct route_list * matches = NULL;
     int num_matches = 0;
@@ -411,7 +411,7 @@ int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
 
 #ifdef CONFIG_DEBUG_VNET
    {
-       struct eth_hdr * hdr = (struct eth_hdr *)(pkt->data);
+       struct eth_hdr * hdr = (struct eth_hdr *)(pkt->header);
        char dest_str[30];
        char src_str[30];
 
@@ -426,14 +426,14 @@ int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
     look_into_cache(pkt, &matched_routes);
        
     if (matched_routes == NULL) {  
-       PrintDebug("Vnet: can not find route in cache, looking into routing table\n");
+       PrintDebug("Vnet: send pkt Looking into routing table\n");
        
        matched_routes = match_route(pkt);
                
        if (matched_routes) {
            add_route_to_cache(pkt, matched_routes);
        } else {
-           PrintDebug("Could not find route for packet...\n");
+           PrintDebug("Could not find route for packet... discards packet\n");
            v3_unlock_irqrestore(vnet_state.lock, flags);
            return -1;
        }
@@ -442,7 +442,7 @@ int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
     v3_unlock_irqrestore(vnet_state.lock, flags);
 
 
-    PrintDebug("Vnet: HandleOnePacket: route matches %d\n", matched_routes->num_routes);
+    PrintDebug("Vnet: send pkt route matches %d\n", matched_routes->num_routes);
 
     for (i = 0; i < matched_routes->num_routes; i++) {
         struct vnet_route_info * route = matched_routes->routes[i];