ksmtuned 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #!/bin/bash
  2. #
  3. # Copyright 2009 Red Hat, Inc. and/or its affiliates.
  4. # Released under the GPL
  5. #
  6. # Author: Dan Kenigsberg <danken@redhat.com>
  7. #
  8. # ksmtuned - a simple script that controls whether (and with what vigor) ksm
  9. # should search for duplicated pages.
  10. #
  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
  13. # threshold.
  14. #
  15. # send SIGUSR1 to this process right after a new qemu process is started, or
  16. # following its death, to retune ksm accordingly
  17. #
  18. # needs testing and ironing. contact danken@redhat.com if something breaks.
  19. if [ -f /etc/ksmtuned.conf ]; then
  20. . /etc/ksmtuned.conf
  21. fi
  22. debug() {
  23. if [ -n "$DEBUG" ]; then
  24. s="`/bin/date`: $*"
  25. [ -n "$LOGFILE" ] && echo "$s" >> "$LOGFILE" || echo "$s"
  26. fi
  27. }
  28. KSM_MONITOR_INTERVAL=${KSM_MONITOR_INTERVAL:-60}
  29. KSM_NPAGES_BOOST=${KSM_NPAGES_BOOST:-300}
  30. KSM_NPAGES_DECAY=${KSM_NPAGES_DECAY:--50}
  31. KSM_NPAGES_MIN=${KSM_NPAGES_MIN:-64}
  32. KSM_NPAGES_MAX=${KSM_NPAGES_MAX:-1250}
  33. # millisecond sleep between ksm scans for 16Gb server. Smaller servers sleep
  34. # more, bigger sleep less.
  35. KSM_SLEEP_MSEC=${KSM_SLEEP_MSEC:-10}
  36. KSM_THRES_COEF=${KSM_THRES_COEF:-20}
  37. KSM_THRES_CONST=${KSM_THRES_CONST:-2048}
  38. total=`awk '/^MemTotal:/ {print $2}' /proc/meminfo`
  39. debug total $total
  40. npages=0
  41. sleep=$[KSM_SLEEP_MSEC * 16 * 1024 * 1024 / total]
  42. [ $sleep -le 10 ] && sleep=10
  43. debug sleep $sleep
  44. thres=$[total * KSM_THRES_COEF / 100]
  45. if [ $KSM_THRES_CONST -gt $thres ]; then
  46. thres=$KSM_THRES_CONST
  47. fi
  48. debug thres $thres
  49. KSMCTL () {
  50. case x$1 in
  51. xstop)
  52. echo 0 > /sys/kernel/mm/ksm/run
  53. ;;
  54. xstart)
  55. echo $2 > /sys/kernel/mm/ksm/pages_to_scan
  56. echo $3 > /sys/kernel/mm/ksm/sleep_millisecs
  57. echo 1 > /sys/kernel/mm/ksm/run
  58. ;;
  59. esac
  60. }
  61. committed_memory () {
  62. # calculate how much memory is committed to running qemu processes
  63. local progname
  64. progname=${1:-qemu-kvm}
  65. ps -C "$progname" -o rsz | awk '{ sum += $1 }; END { print sum }'
  66. }
  67. free_memory () {
  68. awk '/^(MemFree|Buffers|Cached):/ {free += $2}; END {print free}' \
  69. /proc/meminfo
  70. }
  71. increase_npages() {
  72. local delta
  73. delta=${1:-0}
  74. npages=$[npages + delta]
  75. if [ $npages -lt $KSM_NPAGES_MIN ]; then
  76. npages=$KSM_NPAGES_MIN
  77. elif [ $npages -gt $KSM_NPAGES_MAX ]; then
  78. npages=$KSM_NPAGES_MAX
  79. fi
  80. echo $npages
  81. }
  82. adjust () {
  83. local free committed
  84. free=`free_memory`
  85. committed=`committed_memory`
  86. debug committed $committed free $free
  87. if [ $[committed + thres] -lt $total -a $free -gt $thres ]; then
  88. KSMCTL stop
  89. debug "$[committed + thres] < $total and free > $thres, stop ksm"
  90. return 1
  91. fi
  92. debug "$[committed + thres] > $total, start ksm"
  93. if [ $free -lt $thres ]; then
  94. npages=`increase_npages $KSM_NPAGES_BOOST`
  95. debug "$free < $thres, boost"
  96. else
  97. npages=`increase_npages $KSM_NPAGES_DECAY`
  98. debug "$free > $thres, decay"
  99. fi
  100. KSMCTL start $npages $sleep
  101. debug "KSMCTL start $npages $sleep"
  102. return 0
  103. }
  104. function nothing () {
  105. :
  106. }
  107. loop () {
  108. trap nothing SIGUSR1
  109. while true
  110. do
  111. sleep $KSM_MONITOR_INTERVAL &
  112. wait $!
  113. adjust
  114. done
  115. }
  116. PIDFILE=${PIDFILE-/run/ksmtune.pid}
  117. if touch "$PIDFILE"; then
  118. loop &
  119. echo $! > "$PIDFILE"
  120. fi