diff --git a/ksm.init b/ksm.init index 703286b..9b57587 100644 --- a/ksm.init +++ b/ksm.init @@ -76,11 +76,10 @@ case "$1" in stop start ;; - signal) - signal - ;; + condrestart) + ;; *) - echo $"Usage: $prog {start|stop|restart|status|help}" + echo $"Usage: $prog {start|stop|restart|condrestart|status|help}" RETVAL=3 esac diff --git a/ksmtuned b/ksmtuned new file mode 100644 index 0000000..f72859f --- /dev/null +++ b/ksmtuned @@ -0,0 +1,120 @@ +#!/bin/bash +# +# Copyright 2009 Red Hat, Inc. and/or its affiliates. +# Released under the GPL +# +# Author: Dan Kenigsberg +# +# ksmtuned - a simple script that controls whether (and with what vigor) ksm +# should search for 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@redhat.com if something breaks. + +if [ -f /etc/ksmtuned.conf ]; then + . /etc/ksmtuned.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 () { + 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_millisecs + echo 1 > /sys/kernel/mm/ksm/run + ;; + esac +} + +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_npages() { + 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_npages $KSM_NPAGES_BOOST` + [ -n "$DEBUG" ] && echo "$free < $thres, boost" + else + npages=`increase_npages $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 +} + +PIDFILE=${PIDFILE-/var/run/ksmtune.pid} +if touch "$PIDFILE"; then + loop & + echo $! > "$PIDFILE" +fi diff --git a/ksmtuned.conf b/ksmtuned.conf new file mode 100644 index 0000000..87b9178 --- /dev/null +++ b/ksmtuned.conf @@ -0,0 +1,16 @@ +# Configuration file for ksmtuned. + +# How long ksmtuned should sleep between tuning adjustments +# KSM_MONITOR_INTERVAL=60 + +# Millisecond sleep between ksm scans for 16Gb server. +# Smaller servers sleep more, bigger sleep less. +# KSM_SLEEP_MSEC=10 + +# KSM_NPAGES_BOOST=300 +# KSM_NPAGES_DECAY=-50 +# KSM_NPAGES_MIN=64 +# KSM_NPAGES_MAX=1250 + +# KSM_THRES_COEF=20 +# KSM_THRES_CONST=2048 diff --git a/ksmtuned.init b/ksmtuned.init new file mode 100644 index 0000000..205531a --- /dev/null +++ b/ksmtuned.init @@ -0,0 +1,83 @@ +#!/bin/bash +# +# ksmtuned Kernel Samepage Merging (KSM) Tuning Daemon +# +# Author: Dan Kenigsberg +# +# Copyright 2009 Red Hat, Inc. and/or its affiliates. +# Released under the GPL +# +# chkconfig: - 85 15 +# description: The KSM tuning daemon controls whether (and with what vigor) \ +# ksm should ksm search duplicated pages. +# processname: ksmtuned +# config: /etc/ksmtuned.conf +# pidfile: /var/run/ksmtuned.pid +# +### BEGIN INIT INFO +# Provides: ksmtuned +# 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@redhat.com if something breaks. +### END INIT INFO + +. /etc/rc.d/init.d/functions + +prog=ksmtuned +ksmtuned=/usr/sbin/ksmtuned +pidfile=${PIDFILE-/var/run/ksmtune.pid} +RETVAL=0 + +start() { + echo -n $"Starting $prog: " + daemon --pidfile=${pidfile} $ksmtuned + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog +} + +stop() { + echo -n $"Stopping $prog: " + killproc -p ${pidfile} + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog +} + +restart() { + stop + start +} + +condrestart() { + [ -e /var/lock/subsys/$prog ] && restart || : +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status -p ${pidfile} $prog + RETVAL=$? + ;; + restart) + restart + ;; + condrestart) + condrestart + ;; + *) + echo $"Usage: $prog {start|stop|restart|condrestart|status|help}" + RETVAL=3 +esac + +exit $RETVAL diff --git a/qemu.spec b/qemu.spec index 9c3ffc2..705a7c2 100644 --- a/qemu.spec +++ b/qemu.spec @@ -3,7 +3,7 @@ Summary: QEMU is a FAST! processor emulator Name: qemu Version: 0.10.92 -Release: 2%{?dist} +Release: 3%{?dist} # Epoch because we pushed a qemu-1.0 package Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD @@ -19,9 +19,12 @@ Source2: kvm.modules # Creates /dev/kvm Source3: 80-kvm.rules -# KSM control script +# KSM control scripts Source4: ksm.init Source5: ksm.sysconfig +Source6: ksmtuned.init +Source7: ksmtuned +Source8: ksmtuned.conf # Not upstream, why? Patch01: qemu-bios-bigger-roms.patch @@ -100,6 +103,9 @@ This package provides the command line tool for manipulating disk images %package common Summary: QEMU common files needed by all QEMU targets Group: Development/Tools +Requires(post): /sbin/chkconfig +Requires(preun): /sbin/service /sbin/chkconfig +Requires(postun): /sbin/service %description common QEMU is a generic and open source processor emulator which achieves a good emulation speed by using dynamic translation. @@ -300,9 +306,13 @@ make V=1 %{?_smp_mflags} $buildldflags %install rm -rf $RPM_BUILD_ROOT -install -D -p -m 0755 %{SOURCE4} $RPM_BUILD_ROOT%{_sysconfdir}/rc.d/init.d/ksm +install -D -p -m 0755 %{SOURCE4} $RPM_BUILD_ROOT%{_initddir}/ksm install -D -p -m 0644 %{SOURCE5} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/ksm +install -D -p -m 0755 %{SOURCE6} $RPM_BUILD_ROOT%{_initddir}/rc.d/init.d/ksmtuned +install -D -p -m 0755 %{SOURCE7} $RPM_BUILD_ROOT%{_sbindir}/ksmtuned +install -D -p -m 0644 %{SOURCE8} $RPM_BUILD_ROOT%{_sysconfdir}/ksmtuned.conf + %ifarch %{ix86} x86_64 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/modules mkdir -p $RPM_BUILD_ROOT%{_bindir}/ @@ -324,7 +334,7 @@ make prefix="${RPM_BUILD_ROOT}%{_prefix}" \ docdir="${RPM_BUILD_ROOT}%{_docdir}/%{name}-%{version}" \ datadir="${RPM_BUILD_ROOT}%{_datadir}/%{name}" install chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man1/* -install -D -p -m 0755 %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/rc.d/init.d/qemu +install -D -p -m 0755 %{SOURCE1} $RPM_BUILD_ROOT%{_initddir}/qemu install -D -p -m 0644 -t ${RPM_BUILD_ROOT}%{qemudocdir} Changelog README TODO COPYING COPYING.LIB LICENSE install -D -p -m 0644 qemu.sasl $RPM_BUILD_ROOT%{_sysconfdir}/sasl2/qemu.conf @@ -366,6 +376,30 @@ rm -rf $RPM_BUILD_ROOT sh %{_sysconfdir}/sysconfig/modules/kvm.modules %endif +%post common +getent group kvm >/dev/null || groupadd -g 36 -r kvm +getent group qemu >/dev/null || groupadd -g 107 -r qemu +getent passwd qemu >/dev/null || \ + useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ + -c "qemu user" qemu + +/sbin/chkconfig --add ksm +/sbin/chkconfig --add ksmtuned + +%preun common +if [ $1 -eq 0 ]; then + /sbin/service ksmtuned stop &>/dev/null || : + /sbin/chkconfig --del ksmtuned + /sbin/service ksm stop &>/dev/null || : + /sbin/chkconfig --del ksm +fi + +%postun common +if [ $1 -ge 1 ]; then + /sbin/service ksm condrestart &>/dev/null || : + /sbin/service ksmtuned condrestart &>/dev/null || : +fi + %post user /sbin/chkconfig --add qemu @@ -380,13 +414,6 @@ if [ $1 -ge 1 ]; then /sbin/service qemu condrestart &>/dev/null || : fi -%post common -getent group kvm >/dev/null || groupadd -g 36 -r kvm -getent group qemu >/dev/null || groupadd -g 107 -r qemu -getent passwd qemu >/dev/null || \ - useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ - -c "qemu user" qemu - %files %defattr(-,root,root) @@ -409,11 +436,14 @@ getent passwd qemu >/dev/null || \ %{_mandir}/man8/qemu-nbd.8* %{_bindir}/qemu-nbd %config(noreplace) %{_sysconfdir}/sasl2/qemu.conf -%{_sysconfdir}/rc.d/init.d/ksm +%{_initddir}/ksm %config(noreplace) %{_sysconfdir}/sysconfig/ksm +%{_initddir}/ksmtuned +%{_sbindir}/ksmtuned +%config(noreplace) %{_sysconfdir}/ksmtuned.conf %files user %defattr(-,root,root) -%{_sysconfdir}/rc.d/init.d/qemu +%{_initddir}/qemu %{_bindir}/qemu-alpha %{_bindir}/qemu-arm %{_bindir}/qemu-armeb @@ -496,6 +526,10 @@ getent passwd qemu >/dev/null || \ %{_mandir}/man1/qemu-img.1* %changelog +* Wed Sep 16 2009 Mark McLoughlin - 2:0.10.92-3 +- Add ksmtuned, also from Dan Kenigsberg +- Use %_initddir macro + * Wed Sep 16 2009 Mark McLoughlin - 2:0.10.92-2 - Add ksm control script from Dan Kenigsberg