Skip to content
Snippets Groups Projects
  1. Jan 24, 2014
    • Glauber Costa's avatar
      balloon: fix the double move problem · 4eb7d9c2
      Glauber Costa authored
      
      As we have recently discovered, some parallel GCs will move an object to two
      different locations at times, and later on decide on which one to use. This
      breaks our implementation if the final object is the second one to be copied,
      because by then the original region is already mapped - so we won't fault, and
      the unmapped region will not be the actual balloon, so we will have a bogus
      fault
      
      The core of this solution is to keep all the regions unmapped. Because they had
      only garbage before, we know Java shouldn't read anything from it before it
      writes something new. And when it does that, we declare that to be no longer a
      balloon.
      
      Movement is then split in two phases: the normal phase, and the finish phase.
      In the finish phase we will remove the old VMA and create the new VMA again,
      with heap characteristics.
      
      Special care needs to be taken when "conciliating" the array: because we use
      the difference between first faulting address and original array address to
      calculate how many bytes we are skipping, we need to store that information
      somewhere. We're using an unordered_map (hash) for that. We'll keep track of
      all in-flight ballooned regions and hold the original address of the array.
      
      When we detect movement *from* that region, we know it is the new location
      and update the balloon object with the new address.
      
      Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
      Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
      4eb7d9c2
    • Glauber Costa's avatar
      balloon: introduce a conciliation phase · 2b8ceebc
      Glauber Costa authored
      
      This patch introduces a separate operation, "conciliate", that calculates
      the balloon parameters given an arbitrary address
      
      Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
      Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
      2b8ceebc
    • Glauber Costa's avatar
      balloon: fix stack-like behavior for balloons · 5d83b36d
      Glauber Costa authored
      
      We should always remove the last balloon we've created. There are two main
      reasons for that:
      
      1) The older balloons are likely to be already in more tenured generations,
      and will move less, whereas younger balloons could be in younger generations.
      So by removing them like a stack, we'll avoid needless moves
      
      2) The probe, when inserted, should stay for as long as we can.
      
      That was always the intended behavior but I made the small mistake of inserting
      them in the wrong order. Fix that.
      
      Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
      Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
      5d83b36d
  2. Jan 22, 2014
  3. Jan 20, 2014
  4. Jan 16, 2014
  5. Jan 15, 2014
  6. Jan 10, 2014
    • Glauber Costa's avatar
      jvm: set max_heap to all available memory. · 8ea89c9c
      Glauber Costa authored
      
      We respect -Xmx when instructed by the user, but when that is left blank, we
      set that to be all remaining memory that we have. That is not 100 % perfect
      because the JVM itself will use some memory, but that should be good enough of
      an estimate. Specially given that some of the memory currently in use by OSv
      could be potentially freed in the future should we need it.
      
      Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
      Reviewed-by: default avatarNadav Har'El <nyh@cloudius-systems.com>
      Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
      8ea89c9c
    • Glauber Costa's avatar
      jvm_balloon: disable balloon upon jvm memory pressure. · 0034af3f
      Glauber Costa authored
      
      The biggest problem I am seeing with the balloon is that right now the only
      time we call the balloon is when we're seeing memory pressure. If pressure is
      coming from the JVM, we can livelock in quite interesting ways. We need to
      detect that and disable the ballon in those situations, since ballooning when
      the pressure comes from the JVM will only trash our workloads.
      
      It's not yet working reliably, but this is the direction I plan to start from.
      
      Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
      Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
      0034af3f
    • Glauber Costa's avatar
      jvm: insert probe · b32a006b
      Glauber Costa authored
      
      To find out which vmas hold the Java heap, we will use a technique that is very
      close to ballooning (in the implementation, it is effectively the same)
      
      What we will do is we will insert a very small element (2 pages), and mark the
      vma where the object is present as containing the JVM heap. Due to the way the
      JVM allocates objects, that will end up in the young generation. As time
      passes, the object will move the same way the balloon moves, and every new vma
      that is seen will be marked as holding the JVM heap.
      
      That mechanism should work for every generational GC, which should encompass
      most of the JDK7 GCs (it not all). It shouldn't work with the G1GC, but that
      debuts at JDK8, and for that we can do something a lot simpler, namely: having
      the JVM to tell us in advance which map areas contain the heap.
      
      Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
      Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
      b32a006b
    • Glauber Costa's avatar
      java: memory pressure monitor · 88343714
      Glauber Costa authored
      
      The best possible criteria for deflating balloons is heap pressure: Whenever
      there is pressure in the JVM, we should give back memory so pressure stops.
      
      To accomplish that, we need to somehow tap into the JVM. This patch register
      a MXBean that will send us notifications about collections. We will ignore
      minor collections and act upon major collections by deflating any existing
      balloons.
      
      Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
      Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
      88343714
    • Glauber Costa's avatar
      jvm_balloon: control shrinker activation / deactivation · 52cb4738
      Glauber Costa authored
      
      There are restrictions on when and how a shrinker can run. For instance, if we
      have no balloons inflated, there is nothing to deflate (the relaxer should,
      then, be deactivated). Or also, when the JVM fails to allocate memory for an
      extra balloon, it is pointless to keep trying (which would only lead to
      unnecessary spins) until *at least* the next garbage collection phase.
      
      I believe this behavior of activation / deactivation ought to be shrinker
      specific. The reclaiming framework will only provide the infrastructure to do
      so.
      
      In this patch, the JVM Balloon uses that to inform the reclaimer when it makes
      sense for the shrinker or relaxer to be called.
      
      Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
      Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
      52cb4738
    • Glauber Costa's avatar
      JVM ballon driver · 9c59e7e8
      Glauber Costa authored
      
      This patch implements the JVM balloon driver, that is responsible for borrowing
      memory from the JVM when OSv is short on memory, and giving it back when we are
      plentiful. It works by allocating a java byte array, and then unmapping a large
      page-aligned region inside it (as big as our size allows).
      
      This array is good to go until the GC decides to move us. When that happens, we
      need to carefuly emulate the memcpy fault and put things back in place.
      
      Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
      Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
      9c59e7e8
  7. Jan 02, 2014
  8. Dec 27, 2013
  9. Dec 03, 2013
  10. Nov 25, 2013
  11. Nov 18, 2013
  12. Nov 08, 2013
  13. Nov 04, 2013
  14. Oct 29, 2013
  15. Oct 24, 2013
  16. Oct 15, 2013
  17. Oct 14, 2013
    • Nadav Har'El's avatar
      Rework elf::program's API · ba3e3efa
      Nadav Har'El authored
      
      This is patch v2, incorporating most of the comments from the previous round.
      
      Solves issue #47:
      
      elf::program's API - add_object() and remove_object() was problematic in
      two respects:
      
      1. It did not do reference-counting on the loaded object, so if add_object()
         was done 5 times, a single remove_object() would unmap the object and
        its 4 other users will crash.
      
      2. It is un-C++-like.
      
      This patch replaces these two functions by a single function get_library():
      
        std::shared_ptr<elf::object>
         get_library(std::string lib, std::vector<std::string> extra_path = {});
      
      get_library() returns a shared_ptr, which is reference counting and does
      proper C++-style RAII. For example in the code:
      
      	auto lib = elf::get_program()->get_library(path);
      	auto main = lib->lookup<int (int, char**)>("main");
      	int rc = main(argc, argv);
      
      once lib out of scope, the reference count of the elf::object automatically
      goes down, and if nobody else holds another shared-pointer to the same
      library, the object is destroyed (causing the shared library to be unloaded).
      
      This patch also documents, with Doxygen, all the functions it touches.
      
      IMPORTANT NOTE: This reference count is completely unrelated to the issue
      of concurrent use of dlopen()/dlclose()/dl_iterate_phdr(), which is still
      buggy and we need to fix (I have a patch for that, but it's too long to fit
      in the margin).
      
      Signed-off-by: default avatarNadav Har'El <nyh@cloudius-systems.com>
      ba3e3efa
    • Tomasz Grabiec's avatar
      RunJava: handle directories in classpath properly · 9325f833
      Tomasz Grabiec authored
      
      URLClassLoader determines whether URL denotes a jar or directory
      by checking the last character of the path.
      
      Before:
      
         [/]% java -cp java Hello
         Uncaught Java exception:
         java.lang.ClassNotFoundException: Hello
             at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
             at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
             at java.security.AccessController.doPrivileged(Native Method)
             at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
             at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
             at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
             at io.osv.RunJava.loadClass(RunJava.java:175)
             at io.osv.RunJava.runClass(RunJava.java:115)
             at io.osv.RunJava.parseArgs(RunJava.java:81)
             at io.osv.RunJava.main(RunJava.java:27)
      
      After:
      
         [/]% java -cp java Hello
         Hello, world.
      
      Signed-off-by: default avatarTomasz Grabiec <tgrabiec@cloudius-systems.com>
      9325f833
    • Tomasz Grabiec's avatar
      java.cc: return on error rather than abort · e0b8739c
      Tomasz Grabiec authored
      
      Currently we call abort() if something is wrong whith
      java.so command. Now that we allow to run processes from
      the command line this may not be the best behavior because
      a problem with starting a less import program will abort
      the system:
      
        [/]% run java.so -cp java Hello
        run_elf(): running main() in the context of thread 0xffffc0000c30b010
        java.so: Can't create VM.
        Aborted
      
      Instead of that we could just return and the system can
      be still usable:
      
        [/]% run java.so -cp java Hello
        run_elf(): running main() in the context of thread 0xffffc0000c30b010
        java.so: Can't create VM.
        run: finished with exitcode 1
      
        [/]%
      
      Signed-off-by: default avatarTomasz Grabiec <tgrabiec@cloudius-systems.com>
      e0b8739c
  18. Oct 07, 2013
  19. Oct 06, 2013
    • Nadav Har'El's avatar
      Put RunJava.class in a jar, runjava.jar · a8af5dde
      Nadav Har'El authored
      
      We use the RunJava Java class to run Java applications (both java.so
      and the "java" CLI command use it). We used to have RunJava.class
      uncompressed, in the /java directory, but this caused two problems:
      
      1. Or noticed that having a directory (/java) on the classpath causes
         thousands of stat() calls when Java tries to look for all classes
         in this directory. With a jar, its contents are read only once.
      
      2. The "java" CLI command (java.groovy) didn't work because apparently
         Groovy cannot deal with classes being in the top-level package.
      
         So this patch moves RunJava into the io.osv package, and put it into a jar
         /java/runjava.jar.
      
         Note that java.groovy is changed in a separate patch (because it's in
         a different sub-repository....)
      
      Signed-off-by: default avatarNadav Har'El <nyh@cloudius-systems.com>
      a8af5dde
  20. Sep 29, 2013
    • Nadav Har'El's avatar
      Add "-version" option to RunJava · 0ec190c0
      Nadav Har'El authored
      
      Add "-version" option to RunJava, and therefore to java.so and the "java"
      CLI command.
      
      java -version now shows:
      
        java version "1.7.0_25"
        OpenJDK Runtime Environment (1.7.0_25-mockbuild_2013_07_27_13_36-b00)
        OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
      
      I can't explain why the version on the second line is different than what
      "java -version" on Fedora 18 shows for the same libjvm.so:
      
        java version "1.7.0_25"
        OpenJDK Runtime Environment (fedora-2.3.10.4.fc18-x86_64)
        OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
      
      Signed-off-by: default avatarNadav Har'El <nyh@cloudius-systems.com>
      Signed-off-by: default avatarAvi Kivity <avi@cloudius-systems.com>
      0ec190c0
Loading