[fedora-virt] ksmtuned, v2

Dan Kenigsberg danken at redhat.com
Tue Sep 15 14:22:45 UTC 2009


changes since v1:
- broken into two services, one starting ksm up (ksmd), and the other
  tuning it (ksmtuned).
- ksmtune logic separated from service code for cleanliness and simpler
  availability to other distros
- ksm/max_kernel_pages default is absurdly low (allows for 8M of shared
  mem). ksmd now sets it to half of available RAM.
- a handful of typos corrected

Can these files be poured into qemu-system rpm? Or should I file for a
new package?

Comments and suggestion are still welcome.

Dan.
-------------- next part --------------
#!/bin/bash
#
# Copyright 2009 Red Hat, Inc. and/or its affiliates.
# Released under the GPL
#
# ksmd         Kernel Samepage Merging control Daemon
#
# chkconfig: - 84 16
# description: The Kernel Samepage Merging control Daemon is a simple script  \
#	       that starts and stops ksm kernel thread.
# processname: ksmd
# config: /etc/sysconfig/ksm
#
### BEGIN INIT INFO
# Provides: ksmd
# Required-Start:
# Required-Stop:
# Should-Start:
# Short-Description: start and stop ksm
# Description: The Kernel Samepage Merging control Daemon is a simple script
#   that starts and stops ksm kernel thread.
### END INIT INFO

. /etc/rc.d/init.d/functions

if [ -f /etc/sysconfig/ksm ]; then
    . /etc/sysconfig/ksm
fi

prog=ksm
RETVAL=0

# unless KSM_MAX_KERNEL_PAGES is set, let ksm munch up to half of total memory.
default_max_kernel_pages () {
    local total pagesize
    total=`awk '/^MemTotal:/ {print $2}' /proc/meminfo`
    pagesize=`getconf PAGESIZE`
    echo $[total * 1024 / pagesize / 2]
}

start() {
    echo -n $"Starting $prog: "
    KSM_MAX_KERNEL_PAGES=${KSM_MAX_KERNEL_PAGES:-`default_max_kernel_pages`}
    echo $KSM_MAX_KERNEL_PAGES > /sys/kernel/mm/ksm/max_kernel_pages
    echo 1 > /sys/kernel/mm/ksm/run
    RETVAL=$?
    echo
    return $RETVAL
}

stop() {
    echo -n $"Stopping $prog: "
    echo 0 > /sys/kernel/mm/ksm/run
    RETVAL=$?
    echo
}

case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  status)
        is_run=`cat /sys/kernel/mm/ksm/run`
	RETVAL=$?
        if [ is_run -eq 1 ]; then
            echo $"$prog running"
        else
            echo $"$prog not running"
        fi
	;;
  restart)
	stop
	start
	;;
  signal)
	signal
	;;
  *)
	echo $"Usage: $prog {start|stop|restart|status|help}"
	RETVAL=3
esac

exit $RETVAL
-------------- next part --------------
#!/bin/bash
#
# Copyright 2009 Red Hat, Inc. and/or its affiliates.
# Released under the GPL
#
# ksmtune - a simple script that controls whether (and with what vigor) should
# ksm search duplicated pages.
#
# starts ksm when memory commited to qemu processes exceeds a threshold, and
# make ksm work harder and harder untill memory load falls below that
# threshold.
#
# needs testing and ironing. contact danken at redhat.com if something breaks.

if [ -f /etc/ksmd.conf ]; then
    . /etc/ksmd.conf
fi

KSM_MONITOR_INTERVAL=${KSM_MONITOR_INTERVAL:-60}
KSM_NPAGES_BOOST=${KSM_NPAGES_BOOST:-300}
KSM_NPAGES_DECAY=${KSM_NPAGES_DECAY:--50}

KSM_NPAGES_MIN=${KSM_NPAGES_MIN:-64}
KSM_NPAGES_MAX=${KSM_NPAGES_MAX:-1250}
# millisecond sleep between ksm scans for 16Gb server. Smaller servers sleep
# more, bigger sleep less.
KSM_SLEEP_MSEC=${KSM_SLEEP_MSEC:-10}

KSM_THRES_COEF=${KSM_THRES_COEF:-20}
KSM_THRES_CONST=${KSM_THRES_CONST:-2048}

total=`awk '/^MemTotal:/ {print $2}' /proc/meminfo`
[ -n "$DEBUG" ] && echo total $total

npages=0
sleep=$[KSM_SLEEP_MSEC * 16 * 1024 * 1024 / total]
[ $sleep -le 10 ] && sleep=10
[ -n "$DEBUG" ] && echo sleep $sleep
thres=$[total * KSM_THRES_COEF / 100]
if [ $KSM_THRES_CONST -gt $thres ]; then
    thres=$KSM_THRES_CONST
fi
[ -n "$DEBUG" ] && echo thres $thres

KSMCTL () {
    if [ -x /usr/bin/ksmctl ]; then
        local s=$3
        [ -n "$s" ] && s=$[s * 1000]
        /usr/bin/ksmctl $1 $2 $s
    else
        case x$1 in
            xstop)
                echo 0 > /sys/kernel/mm/ksm/run
                ;;
            xstart)
                echo $2 > /sys/kernel/mm/ksm/pages_to_scan
                echo $3 > /sys/kernel/mm/ksm/sleep
                echo 1 > /sys/kernel/mm/ksm/run
                ;;
        esac
    fi
}

committed_memory () {
    # calculate how much memory is committed to running qemu processes
    local progname
    progname=${1:-qemu}
    ps -o vsz `pgrep $progname` | awk '{ sum += $1 }; END { print sum }'
}

free_memory () {
    awk '/^(MemFree|Buffers|MemCached):/ {free += $2}; END {print free}' \
                /proc/meminfo
}

increase_napges() {
    local delta
    delta=${1:-0}
    npages=$[npages + delta]
    if [ $npages -lt $KSM_NPAGES_MIN ]; then
        npages=$KSM_NPAGES_MIN
    elif [ $npages -gt $KSM_NPAGES_MAX ]; then
        npages=$KSM_NPAGES_MAX
    fi
    echo $npages
}


adjust () {
    local free committed
    free=`free_memory`
    committed=`committed_memory`
    [ -n "$DEBUG" ] && echo committed $committed free $free
    if [ $[committed + thres] -lt $total -a $free -gt $thres ]; then
        KSMCTL stop
        [ -n "$DEBUG" ] && echo "$[committed + thres] < $total and free > $thres, stop ksm"
        return 1
    fi
    [ -n "$DEBUG" ] && echo "$[committed + thres] > $total, start ksm"
    if [ $free -lt $thres ]; then
        npages=`increase_napges $KSM_NPAGES_BOOST`
        [ -n "$DEBUG" ] && echo "$free < $thres, boost"
    else
        npages=`increase_napges $KSM_NPAGES_DECAY`
        [ -n "$DEBUG" ] && echo "$free > $thres, decay"
    fi
    KSMCTL start $npages $sleep
    [ -n "$DEBUG" ] && echo "KSMCTL start $npages $sleep"
    return 0
}

loop () {
    while true
    do
        sleep $KSM_MONITOR_INTERVAL
        adjust
    done
}

loop
-------------- next part --------------
#!/bin/bash
#
# Copyright 2009 Red Hat, Inc. and/or its affiliates.
# Released under the GPL
#
# ksmtuned     Kernel Samepage Merging Tuning Daemon
#
# chkconfig: - 85 15
# description: The Kernel Samepage Merging control Daemon is a simple script  \
#	       that controls whether (and with what vigor) should ksm search  \
#              duplicated pages.
# processname: ksmd
# config: /etc/ksmd.conf
# pidfile: /var/run/ksmd.pid
#
### BEGIN INIT INFO
# Provides: ksmd
# Required-Start:
# Required-Stop:
# Should-Start:
# Short-Description: tune the speed of ksm
# Description: The Kernel Samepage Merging control Daemon is a simple script
#   that controls whether (and with what vigor) should ksm search duplicated
#   memory pages.
#   needs testing and ironing. contact danken at redhat.com if something breaks.
### END INIT INFO

. /etc/rc.d/init.d/functions

prog=ksmtune
pidfile=${PIDFILE-/var/run/ksmtune.pid}
RETVAL=0

start() {
    echo -n $"Starting $prog: "
    daemon --pidfile=${pidfile} $prog
    RETVAL=$?
    echo
    return $RETVAL
}

stop() {
    echo -n $"Stopping $prog: "
    killproc -p ${pidfile}
    RETVAL=$?
    echo
}

signal () {
    local pid
    pid=`cat ${pidfile}`
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
        pkill -P $pid sleep
        RETVAL=$?
    fi
}

case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  status)
        status -p ${pidfile} $prog
	RETVAL=$?
	;;
  restart)
	stop
	start
	;;
  signal)
	signal
	;;
  *)
	echo $"Usage: $prog {start|stop|restart|status|signal|help}"
	RETVAL=3
esac

exit $RETVAL


More information about the virt mailing list