3 # Copyright 2009 Red Hat, Inc. and/or its affiliates.
4 # Released under the GPL
6 # Author: Dan Kenigsberg <danken@redhat.com>
8 # ksmtuned - a simple script that controls whether (and with what vigor) ksm
9 # should search for duplicated pages.
11 # starts ksm when memory commited to qemu processes exceeds a threshold, and
12 # make ksm work harder and harder untill memory load falls below that
15 # send SIGUSR1 to this process right after a new qemu process is started, or
16 # following its death, to retune ksm accordingly
18 # needs testing and ironing. contact danken@redhat.com if something breaks.
20 if [ -f /etc/ksmtuned.conf ]; then
25 if [ -n "$DEBUG" ]; then
27 [ -n "$LOGFILE" ] && echo "$s" >> "$LOGFILE" || echo "$s"
32 KSM_MONITOR_INTERVAL=${KSM_MONITOR_INTERVAL:-60}
33 KSM_NPAGES_BOOST=${KSM_NPAGES_BOOST:-300}
34 KSM_NPAGES_DECAY=${KSM_NPAGES_DECAY:--50}
36 KSM_NPAGES_MIN=${KSM_NPAGES_MIN:-64}
37 KSM_NPAGES_MAX=${KSM_NPAGES_MAX:-1250}
38 # millisecond sleep between ksm scans for 16Gb server. Smaller servers sleep
39 # more, bigger sleep less.
40 KSM_SLEEP_MSEC=${KSM_SLEEP_MSEC:-10}
42 KSM_THRES_COEF=${KSM_THRES_COEF:-20}
43 KSM_THRES_CONST=${KSM_THRES_CONST:-2048}
45 total=`awk '/^MemTotal:/ {print $2}' /proc/meminfo`
49 sleep=$[KSM_SLEEP_MSEC * 16 * 1024 * 1024 / total]
50 [ $sleep -le 10 ] && sleep=10
52 thres=$[total * KSM_THRES_COEF / 100]
53 if [ $KSM_THRES_CONST -gt $thres ]; then
54 thres=$KSM_THRES_CONST
61 echo 0 > /sys/kernel/mm/ksm/run
64 echo $2 > /sys/kernel/mm/ksm/pages_to_scan
65 echo $3 > /sys/kernel/mm/ksm/sleep_millisecs
66 echo 1 > /sys/kernel/mm/ksm/run
72 # calculate how much memory is committed to running qemu processes
74 pidlist=$(pgrep -d ' ' -- '^qemu(-(kvm|system-.+)|:.{1,11})$')
75 if [ -n "$pidlist" ]; then
76 ps -p "$pidlist" -o rsz=
77 fi | awk '{ sum += $1 }; END { print 0+sum }'
81 awk '/^(MemFree|Buffers|Cached):/ {free += $2}; END {print free}' \
88 npages=$[npages + delta]
89 if [ $npages -lt $KSM_NPAGES_MIN ]; then
90 npages=$KSM_NPAGES_MIN
91 elif [ $npages -gt $KSM_NPAGES_MAX ]; then
92 npages=$KSM_NPAGES_MAX
101 committed=`committed_memory`
102 debug committed $committed free $free
103 if [ $[committed + thres] -lt $total -a $free -gt $thres ]; then
105 debug "$[committed + thres] < $total and free > $thres, stop ksm"
108 debug "$[committed + thres] > $total, start ksm"
109 if [ $free -lt $thres ]; then
110 npages=`increase_npages $KSM_NPAGES_BOOST`
111 debug "$free < $thres, boost"
113 npages=`increase_npages $KSM_NPAGES_DECAY`
114 debug "$free > $thres, decay"
116 KSMCTL start $npages $sleep
117 debug "KSMCTL start $npages $sleep"
121 function nothing () {
129 sleep $KSM_MONITOR_INTERVAL &
135 PIDFILE=${PIDFILE-/var/run/ksmtune.pid}
136 if touch "$PIDFILE"; then