vhost: Fix mmap size calculation
[vpp.git] / src / vnet / devices / virtio / vhost-user.c
index 5e720f6..3ac7697 100644 (file)
@@ -303,7 +303,7 @@ unmap_all_mem_regions (vhost_user_intf_t * vui)
 
          ssize_t map_sz = (vui->regions[i].memory_size +
                            vui->regions[i].mmap_offset +
-                           page_sz) & ~(page_sz - 1);
+                           page_sz - 1) & ~(page_sz - 1);
 
          r =
            munmap (vui->region_mmap_addr[i] - vui->regions[i].mmap_offset,
@@ -404,6 +404,7 @@ vhost_user_rx_thread_placement ()
          thread_index = vui_workers[i];
          i++;
          vhc = &vum->cpus[thread_index];
+         txvq->interrupt_thread_index = thread_index;
 
          iaq.qid = qid;
          iaq.vhost_iface_index = vui - vum->vhost_user_interfaces;
@@ -534,45 +535,33 @@ vhost_user_set_interrupt_pending (vhost_user_intf_t * vui, u32 ifq)
   vhost_user_main_t *vum = &vhost_user_main;
   vhost_cpu_t *vhc;
   u32 thread_index;
-  vhost_iface_and_queue_t *vhiq;
   vlib_main_t *vm;
-  u32 ifq2;
-  u8 done = 0;
+  u32 ifq2, qid;
+  vhost_user_vring_t *txvq;
+
+  qid = ifq & 0xff;
+  if ((qid % 2) == 0)
+    /* Only care about the odd number virtqueue which is TX */
+    return;
 
   if (vhost_user_intf_ready (vui))
     {
-      vec_foreach (vhc, vum->cpus)
-      {
-       if (vhc->operation_mode == VHOST_USER_POLLING_MODE)
-         continue;
-
-       vec_foreach (vhiq, vhc->rx_queues)
+      txvq = &vui->vrings[qid];
+      thread_index = txvq->interrupt_thread_index;
+      vhc = &vum->cpus[thread_index];
+      if (vhc->operation_mode == VHOST_USER_INTERRUPT_MODE)
        {
+         vm = vlib_mains ? vlib_mains[thread_index] : &vlib_global_main;
          /*
-          * Match the interface and the virtqueue number
+          * Convert virtqueue number in the lower byte to vring
+          * queue index for the input node process. Top bytes contain
+          * the interface, lower byte contains the queue index.
           */
-         if ((vhiq->vhost_iface_index == (ifq >> 8)) &&
-             (VHOST_VRING_IDX_TX (vhiq->qid) == (ifq & 0xff)))
-           {
-             thread_index = vhc - vum->cpus;
-             vm = vlib_mains ? vlib_mains[thread_index] : &vlib_global_main;
-             /*
-              * Convert RX virtqueue number in the lower byte to vring
-              * queue index for the input node process. Top bytes contain
-              * the interface, lower byte contains the queue index.
-              */
-             ifq2 = ((ifq >> 8) << 8) | vhiq->qid;
-             vhc->pending_input_bitmap =
-               clib_bitmap_set (vhc->pending_input_bitmap, ifq2, 1);
-             vlib_node_set_interrupt_pending (vm,
-                                              vhost_user_input_node.index);
-             done = 1;
-             break;
-           }
+         ifq2 = ((ifq >> 8) << 8) | qid / 2;
+         vhc->pending_input_bitmap =
+           clib_bitmap_set (vhc->pending_input_bitmap, ifq2, 1);
+         vlib_node_set_interrupt_pending (vm, vhost_user_input_node.index);
        }
-       if (done)
-         break;
-      }
     }
 }
 
@@ -605,15 +594,14 @@ vhost_user_kickfd_read_ready (unix_file_t * uf)
 
   n = read (uf->file_descriptor, ((char *) &buff), 8);
   DBG_SOCK ("if %d KICK queue %d", uf->private_data >> 8, qid);
-
-  vlib_worker_thread_barrier_sync (vlib_get_main ());
   if (!vui->vrings[qid].started ||
       (vhost_user_intf_ready (vui) != vui->is_up))
     {
+      vlib_worker_thread_barrier_sync (vlib_get_main ());
       vui->vrings[qid].started = 1;
       vhost_user_update_iface_state (vui);
+      vlib_worker_thread_barrier_release (vlib_get_main ());
     }
-  vlib_worker_thread_barrier_release (vlib_get_main ());
 
   vhost_user_set_interrupt_pending (vui, uf->private_data);
   return 0;
@@ -929,7 +917,7 @@ vhost_user_socket_read (unix_file_t * uf)
          /* align size to 2M page */
          ssize_t map_sz = (vui->regions[i].memory_size +
                            vui->regions[i].mmap_offset +
-                           page_sz) & ~(page_sz - 1);
+                           page_sz - 1) & ~(page_sz - 1);
 
          vui->region_mmap_addr[i] = mmap (0, map_sz, PROT_READ | PROT_WRITE,
                                           MAP_SHARED, fds[i], 0);
@@ -1180,7 +1168,7 @@ vhost_user_socket_read (unix_file_t * uf)
        /* align size to 2M page */
        long page_sz = get_huge_page_size (fd);
        ssize_t map_sz =
-         (msg.log.size + msg.log.offset + page_sz) & ~(page_sz - 1);
+         (msg.log.size + msg.log.offset + page_sz - 1) & ~(page_sz - 1);
 
        vui->log_base_addr = mmap (0, map_sz, PROT_READ | PROT_WRITE,
                                   MAP_SHARED, fd, 0);
@@ -1366,15 +1354,6 @@ vhost_user_init (vlib_main_t * vm)
 
 VLIB_INIT_FUNCTION (vhost_user_init);
 
-static clib_error_t *
-vhost_user_exit (vlib_main_t * vm)
-{
-  /* TODO cleanup */
-  return 0;
-}
-
-VLIB_MAIN_LOOP_EXIT_FUNCTION (vhost_user_exit);
-
 static u8 *
 format_vhost_trace (u8 * s, va_list * va)
 {
@@ -2565,6 +2544,7 @@ vhost_user_term_if (vhost_user_intf_t * vui)
                                           vui->unix_server_index);
       unix_file_del (&unix_main, uf);
       vui->unix_server_index = ~0;
+      unlink (vui->sock_filename);
     }
 }
 
@@ -2602,6 +2582,25 @@ vhost_user_delete_if (vnet_main_t * vnm, vlib_main_t * vm, u32 sw_if_index)
   return rv;
 }
 
+static clib_error_t *
+vhost_user_exit (vlib_main_t * vm)
+{
+  vnet_main_t *vnm = vnet_get_main ();
+  vhost_user_main_t *vum = &vhost_user_main;
+  vhost_user_intf_t *vui;
+
+  vlib_worker_thread_barrier_sync (vlib_get_main ());
+  /* *INDENT-OFF* */
+  pool_foreach (vui, vum->vhost_user_interfaces, {
+      vhost_user_delete_if (vnm, vm, vui->sw_if_index);
+  });
+  /* *INDENT-ON* */
+  vlib_worker_thread_barrier_release (vlib_get_main ());
+  return 0;
+}
+
+VLIB_MAIN_LOOP_EXIT_FUNCTION (vhost_user_exit);
+
 /**
  * Open server unix socket on specified sock_filename.
  */
@@ -2814,6 +2813,9 @@ vhost_user_send_interrupt_process (vlib_main_t * vm,
          clib_warning ("BUG: unhandled event type %d", event_type);
          break;
        }
+      /* No less than 1 millisecond */
+      if (timeout < 1e-3)
+       timeout = 1e-3;
     }
   return 0;
 }