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.


add statistic structure to virtual ethernet devices
Lei Xia [Fri, 11 Feb 2011 18:13:38 +0000 (12:13 -0600)]
palacios/include/palacios/vmm_ethernet.h
palacios/src/devices/lnx_virtio_nic.c
palacios/src/devices/ne2k.c

index ddd1435..f5e9822 100644 (file)
 
 #include <palacios/vmm.h>
 
+
+struct nic_statistics {
+    uint64_t tx_pkts;
+    uint64_t tx_bytes;
+    uint64_t tx_dropped;
+       
+    uint64_t rx_pkts;
+    uint64_t rx_bytes;
+    uint64_t rx_dropped;
+
+    uint32_t interrupts;
+};
+    
 static inline int is_multicast_ethaddr(const uint8_t * addr)
 {
     V3_ASSERT(ETH_ALEN == 6);
index 654698f..529ce02 100644 (file)
@@ -107,7 +107,7 @@ struct virtio_net_state {
     int buffed_rx;
     int tx_disabled;                   /* stop TX pkts from guest */
 
-    uint64_t pkt_sent, pkt_recv, pkt_drop;
+    struct nic_statistics statistics;
 
     struct v3_dev_net_ops * net_ops;
     v3_lock_t rx_lock, tx_lock;
@@ -161,7 +161,6 @@ static int virtio_init_state(struct virtio_net_state * virtio)
         PrintError("Virtio NIC: Failure to init locks for net_state\n");
     }
 
-    virtio->pkt_sent = virtio->pkt_recv = virtio->pkt_drop = 0;
     virtio->buffed_rx = 0;
 
     return 0;
@@ -180,7 +179,16 @@ pkt_tx(struct guest_info * core,
        return -ERR_VIRTIO_OTHER;
     }
 
-    return virtio->net_ops->send(buf, len, virtio->backend_data);
+    if(virtio->net_ops->send(buf, len, virtio->backend_data) >= 0){
+       virtio->statistics.tx_pkts ++;
+       virtio->statistics.tx_bytes += len;
+
+       return 0;
+    }
+
+    virtio->statistics.tx_dropped ++;
+
+    return -1;
 }
 
 
@@ -246,7 +254,7 @@ static int handle_rx_kick(struct guest_info *core,
     if(virtio->net_ops->start_rx != NULL){
        virtio->net_ops->start_rx(virtio->backend_data);
     }
-       //disable_cb(&virtio->rx_vq);
+    //disable_cb(&virtio->rx_vq);
 
     v3_unlock_irqrestore(virtio->rx_lock, flags);
        
@@ -308,8 +316,6 @@ static int handle_pkt_tx(struct guest_info *core,
            req_len += buf_desc->length;
            desc_idx = buf_desc->next;
        }
-       virtio_state->pkt_sent ++;
-       recved ++;
 
        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 = req_len; // What do we set this to????
@@ -326,6 +332,8 @@ static int handle_pkt_tx(struct guest_info *core,
     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
        v3_pci_raise_irq(virtio_state->virtio_dev->pci_bus, 0, virtio_state->pci_dev);
        virtio_state->virtio_cfg.pci_isr = 0x1;
+
+       virtio_state->statistics.interrupts ++;
     }
 
     return 0;
@@ -578,7 +586,6 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) {
 
     flags = v3_lock_irqsave(virtio->rx_lock);
 
-    virtio->pkt_recv ++;
     if (!raw)
        data_len -= hdr_len;
 
@@ -639,8 +646,12 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) {
            }
            virtio->buffed_rx = 0;
        }
+
+       virtio->statistics.rx_pkts ++;
+       virtio->statistics.rx_bytes += size;
     } else {
-       virtio->pkt_drop++;
+       virtio->statistics.rx_dropped ++;
+       
        /* 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);
@@ -653,6 +664,8 @@ static int virtio_rx(uint8_t * buf, uint32_t size, void * private_data) {
        PrintDebug("Raising IRQ %d\n",  virtio->pci_dev->config_header.intr_line);
        v3_pci_raise_irq(virtio->virtio_dev->pci_bus, 0, virtio->pci_dev);
        virtio->virtio_cfg.pci_isr = 0x1;
+
+       virtio->statistics.interrupts ++;
     }
 
     ret_val = offset;
index 46594c3..80b372b 100644 (file)
@@ -319,6 +319,8 @@ struct ne2k_state {
     uint8_t mcast_addr[8];
     uint8_t mac[ETH_ALEN];
 
+    struct nic_statistics statistics;
+
     struct v3_dev_net_ops *net_ops;
     void * backend_data;
 };
@@ -333,20 +335,31 @@ static int ne2k_update_irq(struct ne2k_state * nic_state) {
            v3_pci_raise_irq(nic_state->pci_bus, 0, nic_state->pci_dev);
        }
 
+       nic_state->statistics.interrupts ++;
+
        PrintDebug("NE2000: Raise IRQ\n");
     }
 
     return 0;
 }
 
-static int ne2k_send_packet(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) {
+static int tx_one_pkt(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) {
        
 #ifdef CONFIG_DEBUG_NE2K
     PrintDebug("NE2000: Send Packet:\n");
     v3_hexdump(pkt, length, NULL, 0);
 #endif    
 
-    return nic_state->net_ops->send(pkt, length, nic_state->backend_data);
+    if(nic_state->net_ops->send(pkt, length, nic_state->backend_data) >= 0){
+       nic_state->statistics.tx_pkts ++;
+       nic_state->statistics.tx_bytes += length;
+
+       return 0;
+    }
+       
+    nic_state->statistics.tx_dropped ++;
+
+    return -1;
 }
 
 static int ne2k_rxbuf_full(struct ne2k_registers * regs) {
@@ -475,9 +488,14 @@ static int ne2k_rx(uint8_t * buf, uint32_t size, void * private_data){
 #endif    
 
     if(!rx_one_pkt(nic_state, buf, size)){
+       nic_state->statistics.rx_pkts ++;
+       nic_state->statistics.rx_bytes += size;
+       
        return 0;
     }
-    
+
+    nic_state->statistics.rx_dropped ++;
+       
     return -1;
 }
 
@@ -717,7 +735,7 @@ static int ne2k_cmd_write(struct guest_info * core,
            }
 
            if (offset + regs->tbcr <= NE2K_PMEM_END) {
-               ne2k_send_packet(nic_state, nic_state->mem + offset, regs->tbcr);
+               tx_one_pkt(nic_state, nic_state->mem + offset, regs->tbcr);
            }
 
            regs->tsr.val = 0;        /* clear the tx status reg */