2 Commits 317cdfe56a ... 31c9ed569b

Author SHA1 Message Date
  Agustina Arzille 31c9ed569b Test that multiple objects can be received 5 months ago
  Agustina Arzille d836440994 Minor style fixes 5 months ago
7 changed files with 77 additions and 73 deletions
  1. 1 1
      arch/x86/machine/cpu.h
  2. 23 35
      kern/capability.c
  3. 3 5
      kern/thread.c
  4. 36 16
      test/test_cap.c
  5. 13 12
      test/test_intr.c
  6. 1 1
      vm/map.h
  7. 0 3
      vm/page.c

+ 1 - 1
arch/x86/machine/cpu.h

@@ -964,7 +964,7 @@ noreturn void cpu_unw_mctx_set_frame (const uintptr_t *regs, int retval);
 // Switch to a new stack and PC in a flow's port.
 long cpu_port_swap (uintptr_t *args, void *port, void *pc);
 
-// Return from a ported execution context.
+// Return from the execution context in a port.
 noreturn void cpu_port_return (uintptr_t sp, intptr_t ret);
 
 /*

+ 23 - 35
kern/capability.c

@@ -254,20 +254,10 @@ cap_alert_free (struct cap_alert *alert)
   _Auto k_alert = &alert->k_alert;
   int type = cap_alert_type (alert);
 
-  switch (type)
-    {
-      case CAP_ALERT_INTR:
-        cap_intr_rem (k_alert->intr.irq, &async->xlink);
-        break;
-
-      case CAP_ALERT_THREAD_DIED:
-      case CAP_ALERT_TASK_DIED:
-        cap_task_thread_rem (k_alert->any_id, type, &async->xlink);
-        break;
-
-      default:
-        break;
-    }
+  if (type == CAP_ALERT_INTR)
+    cap_intr_rem (k_alert->intr.irq, &async->xlink);
+  else if (type == CAP_ALERT_THREAD_DIED || type == CAP_ALERT_TASK_DIED)
+    cap_task_thread_rem (k_alert->any_id, type, &async->xlink);
 
   kmem_cache_free (&cap_misc_cache, alert);
 }
@@ -543,7 +533,7 @@ cap_recv_alert (struct cap_flow *flow, void *buf,
       SPINLOCK_GUARD (&flow->lock);
       pqueue_insert (&flow->pending_alerts, &entry->pnode);
 
-      if (payload != entry->payload)
+      if (type == CAP_ALERT_INTR)
         entry->k_alert.intr.count +=
           ((struct cap_kern_alert *)payload)->intr.count;
       else if (type != CAP_ALERT_USER)
@@ -813,15 +803,14 @@ cap_pull_iters (struct cap_iters *it, struct ipc_msg_data *mdata)
 
   ssize_t ret = cap_transfer_iters (port->task, &port->in_it, it,
                                     IPC_COPY_FROM, &tmp.bytes_recv);
-  if (ret < 0)
-    return (ret);
+  if (ret > 0)
+    port->mdata.bytes_recv += ret;
 
-  port->mdata.bytes_recv += ret;
   port->mdata.vmes_recv += tmp.vmes_recv;
   port->mdata.caps_recv += tmp.caps_recv;
 
-  if (mdata && user_copy_to (mdata, &tmp, sizeof (tmp)) != 0)
-    ret = -EFAULT;
+  if (mdata)
+    user_copy_to (mdata, &tmp, sizeof (tmp));
 
   return (ret);
 }
@@ -838,15 +827,14 @@ cap_push_iters (struct cap_iters *it, struct ipc_msg_data *mdata)
 
   ssize_t ret = cap_transfer_iters (port->task, port->out_it, it,
                                     IPC_COPY_TO, &tmp.bytes_sent);
-  if (ret < 0)
-    return (ret);
+  if (ret > 0)
+    port->mdata.bytes_sent += ret;
 
-  port->mdata.bytes_sent += ret;
   port->mdata.vmes_sent += tmp.vmes_sent;
   port->mdata.caps_sent += tmp.caps_sent;
 
-  if (mdata && user_copy_to (mdata, &tmp, sizeof (tmp)) != 0)
-    ret = -EFAULT;
+  if (mdata)
+    user_copy_to (mdata, &tmp, sizeof (tmp));
 
   return (ret);
 }
@@ -875,19 +863,19 @@ cap_reply_iters (struct cap_iters *it, int rv)
 
       ret = cap_transfer_iters (port->task, port->out_it, it,
                                 IPC_COPY_TO, &tmp.bytes_sent);
-      if (ret >= 0)
+      if (ret > 0)
         {
           port->mdata.bytes_sent += ret;
-          port->mdata.caps_sent += tmp.caps_sent;
-          port->mdata.vmes_sent += tmp.vmes_sent;
-          cap_mdata_swap (&port->mdata);
-          if (!ipc_iov_iter_empty (&it->iov) ||
-              ipc_vme_iter_size (&it->vme) ||
-              ipc_cap_iter_size (&it->cap))
-            port->mdata.flags |= IPC_MSG_TRUNC;
-
-          ret = port->mdata.bytes_recv;
+          ret = port->mdata.bytes_sent;
         }
+
+      port->mdata.caps_sent += tmp.caps_sent;
+      port->mdata.vmes_sent += tmp.vmes_sent;
+      cap_mdata_swap (&port->mdata);
+      if (!ipc_iov_iter_empty (&it->iov) ||
+          ipc_vme_iter_size (&it->vme) ||
+          ipc_cap_iter_size (&it->cap))
+        port->mdata.flags |= IPC_MSG_TRUNC;
     }
   else
     ret = rv;

+ 3 - 5
kern/thread.c

@@ -2061,7 +2061,7 @@ thread_setup_common (uint32_t cpu)
 static int __init
 thread_setup (void)
 {
-  for (uint32_t cpu = 1; cpu < cpu_count (); cpu++)
+  for (uint32_t cpu = 1; cpu < cpu_count (); ++cpu)
     thread_setup_common (cpu);
 
   kmem_cache_init (&thread_cache, "thread", sizeof (struct thread),
@@ -2776,14 +2776,12 @@ thread_ipc_affinity_impl (struct thread *thread, void *map,
   int error = user_copy_from (cpumap->cpus, map, size);
 
   if (error)
-    goto out;
-
-  if (set)
+    ;
+  else if (set)
     error = thread_set_affinity (thread, cpumap);
   else if ((error = thread_get_affinity (thread, cpumap)) == 0)
     error = user_copy_to (map, cpumap->cpus, size);
 
-out:
   cpumap_destroy (cpumap);
   return (-error);
 }

+ 36 - 16
test/test_cap.c

@@ -50,8 +50,8 @@ struct test_cap_vars
   char buf[16];
   uint32_t bufsize;
   struct iovec iov;
-  struct ipc_msg_vme mvme;
-  struct ipc_msg_cap mcap;
+  struct ipc_msg_vme mvme[2];
+  struct ipc_msg_cap mcap[2];
   struct cap_thread_info info;
   struct cap_kern_alert alert;
 };
@@ -91,14 +91,14 @@ test_cap_entry (struct ipc_msg *msg, struct ipc_msg_data *mdata)
   assert (nb == (ssize_t)vars->bufsize);
   assert (memcmp (vars->buf, "hello", 5) == 0);
 
-  _Auto entry = vm_map_find (vm_map_self (), vars->mvme.addr);
+  _Auto entry = vm_map_find (vm_map_self (), vars->mvme[0].addr);
   assert (entry);
   assert (VM_MAP_PROT (entry->flags) == VM_PROT_READ);
-  assert (*(char *)vars->mvme.addr == 'x');
+  assert (*(char *)vars->mvme[0].addr == 'x');
 
   vm_map_entry_put (entry);
 
-  _Auto cap = cspace_get (cspace_self (), vars->mcap.cap);
+  _Auto cap = cspace_get (cspace_self (), vars->mcap[0].cap);
   assert (cap != NULL);
   assert (cap->type == CAP_TYPE_TASK);
   assert (((struct cap_task *)cap)->task == thread_self()->task);
@@ -107,7 +107,7 @@ test_cap_entry (struct ipc_msg *msg, struct ipc_msg_data *mdata)
   vars->bufsize = 'Z';
 
   void *mem;
-  int error = vm_map_anon_alloc (&mem, vm_map_self (), 101);
+  int error = vm_map_anon_alloc (&mem, vm_map_self (), PAGE_SIZE * 2);
   assert (! error);
 
   _Auto mp = (struct ipc_msg_data *)mem + 1;
@@ -116,10 +116,15 @@ test_cap_entry (struct ipc_msg *msg, struct ipc_msg_data *mdata)
   assert (mp->bytes_sent == nb);
 
   memset (mem, 'z', 100);
-  vars->mvme.addr = (uintptr_t)mem;
-  vars->mvme.size = PAGE_SIZE;
-  vars->mcap.cap = test_cap_alloc_task (task_self ());
+  vars->mvme[0].addr = (uintptr_t)mem;
+  vars->mvme[0].size = vars->mvme[1].size = PAGE_SIZE;
+  vars->mvme[1].addr = (uintptr_t)mem + PAGE_SIZE;
+
+  vars->mcap[0].cap = test_cap_alloc_task (task_self ());
   vars->iov = IOVEC (memset (vars->buf, '?', sizeof (vars->buf)), 8);
+  vars->msg.iov_cnt = 1;
+  vars->msg.cap_cnt = 1;
+  vars->msg.vme_cnt = 2;
 
   cap_reply_msg (&vars->msg, 0);
   panic ("cap_reply_msg returned");
@@ -173,16 +178,16 @@ test_cap_receiver (void *arg)
     assert (vars->mdata.tag == data->tag);
   }
 
-  vars->mvme = (struct ipc_msg_vme) { .addr = PAGE_SIZE * 10 };
+  vars->mvme[0] = (struct ipc_msg_vme) { .addr = PAGE_SIZE * 10 };
   vars->iov = IOVEC (&vars->bufsize, sizeof (vars->bufsize));
   vars->msg = (struct ipc_msg)
     {
       .size = sizeof (struct ipc_msg),
       .iovs = &vars->iov,
       .iov_cnt = 1,
-      .vmes = &vars->mvme,
+      .vmes = vars->mvme,
       .vme_cnt = 1,
-      .caps = &vars->mcap,
+      .caps = vars->mcap,
       .cap_cnt = 1,
     };
 
@@ -225,6 +230,9 @@ test_cap_sender (void *arg)
       struct ipc_msg msg;
       struct ipc_msg_data mdata;
       struct ipc_msg_cap mcap;
+      struct ipc_msg out_msg;
+      struct ipc_msg_vme out_vme[2];
+      struct ipc_msg_cap out_cap[2];
     } *vars = (void *)((char *)mem + PAGE_SIZE);
 
   vars->mvme = (struct ipc_msg_vme)
@@ -257,19 +265,31 @@ test_cap_sender (void *arg)
       .cap_cnt = 1,
     };
 
-  ssize_t nb = cap_send_msg (data->ch, &vars->msg, &vars->msg, &vars->mdata);
+  vars->out_msg = (struct ipc_msg)
+    {
+      .size = sizeof (struct ipc_msg),
+      .iovs = vars->iovecs,
+      .iov_cnt = 2,
+      .vmes = vars->out_vme,
+      .vme_cnt = 2,
+      .caps = vars->out_cap,
+      .cap_cnt = 2
+    };
+
+  ssize_t nb = cap_send_msg (data->ch, &vars->msg,
+                             &vars->out_msg, &vars->mdata);
 
   assert (nb == (ssize_t)(sizeof (uint32_t) + sizeof (vars->buf) - 1));
   assert (vars->bufsize == 'Z');
   assert (memcmp (vars->buf, "?????", 5) == 0);
-  assert (*(char *)vars->mvme.addr == 'z');
+  assert (*(char *)vars->out_vme[0].addr == 'z');
   assert (vars->mdata.vmes_sent == 1);
-  assert (vars->mdata.vmes_recv == 1);
+  assert (vars->mdata.vmes_recv == 2);
   assert (vars->mdata.caps_sent == 1);
   assert (vars->mdata.caps_recv == 1);
   assert (vars->mdata.flags & IPC_MSG_TRUNC);
 
-  _Auto cap = cspace_get (cspace_self (), vars->mcap.cap);
+  _Auto cap = cspace_get (cspace_self (), vars->out_cap[0].cap);
   assert (cap != NULL);
   assert (cap->type == CAP_TYPE_TASK);
   assert (((struct cap_task *)cap)->task == data->receiver);

+ 13 - 12
test/test_intr.c

@@ -105,6 +105,17 @@ test_intr (void *arg)
   assert (data->md.thread_id == 0);
 }
 
+static void
+test_fire_intr (int cnt, int intr)
+{
+  thread_intr_enter ();
+  cpu_intr_disable ();
+  for (int i = 0; i < cnt; ++i)
+    intr_handle (intr);
+  cpu_intr_enable ();
+  thread_intr_leave ();
+}
+
 TEST_DEFERRED (intr)
 {
   semaphore_init (test_intr_sems + 0, 0, 0xff);
@@ -118,24 +129,14 @@ TEST_DEFERRED (intr)
   error = cap_intr_register (flow, TEST_INTR_FIRST);
   assert (! error);
 
-  thread_intr_enter ();
-  cpu_intr_disable ();
-  intr_handle (TEST_INTR_FIRST);
-  intr_handle (TEST_INTR_FIRST);
-  cpu_intr_enable ();
-  thread_intr_leave ();
+  test_fire_intr (2, TEST_INTR_FIRST);
 
   struct thread *thr;
   error = test_util_create_thr (&thr, test_intr, flow, "intr");
   assert (! error);
 
   semaphore_wait (test_intr_sems + 0);
-  thread_intr_enter ();
-  cpu_intr_disable ();
-  intr_handle (TEST_INTR_FIRST);
-  cpu_intr_disable ();
-  thread_intr_leave ();
-
+  test_fire_intr (1, TEST_INTR_FIRST);
   semaphore_post (test_intr_sems + 1);
 
   thread_join (thr);

+ 1 - 1
vm/map.h

@@ -159,7 +159,7 @@ vm_map_entry_put (struct vm_map_entry *entry)
     vm_object_unref (obj);
 }
 
-// Same as 'vm_map_lookup', only more ergonomic
+// Same as 'vm_map_lookup', only more ergonomic.
 #define vm_map_find(map, addr)   \
   ({   \
      struct vm_map_entry *e_ = __builtin_alloca (sizeof (*e_));   \

+ 0 - 3
vm/page.c

@@ -76,9 +76,6 @@
  */
 #define VM_PAGE_CPU_POOL_TRANSFER_RATIO   2
 
-// Order of pages to accumulate before freeing.
-#define VM_PAGE_LIST_FREE_ORDER   8
-
 // Per-processor cache of pages.
 struct vm_page_cpu_pool
 {