src/os/linux/vm/os_linux.cpp

changeset 9413
5aa3d728164a
parent 9013
18366fa39fe0
child 9417
65409bcab2ad
     1.1 --- a/src/os/linux/vm/os_linux.cpp	Tue Jul 10 18:31:51 2018 +0100
     1.2 +++ b/src/os/linux/vm/os_linux.cpp	Fri Jul 06 18:50:13 2018 +0000
     1.3 @@ -37,6 +37,7 @@
     1.4  #include "mutex_linux.inline.hpp"
     1.5  #include "oops/oop.inline.hpp"
     1.6  #include "os_share_linux.hpp"
     1.7 +#include "osContainer_linux.hpp"
     1.8  #include "prims/jniFastGetField.hpp"
     1.9  #include "prims/jvm.h"
    1.10  #include "prims/jvm_misc.hpp"
    1.11 @@ -179,13 +180,62 @@
    1.12  julong os::Linux::available_memory() {
    1.13    // values in struct sysinfo are "unsigned long"
    1.14    struct sysinfo si;
    1.15 +  julong avail_mem;
    1.16 +
    1.17 +  if (OSContainer::is_containerized()) {
    1.18 +    jlong mem_limit, mem_usage;
    1.19 +    if ((mem_limit = OSContainer::memory_limit_in_bytes()) < 1) {
    1.20 +      if (PrintContainerInfo) {
    1.21 +        tty->print_cr("container memory limit %s: " JLONG_FORMAT ", using host value",
    1.22 +                       mem_limit == OSCONTAINER_ERROR ? "failed" : "unlimited", mem_limit);
    1.23 +      }
    1.24 +    }
    1.25 +
    1.26 +    if (mem_limit > 0 && (mem_usage = OSContainer::memory_usage_in_bytes()) < 1) {
    1.27 +      if (PrintContainerInfo) {
    1.28 +        tty->print_cr("container memory usage failed: " JLONG_FORMAT ", using host value", mem_usage);
    1.29 +      }
    1.30 +    }
    1.31 +
    1.32 +    if (mem_limit > 0 && mem_usage > 0 ) {
    1.33 +      avail_mem = mem_limit > mem_usage ? (julong)mem_limit - (julong)mem_usage : 0;
    1.34 +      if (PrintContainerInfo) {
    1.35 +        tty->print_cr("available container memory: " JULONG_FORMAT, avail_mem);
    1.36 +      }
    1.37 +      return avail_mem;
    1.38 +    }
    1.39 +  }
    1.40 +
    1.41    sysinfo(&si);
    1.42 -
    1.43 -  return (julong)si.freeram * si.mem_unit;
    1.44 +  avail_mem = (julong)si.freeram * si.mem_unit;
    1.45 +  if (Verbose) {
    1.46 +    tty->print_cr("available memory: " JULONG_FORMAT, avail_mem);
    1.47 +  }
    1.48 +  return avail_mem;
    1.49  }
    1.50  
    1.51  julong os::physical_memory() {
    1.52 -  return Linux::physical_memory();
    1.53 +  jlong phys_mem = 0;
    1.54 +  if (OSContainer::is_containerized()) {
    1.55 +    jlong mem_limit;
    1.56 +    if ((mem_limit = OSContainer::memory_limit_in_bytes()) > 0) {
    1.57 +      if (PrintContainerInfo) {
    1.58 +        tty->print_cr("total container memory: " JLONG_FORMAT, mem_limit);
    1.59 +      }
    1.60 +      return mem_limit;
    1.61 +    }
    1.62 +
    1.63 +    if (PrintContainerInfo) {
    1.64 +      tty->print_cr("container memory limit %s: " JLONG_FORMAT ", using host value",
    1.65 +                     mem_limit == OSCONTAINER_ERROR ? "failed" : "unlimited", mem_limit);
    1.66 +    }
    1.67 +  }
    1.68 +
    1.69 +  phys_mem = Linux::physical_memory();
    1.70 +  if (Verbose) {
    1.71 +    tty->print_cr("total system memory: " JLONG_FORMAT, phys_mem);
    1.72 +  }
    1.73 +  return phys_mem;
    1.74  }
    1.75  
    1.76  ////////////////////////////////////////////////////////////////////////////////
    1.77 @@ -2114,6 +2164,8 @@
    1.78    os::Posix::print_load_average(st);
    1.79  
    1.80    os::Linux::print_full_memory_info(st);
    1.81 +
    1.82 +  os::Linux::print_container_info(st);
    1.83  }
    1.84  
    1.85  // Try to identify popular distros.
    1.86 @@ -2179,6 +2231,57 @@
    1.87     st->cr();
    1.88  }
    1.89  
    1.90 +void os::Linux::print_container_info(outputStream* st) {
    1.91 +if (!OSContainer::is_containerized()) {
    1.92 +    return;
    1.93 +  }
    1.94 +
    1.95 +  st->print("container (cgroup) information:\n");
    1.96 +
    1.97 +  const char *p_ct = OSContainer::container_type();
    1.98 +  st->print("container_type: %s\n", p_ct != NULL ? p_ct : "failed");
    1.99 +
   1.100 +  char *p = OSContainer::cpu_cpuset_cpus();
   1.101 +  st->print("cpu_cpuset_cpus: %s\n", p != NULL ? p : "failed");
   1.102 +  free(p);
   1.103 +
   1.104 +  p = OSContainer::cpu_cpuset_memory_nodes();
   1.105 +  st->print("cpu_memory_nodes: %s\n", p != NULL ? p : "failed");
   1.106 +  free(p);
   1.107 +
   1.108 +  int i = OSContainer::active_processor_count();
   1.109 +  if (i > 0) {
   1.110 +    st->print("active_processor_count: %d\n", i);
   1.111 +  } else {
   1.112 +    st->print("active_processor_count: failed\n");
   1.113 +  }
   1.114 +
   1.115 +  i = OSContainer::cpu_quota();
   1.116 +  st->print("cpu_quota: %d\n", i);
   1.117 +
   1.118 +  i = OSContainer::cpu_period();
   1.119 +  st->print("cpu_period: %d\n", i);
   1.120 +
   1.121 +  i = OSContainer::cpu_shares();
   1.122 +  st->print("cpu_shares: %d\n", i);
   1.123 +
   1.124 +  jlong j = OSContainer::memory_limit_in_bytes();
   1.125 +  st->print("memory_limit_in_bytes: " JLONG_FORMAT "\n", j);
   1.126 +
   1.127 +  j = OSContainer::memory_and_swap_limit_in_bytes();
   1.128 +  st->print("memory_and_swap_limit_in_bytes: " JLONG_FORMAT "\n", j);
   1.129 +
   1.130 +  j = OSContainer::memory_soft_limit_in_bytes();
   1.131 +  st->print("memory_soft_limit_in_bytes: " JLONG_FORMAT "\n", j);
   1.132 +
   1.133 +  j = OSContainer::OSContainer::memory_usage_in_bytes();
   1.134 +  st->print("memory_usage_in_bytes: " JLONG_FORMAT "\n", j);
   1.135 +
   1.136 +  j = OSContainer::OSContainer::memory_max_usage_in_bytes();
   1.137 +  st->print("memory_max_usage_in_bytes: " JLONG_FORMAT "\n", j);
   1.138 +  st->cr();
   1.139 +}
   1.140 +
   1.141  void os::print_memory_info(outputStream* st) {
   1.142  
   1.143    st->print("Memory:");
   1.144 @@ -4951,6 +5054,10 @@
   1.145    }
   1.146  }
   1.147  
   1.148 +void os::pd_init_container_support() {
   1.149 +  OSContainer::init();
   1.150 +}
   1.151 +
   1.152  // this is called _after_ the global arguments have been parsed
   1.153  jint os::init_2(void)
   1.154  {
   1.155 @@ -5131,7 +5238,7 @@
   1.156  // sched_getaffinity gives an accurate answer as it accounts for cpusets.
   1.157  // If anything goes wrong we fallback to returning the number of online
   1.158  // processors - which can be greater than the number available to the process.
   1.159 -int os::active_processor_count() {
   1.160 +int os::Linux::active_processor_count() {
   1.161    cpu_set_t cpus;  // can represent at most 1024 (CPU_SETSIZE) processors
   1.162    int cpus_size = sizeof(cpu_set_t);
   1.163    int cpu_count = 0;
   1.164 @@ -5149,10 +5256,48 @@
   1.165              "which may exceed available processors", strerror(errno), cpu_count);
   1.166    }
   1.167  
   1.168 -  assert(cpu_count > 0 && cpu_count <= processor_count(), "sanity check");
   1.169 +  assert(cpu_count > 0 && cpu_count <= os::processor_count(), "sanity check");
   1.170    return cpu_count;
   1.171  }
   1.172  
   1.173 +// Determine the active processor count from one of
   1.174 +// three different sources:
   1.175 +//
   1.176 +// 1. User option -XX:ActiveProcessorCount
   1.177 +// 2. kernel os calls (sched_getaffinity or sysconf(_SC_NPROCESSORS_ONLN)
   1.178 +// 3. extracted from cgroup cpu subsystem (shares and quotas)
   1.179 +//
   1.180 +// Option 1, if specified, will always override.
   1.181 +// If the cgroup subsystem is active and configured, we
   1.182 +// will return the min of the cgroup and option 2 results.
   1.183 +// This is required since tools, such as numactl, that
   1.184 +// alter cpu affinity do not update cgroup subsystem
   1.185 +// cpuset configuration files.
   1.186 +int os::active_processor_count() {
   1.187 +  // User has overridden the number of active processors
   1.188 +  if (ActiveProcessorCount > 0) {
   1.189 +    if (PrintActiveCpus) {
   1.190 +      tty->print_cr("active_processor_count: "
   1.191 +                    "active processor count set by user : %d",
   1.192 +                    ActiveProcessorCount);
   1.193 +    }
   1.194 +    return ActiveProcessorCount;
   1.195 +  }
   1.196 +
   1.197 +  int active_cpus;
   1.198 +  if (OSContainer::is_containerized()) {
   1.199 +    active_cpus = OSContainer::active_processor_count();
   1.200 +    if (PrintActiveCpus) {
   1.201 +      tty->print_cr("active_processor_count: determined by OSContainer: %d",
   1.202 +                     active_cpus);
   1.203 +    }
   1.204 +  } else {
   1.205 +    active_cpus = os::Linux::active_processor_count();
   1.206 +  }
   1.207 +
   1.208 +  return active_cpus;
   1.209 +}
   1.210 +
   1.211  void os::set_native_thread_name(const char *name) {
   1.212    // Not yet implemented.
   1.213    return;

mercurial