| #!/bin/sh | |
| # Copyright 2016 The ChromiumOS Authors | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| set -e | |
| JOB=$(basename "$0") | |
| DEVICE_SHUTTING_DOWN=4 # Defined in session_manager_service.h | |
| # Check if file exists and is writeable by us. -w is always true under root. | |
| is_writeable() { | |
| local file="$1" | |
| local v=0 | |
| if [ -f "${file}" ]; then | |
| local wfile | |
| wfile=$(find "${file}" -maxdepth 1 | awk '$1 ~ /^.*w.*/ { print $NF; }') | |
| if [ -n "${wfile}" ]; then | |
| v=1 | |
| fi | |
| fi | |
| echo "${v}" | |
| } | |
| # Read chrome OS configurations | |
| read_cros_config() { | |
| local path="$1" | |
| local key="$2" | |
| local def="$3" | |
| # cros_config exits with non-zero when a key isn't existed, | |
| cros_config "${path}" "${key}" || echo "${def}" | |
| } | |
| read_cros_config_int() { | |
| local v | |
| v=$(read_cros_config "$@") | |
| # config value should be an integer | |
| case "${v}" in | |
| ''|*[!0-9]*) | |
| logger -t "${JOB}" -p warn \ | |
| "cros_config ${path}/${key} is not an integer! "\ | |
| "Let me use ${def} instead of ${v}." | |
| echo "${def}" | |
| ;; | |
| *) | |
| echo "${v}" | |
| ;; | |
| esac | |
| } | |
| # The ui job can be restarted asynchronously via ui-respawn. This allows the | |
| # possibility that ui can be started while shutdown/reboot is in process. | |
| # Make sure that the reboot/halt jobs are not active at the time we are | |
| # restarting ui. | |
| if ! initctl status reboot | grep -q 'stop/waiting' || \ | |
| ! initctl status halt | grep -q 'stop/waiting'; then | |
| logger -t "${UPSTART_JOB:-}" "ERROR: reboot/shutdown in progress, quit." | |
| stop ui | |
| exit "${DEVICE_SHUTTING_DOWN}" | |
| fi | |
| # Setup drm log tracing if available. This will allow us to access more verbose | |
| # logs to debug display connectivity issues when they arise. The traces are | |
| # accessible via chrome://system and included in feedback/crash reports. | |
| # | |
| # As configured, we won't have a lot of volume in these traces, they will only | |
| # be written in cases where the display configuration changes, or an error | |
| # occurs. As such, there is no performance impact during steady-state operation. | |
| # | |
| # TODO(seanpaul): Once we've finished moving over to the upstream tracefs | |
| # implementation, remove the block initializing the downstream | |
| # debugfs code. Tracked in b/163580546. | |
| DRM_TRACE_DIR="/sys/kernel/debug/dri" | |
| DRM_TRACE_MASK="${DRM_TRACE_DIR}/trace_mask" | |
| if [ -w "${DRM_TRACE_MASK}" ]; then | |
| # 64kB per-cpu of drm logs. | |
| echo 64 > "${DRM_TRACE_DIR}/trace_size_kb" | |
| # 0x106 corresponds to (DRM_UT_DRIVER | DRM_UT_KMS | DRM_UT_DP). | |
| echo 0x106 > "${DRM_TRACE_MASK}" | |
| fi | |
| DRM_TRACEFS_INSTANCE="/sys/kernel/tracing/instances/drm" | |
| DRM_TRACEFS_BUF_SIZE="${DRM_TRACEFS_INSTANCE}/buffer_size_kb" | |
| if [ -w "${DRM_TRACEFS_BUF_SIZE}" ]; then | |
| # 64kB per-cpu of drm logs. | |
| echo 64 > "${DRM_TRACEFS_BUF_SIZE}" | |
| fi | |
| mkdir -p "${UI_LOG_DIR:-}" | |
| ln -sf ui."$(date --utc +%Y%m%d-%H%M%S)" "${UI_LOG_DIR}/${UI_LOG_FILE:-}" | |
| mkdir -p "${CONTAINER_ROOT_DIR:-}" | |
| # Create support directory for Chrome to write its support files and give | |
| # ownership to Chronos since only interaction will be done by it. | |
| SUPPORT_DIR="/var/spool/support" | |
| mkdir -p "${SUPPORT_DIR}" | |
| chown -R chronos "${SUPPORT_DIR}" | |
| # Create a top-level cpu cgroup for ui tasks. This will be used to share cpu | |
| # resources with tasks not managed by the UI. Android will be placed in a | |
| # parallel cgroup allowing priority to be given to one or the other depending | |
| # on what the user is doing at the time. | |
| if [ ! -d "${UI_CPU_CGROUP_DIR:-}" ]; then | |
| mkdir -p "${UI_CPU_CGROUP_DIR}" | |
| fi | |
| # Set up cgroups for chrome. We create two task groups, one for at most one | |
| # foreground renderer and one for all the background renderers and set the | |
| # background group to a very low priority. We specifically do not set it to | |
| # the lowest "2" such that other processes like the update-engine can be even | |
| # lower. The default value is 1024. | |
| CHROME_CPU_CGROUP_DIR=/sys/fs/cgroup/cpu/chrome_renderers | |
| if [ ! -d "${CHROME_CPU_CGROUP_DIR}" ]; then | |
| mkdir -p "${CHROME_CPU_CGROUP_DIR}/foreground" | |
| mkdir -p "${CHROME_CPU_CGROUP_DIR}/background" | |
| echo "10" > "${CHROME_CPU_CGROUP_DIR}/background/cpu.shares" | |
| # Allow featured to still modify these values | |
| chmod -R g+w "${CHROME_CPU_CGROUP_DIR}" | |
| chown -R chronos "${CHROME_CPU_CGROUP_DIR}" | |
| # TODO(ikjn): This scheduler settings are a bit complex, | |
| # Let's move these out to an another executable (c++). | |
| # Tracked in b/182958867 | |
| # We only do this once when we initially create the cgroups. | |
| # Apply ui and chrome foreground cgroup's uclamp.min, default 20%, | |
| v=$(read_cros_config_int "/scheduler-tune" "boost-urgent" "20") | |
| for knob in "${UI_CPU_CGROUP_DIR}/cpu.uclamp.min" \ | |
| "${CHROME_CPU_CGROUP_DIR}/cpu.uclamp.min" \ | |
| "${CHROME_CPU_CGROUP_DIR}/foreground/cpu.uclamp.min"; do | |
| if [ -f "${knob}" ]; then | |
| echo "${v}" > "${knob}" | |
| fi | |
| done | |
| fi | |
| # Apply Input boosting | |
| INPUT_BOOST=/sys/module/cpu_boost/parameters/input_boost_freq_percent | |
| INPUT_BOOST_DEFAULT=0 | |
| CPUFREQ_CONF=/etc/cpufreq.conf | |
| if [ -f "${INPUT_BOOST}" ]; then | |
| # Default value is 75 for platforms using EAS | |
| if [ -f "${CPUFREQ_CONF}" ]; then | |
| # shellcheck source=/dev/null | |
| . "${CPUFREQ_CONF}" | |
| if [ "${CPUFREQ_GOVERNOR:-}" = "schedutil" ]; then | |
| INPUT_BOOST_DEFAULT=75 | |
| fi | |
| fi | |
| read_cros_config_int "/scheduler-tune" "input-boost" \ | |
| "${INPUT_BOOST_DEFAULT}" > "${INPUT_BOOST}" | |
| fi | |
| # Set up the ui freezer cgroup. This is used during suspend to order the | |
| # freezing of processes to avoid FUSE causing freeze to timeout. | |
| if [ ! -d "${UI_FREEZER_CGROUP_DIR:-}" ]; then | |
| mkdir -p "${UI_FREEZER_CGROUP_DIR}" | |
| chown -R chronos "${UI_FREEZER_CGROUP_DIR}" | |
| chown power:power "${UI_FREEZER_CGROUP_DIR}"/freezer.state | |
| fi | |
| # Set up the renderer freezer. This is used during the suspend/resume cycle | |
| # to freeze all the chrome renderers so that they don't take up a lot of power | |
| # when the system comes up in dark resume | |
| if [ ! -d "${CHROME_FREEZER_CGROUP_DIR:-}" ]; then | |
| mkdir -p "${CHROME_FREEZER_CGROUP_DIR}" | |
| mkdir -p "${CHROME_FREEZER_CGROUP_DIR}/to_be_frozen" | |
| chown -R chronos "${CHROME_FREEZER_CGROUP_DIR}" | |
| fi | |
| # Set up a cgroup for containers(Android) started by session manager. To | |
| # start, limit the cpu shares of Android. This will be reset to the default | |
| # once the user clicks on an Android app. Keeping the usage low prevents | |
| # Android boot from slowing the login process. | |
| CONTAINER_CGROUP_DIR=/sys/fs/cgroup/cpu/session_manager_containers | |
| if [ -d "${CONTAINER_CGROUP_DIR}" ]; then | |
| echo "32" > "${CONTAINER_CGROUP_DIR}/cpu.shares" | |
| echo "-1" > "${CONTAINER_CGROUP_DIR}/cpu.cfs_quota_us" | |
| if [ -f "${CONTAINER_CGROUP_DIR}/cpu.uclamp.min" ]; then | |
| echo "100" > "${CONTAINER_CGROUP_DIR}/cpu.uclamp.min" | |
| fi | |
| fi | |
| # Enable transparent huge pages on devices with 8GB+ RAM. | |
| # TODO (b/315138994): move this to chromeos_startup, to enable THP | |
| # as early as possible. | |
| MEM_TOTAL=$(awk '/^MemTotal:/ { print $2 }' /proc/meminfo) | |
| if [ "${MEM_TOTAL}" -ge $((7 * 1024 * 1024)) ]; then | |
| # Only use THP when explicitly requested via madvise(MADV_HUGEPAGE). | |
| if [ -f "/sys/kernel/mm/transparent_hugepage/enabled" ]; then | |
| echo "madvise" > "/sys/kernel/mm/transparent_hugepage/enabled" | |
| fi | |
| # Enable madvise(MADV_HUGEPAGE) on shared memory for VMs guest mappings. | |
| if [ -f "/sys/kernel/mm/transparent_hugepage/shmem_enabled" ]; then | |
| echo "advise" > "/sys/kernel/mm/transparent_hugepage/shmem_enabled" | |
| fi | |
| fi | |
| # Tweak KVM HLT polling only for x86 | |
| if uname -m | grep -q x86; then | |
| HALT_POLL_NS_SHRINK=/sys/module/kvm/parameters/halt_poll_ns_shrink | |
| HALT_POLL_NS=/sys/module/kvm/parameters/halt_poll_ns | |
| # Older kernels (e.g. 4.4) do not permit dynamic halt_poll_ns_shrink and | |
| # have this attr as read-only. | |
| v=$(is_writeable "${HALT_POLL_NS_SHRINK}") | |
| if [ "${v}" != "0" ]; then | |
| echo 2 > "${HALT_POLL_NS_SHRINK}" | |
| fi | |
| # Ditto, just in case | |
| v=$(is_writeable "${HALT_POLL_NS}") | |
| if [ "${v}" != "0" ]; then | |
| echo 160000 > "${HALT_POLL_NS}" | |
| fi | |
| fi | |
| if crossystem "cros_debug?1"; then | |
| # Set up the alt-syscall kernel module (on systems with kernel 3.14 or later) | |
| # to allow developer mode only system calls to be exposed to Android | |
| # containers (and potentially other containers) when the system is in | |
| # developer mode. | |
| DEVMODE_SYSCALL=/proc/sys/kernel/chromiumos/alt_syscall/allow_devmode_syscalls | |
| if [ -e "${DEVMODE_SYSCALL}" ]; then | |
| echo "1" > "${DEVMODE_SYSCALL}" | |
| fi | |
| # /proc/sys/kernel/perf_event_paranoid controls the use of kernel perf events | |
| # system by users without the CAP_SYS_ADMIN capability (see | |
| # kernel/Documentation/sysctl/kernel.txt for details). On systems with kernel | |
| # 3.14 or later, we enable CONFIG_SECURITY_PERF_EVENTS_RESTRICT in kernel, | |
| # which sets the default value of perf_event_paranoid to a more restrictive | |
| # level "3", instead of "1". As alt-syscall exposes perf_event_open() to | |
| # Android containers when the system is in developer mode, restore | |
| # perf_event_paranoid to the less restrictive level "1". | |
| PERF_EVENT_PARANOID=/proc/sys/kernel/perf_event_paranoid | |
| if [ -e "${PERF_EVENT_PARANOID}" ]; then | |
| echo "1" > "${PERF_EVENT_PARANOID}" | |
| fi | |
| fi | |
| # Set up the lucid sleep debug flag. This file only exists on devices that | |
| # use kernel 3.14. When this sysfs entry is set to 1, the kernel will treat | |
| # all resumes as dark resumes, relying on chrome and powerd to detect any user | |
| # activity and to transition out of dark resume into regular resume. Since we | |
| # are currently unable to distinguish the source that woke up the system, this | |
| # is a temporary workaround to allow for apps and extensions to test lucid | |
| # sleep functionality. Chrome will write 1 to this file only if the | |
| # wake-on-packets flag is set. | |
| # | |
| # TODO(chirantan): Remove this once the firmware change and corresponding | |
| # kernel change for querying the wakeup source is ready (crbug.com/414949). | |
| DARK_RESUME_ALWAYS_FILE=/sys/power/dark_resume_always | |
| if [ -e "${DARK_RESUME_ALWAYS_FILE}" ]; then | |
| chown chronos "${DARK_RESUME_ALWAYS_FILE}" | |
| fi |