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.


Further cleanup of vnet /proc interface
[palacios.git] / linux_module / palacios-vnet-brg.c
index 4efbb86..efb7d18 100644 (file)
 #include "palacios-vnet.h"
 #include "palacios.h"
 
+
 #define VNET_SERVER_PORT 9000
 
+#define VNET_YIELD_TIME_USEC 1000
+
 struct vnet_link {
     uint32_t dst_ip;
     uint16_t dst_port;
@@ -106,7 +109,7 @@ static void _delete_link(struct vnet_link * link){
           link->dst_port, 
           link->idx);
 
-    kfree(link);
+    palacios_free(link);
     link = NULL;
 }
 
@@ -182,7 +185,7 @@ uint32_t vnet_brg_add_link(uint32_t ip, uint16_t port, vnet_brg_proto_t proto){
      struct vnet_link * new_link = NULL;
      uint32_t idx;
 
-     new_link = kmalloc(sizeof(struct vnet_link), GFP_KERNEL);
+     new_link = palacios_alloc(sizeof(struct vnet_link));
      if (!new_link) {
        return -1;
      }
@@ -195,7 +198,7 @@ uint32_t vnet_brg_add_link(uint32_t ip, uint16_t port, vnet_brg_proto_t proto){
      idx = _create_link(new_link);
      if (idx < 0) {
        WARNING("Could not create link\n");
-       kfree(new_link);
+       palacios_free(new_link);
        return -1;
      }
 
@@ -255,8 +258,8 @@ _udp_send(struct socket * sock,
 
 static int 
 _udp_recv(struct socket * sock, 
-        struct sockaddr_in * addr,
-        unsigned char * buf, int len) {
+         struct sockaddr_in * addr,
+         unsigned char * buf, int len, int nonblocking) {
     struct msghdr msg;
     struct iovec iov;
     mm_segment_t oldfs;
@@ -269,7 +272,7 @@ _udp_recv(struct socket * sock,
     iov.iov_base = buf;
     iov.iov_len = len;
     
-    msg.msg_flags = 0;
+    msg.msg_flags = MSG_NOSIGNAL | (nonblocking ? MSG_DONTWAIT : 0);
     msg.msg_name = addr;
     msg.msg_namelen = sizeof(struct sockaddr_in);
     msg.msg_control = NULL;
@@ -349,7 +352,7 @@ bridge_send_pkt(struct v3_vm_info * vm,
        link->stats.tx_bytes += pkt->size;
        link->stats.tx_pkts ++;
     } else {
-       INFO("VNET Bridge Linux Host: wrong dst link, idx: %d, discards the packet\n", pkt->dst_id);
+       INFO("VNET Bridge Linux Host: wrong dst link, idx: %d, discarding the packet\n", pkt->dst_id);
        vnet_brg_s.stats.pkt_drop_vmm ++;
     }
 
@@ -410,18 +413,40 @@ static int _udp_server(void * arg) {
 
     INFO("Palacios VNET Bridge: UDP receiving server ..... \n");
 
-    pkt = kmalloc(MAX_PACKET_LEN, GFP_KERNEL);
+    pkt = palacios_alloc(MAX_PACKET_LEN);
+
+    if (!pkt) { 
+       ERROR("Unable to allocate packet in VNET UDP Server\n");
+       return -1;
+    }
+
+
     while (!kthread_should_stop()) {
+
+       // This is a NONBLOCKING receive
+       // If we block here, we will never detect that this thread
+       // is being signaled to stop, plus we might go uninterrupted on this core
+       // blocking out access to other threads - leave this NONBLOCKING
+       // unless you know what you are doing
+       len = _udp_recv(vnet_brg_s.serv_sock, &pkt_addr, pkt, MAX_PACKET_LEN, 1); 
+
+
+       // If it would have blocked, we have no packet, and so
+       // we will give other threads on this core a chance
+       if (len==-EAGAIN || len==-EWOULDBLOCK || len==-EINTR) { 
+           palacios_yield_cpu_timed(VNET_YIELD_TIME_USEC);
+           continue;
+       }
        
-       len = _udp_recv(vnet_brg_s.serv_sock, &pkt_addr, pkt, MAX_PACKET_LEN); 
        if(len < 0) {
            WARNING("Receive error: Could not get packet, error %d\n", len);
            continue;
        }
 
        link = _link_by_ip(pkt_addr.sin_addr.s_addr);
+
        if (link == NULL){
-           WARNING("VNET Server: No VNET Link match the src IP\n");
+           WARNING("VNET Server: No VNET Link matches the src IP\n");
            vnet_brg_s.stats.pkt_drop_phy ++;
            continue;
        }
@@ -433,7 +458,9 @@ static int _udp_server(void * arg) {
        send_to_palacios(pkt, len, link->idx);
     }
 
-    kfree(pkt);
+    INFO("VNET Server: UDP thread exiting\n");
+
+    palacios_free(pkt);
 
     return 0;
 }
@@ -447,6 +474,8 @@ static int _rx_server(void * arg) {
        //accept new connection
        //use select to receive pkt from physical network
        //or create new kthread to handle each connection?
+       WARNING("VNET Server: TCP is not currently supported\n");
+       return -1;
     }else {
        WARNING ("VNET Server: Unsupported Protocol\n");
        return -1;
@@ -507,16 +536,29 @@ int vnet_bridge_init(void) {
 
 void vnet_bridge_deinit(void){
 
+    INFO("VNET LNX Bridge Deinit Started\n");
+
     v3_vnet_del_bridge(HOST_LNX_BRIDGE);
 
+    //DEBUG("Stopping bridge service thread\n");
+
     kthread_stop(vnet_brg_s.serv_thread);
+
+    //DEBUG("Releasing bridee service socket\n");
+
     vnet_brg_s.serv_sock->ops->release(vnet_brg_s.serv_sock);
 
+    //DEBUG("Deiniting bridge links\n");
+
     deinit_links_list();
 
+    //DEBUG("Freeing bridge hash tables\n");
+
     vnet_free_htable(vnet_brg_s.ip2link, 0, 0);
 
     vnet_brg_s.status = 0;
+
+    INFO("VNET LNX Bridge Deinit Finished\n");
 }