ram_alloc_remote(): reset affinity before calling slot_alloc() release2012-08-08
authorKornilios Kourtis <kkourt@inf.ethz.ch>
Mon, 6 Aug 2012 12:06:52 +0000 (14:06 +0200)
committerKornilios Kourtis <kkourt@inf.ethz.ch>
Mon, 6 Aug 2012 12:06:52 +0000 (14:06 +0200)
commit83fcfcbd94af6241f2e7041fae315e3fecb03fc6
treeaf23d4e59b684fd08d12275d518fc4b6b28b9469
parentefb7e51ef13121313a723364c9f48f2c366cbbec
ram_alloc_remote(): reset affinity before calling slot_alloc()

Based on patch provided by Shi Jinghao <jhshi@cs.hku.hk>:
https://lists.inf.ethz.ch/pipermail/barrelfish-users/2012-August/000783.html:

In ram_alloc_remote, there is a hack that before we obtain the
ram_alloc_lock and do the actual transport, we first check if cs->space ==
1: if yes, we do a pair of dummy slot_alloc and slot_free to help the
slot_allocator grow itself. But since slot_alloc may involve another
ram_alloc call, we need to reset the affinity to the default (0, 0) before
slot_alloc and restore the affinity after slot_free.

I found this bug when I repeatly do: set affinity to
(0x80000000-0xc0000000) (shared memory on SCC), allocate a 4K frame use
frame_alloc, set the affinity back to (0, 0). After a certain number of
iterations, all the slot in slot_allocator are consumed and trigger the
dummy slot_alloc/slot_free operation. Then the slot_alloc failed since at
the moment, the affinity is not the default (0, 0) but
(0x80000000,0xc0000000). So the new frame is allocated on a non-expected
physical memory region and somehow a page fault is triggered, which cause
the system to crash.

Here is the fix patch, FYI.

diff -r ba0440b6d59d lib/barrelfish/ram_alloc.c
--- a/lib/barrelfish/ram_alloc.c Wed Aug 01 20:17:53 2012 +0800
+++ b/lib/barrelfish/ram_alloc.c Wed Aug 01 20:18:31 2012 +0800
@@ -35,6 +35,7 @@
     struct slot_alloc_state *sas = get_slot_alloc_state();
     struct slot_allocator *ca = (struct slot_allocator*)(&sas->defca);
     if (ca->space == 1) {
+        ram_set_affinity(0, 0);
         struct capref cap;
         err = slot_alloc(&cap);
         if (err_is_fail(err)) {
@@ -44,6 +45,7 @@
         if (err_is_fail(err)) {
             return err_push(err, LIB_ERR_SLOT_FREE);
         }
+        ram_set_affinity(minbase, maxlimit);
     }

     assert(ret != NULL);
lib/barrelfish/ram_alloc.c