Files
mckernel/docs/operators.rst
Masamichi Takagi e17e86840b docs: switch to https://ihkmckernel.readthedocs.io and add contents
Change-Id: I9515034ac372dbe554e1010f646b382c5dc94458
2020-08-19 12:44:03 +09:00

1072 lines
39 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

.. sectnum::
:suffix: .
:depth: 3
This document will explain how to operate system with McKernel.
Installation
============
See `Quick Guide -- Installation <quick.html#installation>`__.
.. include:: uti.rst
Boot and Shut-down
=========================
Related files
-------------
In the followings, the install directory of IHK/McKernel is shown as ``<install>`` .
The kernel modules and their locations are as follows.
+---------------------------+------------------------------------+
| <install>/kmod/ihk.ko | IHK-master core |
+---------------------------+------------------------------------+
| |ihk-smp| | IHK-master driver |
| | |
+---------------------------+------------------------------------+
| |mcctrl| | Delegator module |
| | |
+---------------------------+------------------------------------+
| |mckernel.img| | Kernel Image |
| | |
+---------------------------+------------------------------------+
.. |mckernel.img| replace:: <install>/smp-x86/kernel/mckernel.img
.. |mcctrl| replace:: <install>/kmod/mcctrl.ko
.. |ihk-smp| replace:: <install>/kmod/ihk-smp-x86.ko
The commands and daemons for operation and their locations are as follows.
+---------------------------+--------------------------------------+
| |mcreboot| | Boot script |
| | |
+---------------------------+--------------------------------------+
| |mcstop| | Shutdown script |
| | |
+---------------------------+--------------------------------------+
| <install>/bin/mcexec | Process invocation command |
+---------------------------+--------------------------------------+
| <install>/bin/eclair | Kernel dump analysis tool |
+---------------------------+--------------------------------------+
| |vmcore2mckdump| | Kernel dump format conversion tool |
+---------------------------+--------------------------------------+
.. |mcreboot| replace:: <install>/sbin/mcreboot.sh
.. |mcstop| replace:: <install>/sbin/mcstop+release.sh
.. |vmcore2mckdump| replace:: <install>/bin/vmcore2mckdump
以下、関連コマンドおよび関連関数のインターフェイスを説明する。
インターフェイス
----------------
カーネル引数
~~~~~~~~~~~~
McKernelのカーネル引数を表 :numref:`tab-kargs` に示す。
.. _tab-kargs:
.. table:: McKernelのカーネル引数
+-------------+-------------------------------------------------------+
| hidos | IKCを有効にする。 |
+-------------+-------------------------------------------------------+
| |dlv| | | Linuxのpanicハンドラ経由でダンプを行った場合の、ダ |
| | | ンプ対象とするメモリ領域の種類を<level>に設定する。 |
| | | 設定可能な値は以下の通り。 |
| | |
| | .. list-table:: |
| | |
| | * - 0 |
| | - IHKがMcKernelに割り当てたメモリ領域を出力する |
| | * - 24 |
| | - カーネルが使用しているメモリ領域を出力する |
| | |
| | 指定がなかった場合は24が用いられる。 |
+-------------+-------------------------------------------------------+
| |allow| | | McKernelに割り当てられたCPU数より大きい数のスレッド |
| | | またはプロセスの生成を許可する。この引数が指定され |
| | | ない場合に、CPU数より大きい数のスレッドまたはプロセ |
| | | スをclone(), fork(), vfork()などで生成しようとする |
| | | と、当該システムコールがEINVALエラーを返す。 |
+-------------+-------------------------------------------------------+
.. |dlv| replace:: dump_level=<level>
.. |allow| replace:: allow_oversubscribe
ブートスクリプト
~~~~~~~~~~~~~~~~
書式
""""
.. code-block:: bash
mcreboot.sh -c <cpulist> -r <ikcmap> -m <memlist> -f <facility> -o <chownopt> -i <mon_interval> -k <redirct_kmsg> -q <irq> -t -d <dump_level> -O
オプション
^^^^^^^^^^
+-------------+-------------------------------------------------------+
| |opt-c| | | McKernelに割り当てるCPUのリストを指定する。フォー |
| | | マットは以下の通り。 |
| | | <CPU logical id>,<CPU logical id>...または |
| | | <CPU logical id>-<CPU logical id>,<CPU logical id> |
| | | -<CPU logical id>...または両者の混合。 |
+-------------+-------------------------------------------------------+
| |opt-r| | | McKernelのCPUがIKCメッセージを送るLinux |
| | | CPUを指定する。フォーマットは以下の通り。 |
| | | <CPU list>:<CPU id>+<CPU list>:<CPU id>... |
| | | <CPU list>のフォーマットは-cオプションにおけるもの |
| | | と同じである。 |
| | | 各<CPU list>:<CPU id>は<CPU list>で示されるMcKernel |
| | | のCPUが<CPU logical id>で示されるLinuxのCPUにIKC |
| | | メッセージを送信することを意味する。 |
+-------------+-------------------------------------------------------+
| |opt-m| | | McKernelに割り当てるメモリ領域を指定する。フォーマッ|
| | | トは以下の通り。 |
| | | <size>@<NUMA-id>, <size>@<NUMA-id>... |
+-------------+-------------------------------------------------------+
| |opt-f| | | ihkmondが使用するsyslogプロトコルのfacilityを指定す |
| | | る。デフォルトはLOG_LOCAL6。 |
+-------------+-------------------------------------------------------+
| |opt-o| | | IHKのデバイスファイル(/dev/mcd*, /dev/mcos*)のオー |
| | | ナーとグループの値を<user>[:<group>]の形式で指定す |
| | | る。デフォルトはmcreboot.shを実行したユーザ。 |
+-------------+-------------------------------------------------------+
| |opt-i| | | ihkmondがハングアップ検知のためにOS状態を確認する時 |
| | | 間間隔を秒単位で指定する。-1が指定された場合はハン |
| | | グアップ検知を行わない。指定がない場合はハングアッ |
| | | プ検知を行わない。 |
+-------------+-------------------------------------------------------+
| |opt-k| | | カーネルメッセージの/dev/logへのリダイレクト有無を |
| | | 指定する。0が指定された場合はリダイレクトを行わず、 |
| | | 0以外が指定された場合はリダイレクトを行う。指定がな |
| | | い場合はリダイレクトを行わない。 |
+-------------+-------------------------------------------------------+
| -q <irq> | | IHKが使用するIRQ番号を指定する。指定がない場合は |
| | | 64-255の範囲で空いているものを使用する。 |
+-------------+-------------------------------------------------------+
| -t | | x86_64アーキテクチャのみTurbo |
| | | Boostをオンにする。デフォルトはオフ。 |
+-------------+-------------------------------------------------------+
| -d <level> | | Linuxのpanicハンドラ経由でダンプを行った場合の、ダ |
| | | ンプ対象とするメモリ領域の種類を<level>に設定する。 |
| | | 設定可能な値は以下の通り。 |
| | |
| | .. list-table:: |
| | |
| | * - 0 |
| | - IHKがMcKernelに割り当てたメモリ領域を出力する |
| | * - 24 |
| | - カーネルが使用しているメモリ領域を出力する |
| | |
| | 指定がなかった場合は24が用いられる。 |
+-------------+-------------------------------------------------------+
| -O | | McKernelに割り当てられたCPU数より大きい数のスレッド |
| | | またはプロセスの生成を許可する。指定がない場合は許可|
| | | しない。すなわち、CPU数より大きい数のスレッドまたは |
| | | プロセスを生成しようとするとエラーとなる。 |
+-------------+-------------------------------------------------------+
.. |opt-c| replace:: -c <list>
.. |opt-r| replace:: -r <map>
.. |opt-m| replace:: -m <list>
.. |opt-f| replace:: -f <facility>
.. |opt-o| replace:: -o <chownopt>
.. |opt-i| replace:: -i <interval>
.. |opt-k| replace:: -k <redirect_kmsg>
説明
^^^^
McKernel関連カーネルモジュールをinsmodし、<cpulist>で指定されたCPUと<memlist>で指定されたメモリ領域からなるパーティションを作成し、IKC
mapを<ikcmap>に設定し、前記パーティションにMcKernelをブートする。
戻り値
^^^^^^
+-------------+----------------------------------------------+
| 0 | 正常終了 |
+-------------+----------------------------------------------+
| 0以外 | エラー |
+-------------+----------------------------------------------+
シャットダウンスクリプト
~~~~~~~~~~~~~~~~~~~~~~~~
.. _書式-1:
書式
""""
.. code-block:: bash
mcstop+release.sh
.. _オプション-1:
オプション
^^^^^^^^^^
なし
.. _説明-1:
説明
^^^^
McKernelをシャットダウンし、McKernel用パーティションを削除し、関連カーネルモジュールをrmmodする。
.. _戻り値-1:
戻り値
^^^^^^
+-------------+-------------------------------------------------+
| 0 | 正常終了 |
+-------------+-------------------------------------------------+
| 0以外 | エラー |
+-------------+-------------------------------------------------+
プロセス起動コマンド
~~~~~~~~~~~~~~~~~~~~
.. include:: spec/mcexec.rst
ダンプ解析コマンド
~~~~~~~~~~~~~~~~~~
.. include:: spec/eclair.rst
ダンプ形式変換コマンド
~~~~~~~~~~~~~~~~~~~~~~
.. include:: spec/vmcore2mckdump.rst
ブート手順
----------
mcreboot.shを用いてブート手順を説明する。
スクリプトは以下の通り。
.. code-block:: bash
:linenos:
#!/bin/bash
# IHK SMP-x86 example boot script.
# author: Balazs Gerofi <bgerofi@riken.jp>
# Copyright (C) 2014 RIKEN AICS
#
# This is an example script for loading IHK, configuring a partition and
# booting McKernel on it. Unless specific CPUs and memory are requested,
# the script reserves half of the CPU cores and 512MB of RAM from
# NUMA node 0 when IHK is loaded for the first time.
# Otherwise, it destroys the current McKernel instance and reboots it using
# the same set of resources as it used previously.
# Note that the script does not output anything unless an error occurs.
prefix="/home/takagi/project/os/install"
BINDIR="${prefix}/bin"
SBINDIR="${prefix}/sbin"
ETCDIR=/home/takagi/project/os/install/etc
KMODDIR="${prefix}/kmod"
KERNDIR="${prefix}/smp-x86/kernel"
ENABLE_MCOVERLAYFS="yes"
mem="512M@0"
cpus=""
ikc_map=""
if [ "${BASH_VERSINFO[0]}" -lt 4 ]; then
echo "You need at least bash-4.0 to run this script." >&2
exit 1
fi
redirect_kmsg=0
mon_interval="-1"
DUMP_LEVEL=24
facility="LOG_LOCAL6"
chown_option=`logname 2> /dev/null`
if [ "`systemctl status irqbalance_mck.service 2> /dev/null |grep -E 'Active: active'`"\
!= "" -o "`systemctl status irqbalance.service 2> /dev/null |grep -E 'Active: active'`"\
!= "" ]; then
irqbalance_used="yes"
else
irqbalance_used="no"
fi
turbo=""
ihk_irq=""
while getopts :tk:c:m:o:f:r:q:i:d: OPT
do
case ${OPT} in
f) facility=${OPTARG}
;;
o) chown_option=${OPTARG}
;;
k) redirect_kmsg=${OPTARG}
;;
c) cpus=${OPTARG}
;;
m) mem=${OPTARG}
;;
r) ikc_map=${OPTARG}
;;
q) ihk_irq=${OPTARG}
;;
t) turbo="turbo"
;;
d) DUMP_LEVEL=${OPTARG}
;;
i) mon_interval=${OPTARG}
;;
*) echo "invalid option -${OPT}" >&2
exit 1
esac
done
# Start ihkmond
pid=`pidof ihkmond`
if [ "${pid}" != "" ]; then
sudo kill -9 ${pid} > /dev/null 2> /dev/null
fi
if [ "${redirect_kmsg}" != "0" -o "${mon_interval}" != "-1" ]; then
${SBINDIR}/ihkmond -f ${facility} -k ${redirect_kmsg} -i ${mon_interval}
fi
#
# Revert any state that has been initialized before the error occured.
#
error_exit() {
local status=$1
case $status in
mcos_sys_mounted)
if [ "$enable_mcoverlay" == "yes" ]; then
umount /tmp/mcos/mcos0_sys
fi
;&
mcos_proc_mounted)
if [ "$enable_mcoverlay" == "yes" ]; then
umount /tmp/mcos/mcos0_proc
fi
;&
mcoverlayfs_loaded)
if [ "$enable_mcoverlay" == "yes" ]; then
rmmod mcoverlay 2>/dev/null
fi
;&
linux_proc_bind_mounted)
if [ "$enable_mcoverlay" == "yes" ]; then
umount /tmp/mcos/linux_proc
fi
;&
tmp_mcos_mounted)
if [ "$enable_mcoverlay" == "yes" ]; then
umount /tmp/mcos
fi
;&
tmp_mcos_created)
if [ "$enable_mcoverlay" == "yes" ]; then
rm -rf /tmp/mcos
fi
;&
os_created)
# Destroy all LWK instances
if ls /dev/mcos* 1>/dev/null 2>&1; then
for i in /dev/mcos*; do
ind=`echo $i|cut -c10-`;
if ! ${SBINDIR}/ihkconfig 0 destroy $ind; then
echo "warning: failed to destroy LWK instance $ind" >&2
fi
done
fi
;&
mcctrl_loaded)
rmmod mcctrl 2>/dev/null || echo "warning: failed to remove mcctrl" >&2
;&
cpus_reserved)
cpus=`${SBINDIR}/ihkconfig 0 query cpu`
if [ "${cpus}" != "" ]; then
if ! ${SBINDIR}/ihkconfig 0 release cpu $cpus > /dev/null; then
echo "warning: failed to release CPUs" >&2
fi
fi
;&
mem_reserved)
mem=`${SBINDIR}/ihkconfig 0 query mem`
if [ "${mem}" != "" ]; then
if ! ${SBINDIR}/ihkconfig 0 release mem $mem > /dev/null; then
echo "warning: failed to release memory" >&2
fi
fi
;&
ihk_smp_loaded)
rmmod ihk_smp_x86 2>/dev/null || echo "warning: failed to remove ihk_smp_x86" >&2
;&
ihk_loaded)
rmmod ihk 2>/dev/null || echo "warning: failed to remove ihk" >&2
;&
irqbalance_stopped)
if [ "`systemctl status irqbalance_mck.service 2> /dev/null |'\
'grep -E 'Active: active'`" != "" ]; then
if ! systemctl stop irqbalance_mck.service 2>/dev/null; then
echo "warning: failed to stop irqbalance_mck" >&2
fi
if ! systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null; then
echo "warning: failed to disable irqbalance_mck" >&2
fi
if ! etcdir=/home/takagi/project/os/install/etc perl -e \
'$etcdir=$ENV{'etcdir'}; @files = grep { -f } glob "$etcdir/proc/irq/*/smp_affinity";'\
' foreach $file (@files) { $dest = substr($file, length($etcdir));'\
' if(0) {print "cp $file $dest\n";} system("cp $file $dest 2>/dev/null"); }'; then
echo "warning: failed to restore /proc/irq/*/smp_affinity" >&2
fi
if ! systemctl start irqbalance.service; then
echo "warning: failed to start irqbalance" >&2;
fi
fi
;&
initial)
# Nothing more to revert
;;
esac
exit 1
}
ihk_ikc_irq_core=0
release=`uname -r`
major=`echo ${release} | sed -e 's/^\([0-9]*\).*/\1/'`
minor=`echo ${release} | sed -e 's/^[0-9]*.\([0-9]*\).*/\1/'`
patch=`echo ${release} | sed -e 's/^[0-9]*.[0-9]*.\([0-9]*\).*/\1/'`
linux_version_code=`expr \( ${major} \* 65536 \) + \( ${minor} \* 256 \) + ${patch}`
rhel_release=`echo ${release} | sed -e 's/^[0-9]*.[0-9]*.[0-9]*-\([0-9]*\).*/\1/'`
if [ "${release}" == "${rhel_release}" ]; then
rhel_release="";
fi
enable_mcoverlay="no"
if [ "${ENABLE_MCOVERLAYFS}" == "yes" ]; then
if [ "${rhel_release}" == "" ]; then
if [ ${linux_version_code} -ge 262144 -a ${linux_version_code} -lt 262400 ]; then
enable_mcoverlay="yes"
fi
if [ ${linux_version_code} -ge 263680 -a ${linux_version_code} -lt 263936 ]; then
enable_mcoverlay="yes"
fi
else
if [ ${linux_version_code} -eq 199168 -a ${rhel_release} -ge 327 -a ${rhel_release} -le 693 ]; then
enable_mcoverlay="yes"
fi
if [ ${linux_version_code} -ge 262144 -a ${linux_version_code} -lt 262400 ]; then
enable_mcoverlay="yes"
fi
fi
fi
# Figure out CPUs if not requested by user
if [ "$cpus" == "" ]; then
# Get the number of CPUs on NUMA node 0
nr_cpus=`lscpu --parse | awk -F"," '{if ($4 == 0) print $4}' | wc -l`
# Use the second half of the cores
let nr_cpus="$nr_cpus / 2"
cpus=`lscpu --parse | awk -F"," '{if ($4 == 0) print $1}' | tail -n $nr_cpus |'\
' xargs echo -n | sed 's/ /,/g'`
if [ "$cpus" == "" ]; then
echo "error: no available CPUs on NUMA node 0?" >&2
exit 1
fi
fi
# Remove mcoverlay if loaded
if [ "$enable_mcoverlay" == "yes" ]; then
if grep mcoverlay /proc/modules &>/dev/null; then
if [ "`cat /proc/mounts | grep /tmp/mcos/mcos0_sys`" != "" ]; \
then umount -l /tmp/mcos/mcos0_sys; fi
if [ "`cat /proc/mounts | grep /tmp/mcos/mcos0_proc`" != "" ]; \
then umount -l /tmp/mcos/mcos0_proc; fi
if [ "`cat /proc/mounts | grep /tmp/mcos/linux_proc`" != "" ]; \
then umount -l /tmp/mcos/linux_proc; fi
if [ "`cat /proc/mounts | grep /tmp/mcos`" != "" ]; then umount -l /tmp/mcos; fi
if [ -e /tmp/mcos ]; then rm -rf /tmp/mcos; fi
if ! rmmod mcoverlay 2>/dev/null; then
echo "error: removing mcoverlay" >&2
exit 1
fi
fi
fi
# Stop irqbalance
if [ "${irqbalance_used}" == "yes" ]; then
systemctl stop irqbalance_mck.service 2>/dev/null
if ! systemctl stop irqbalance.service 2>/dev/null ; then
echo "error: stopping irqbalance" >&2
exit 1
fi;
if ! etcdir=/home/takagi/project/os/install/etc perl -e \
'use File::Copy qw(copy); $etcdir=$ENV{'etcdir'}; '\
'@files = grep { -f } glob "/proc/irq/*/smp_affinity"; foreach $file (@files) { '\
'$rel = substr($file, 1); $dir=substr($rel, 0, length($rel)-length("/smp_affinity")); '\
'if(0) { print "cp $file $etcdir/$rel\n";} if(system("mkdir -p $etcdir/$dir")){ exit 1;} '\
'if(!copy($file,"$etcdir/$rel")){ exit 1;} }'; then
echo "error: saving /proc/irq/*/smp_affinity" >&2
error_exit "mcos_sys_mounted"
fi;
# Prevent /proc/irq/*/smp_affinity from getting zero after offlining
# McKernel CPUs by using the following algorithm.
# if (smp_affinity & mck_cores) {
# smp_affinity = (mck_cores ^ -1);
# }
ncpus=`lscpu | grep -E '^CPU\(s\):' | awk '{print $2}'`
smp_affinity_mask=`echo $cpus | ncpus=$ncpus perl -e \
'while(<>){@tokens = split /,/;foreach $token (@tokens) '\
'{@nums = split /-/,$token; for($num = $nums[0]; $num <= $nums[$#nums]; $num++) {'\
'$ndx=int($num/32); $mask[$ndx] |= (1<<($num % 32))}}}'\
' $nint32s = int(($ENV{'ncpus'}+31)/32); for($j = $nint32s - 1; $j >= 0; $j--) {'\
' if($j != $nint32s - 1){print ",";}'\
' $nblks = ($j != $nint32s - 1) ? 8 : ($ENV{'ncpus'} % 32 != 0) ? '\
'int((($ENV{'ncpus'} + 3) % 32) / 4) : 8;'\
' for($i = $nblks - 1;$i >= 0;$i--){ printf("%01x",($mask[$j] >> ($i*4)) & 0xf);}}'`
# echo cpus=$cpus ncpus=$ncpus smp_affinity_mask=$smp_affinity_mask
if ! ncpus=$ncpus smp_affinity_mask=$smp_affinity_mask perl -e \
'@dirs = grep { -d } glob "/proc/irq/*"; foreach $dir (@dirs) {'\
' $hit = 0; $affinity_str = `cat $dir/smp_affinity`; chomp $affinity_str;'\
' @int32strs = split /,/, $affinity_str; @int32strs_mask=split /,/, $ENV{'smp_affinity_mask'};'\
' for($i=0;$i <= $#int32strs_mask; $i++) {'\
' $int32strs_inv[$i] = sprintf("%08x",hex($int32strs_mask[$i])^0xffffffff);'\
' if($i == 0) { $len = int((($ENV{'ncpus'}%32)+3)/4); if($len != 0) {'\
' $int32strs_inv[$i] = substr($int32strs_inv[$i], -$len, $len); } } }'\
' $inv = join(",", @int32strs_inv); $nint32s = int(($ENV{'ncpus'}+31)/32);'\
' for($j = $nint32s - 1; $j >= 0; $j--) {'\
' if(hex($int32strs[$nint32s - 1 - $j]) & hex($int32strs_mask[$nint32s - 1 - $j])) {'\
' $hit = 1; }} if($hit == 1) {'\
' $cmd = "echo $inv > $dir/smp_affinity 2>/dev/null"; system $cmd;}}'; then
echo "error: modifying /proc/irq/*/smp_affinity" >&2
error_exit "mcos_sys_mounted"
fi
fi
# Load IHK if not loaded
if ! grep -E 'ihk\s' /proc/modules &>/dev/null; then
if ! taskset -c 0 insmod ${KMODDIR}/ihk.ko 2>/dev/null; then
echo "error: loading ihk" >&2
error_exit "irqbalance_stopped"
fi
fi
# Increase swappiness so that we have better chance to allocate memory for IHK
echo 100 > /proc/sys/vm/swappiness
# Drop Linux caches to free memory
sync && echo 3 > /proc/sys/vm/drop_caches
# Merge free memory areas into large, physically contigous ones
echo 1 > /proc/sys/vm/compact_memory 2>/dev/null
sync
# Load IHK-SMP if not loaded and reserve CPUs and memory
if ! grep ihk_smp_x86 /proc/modules &>/dev/null; then
if [ "$ihk_irq" == "" ]; then
for i in `seq 64 255`; do
if [ ! -d /proc/irq/$i ] && \
[ "`cat /proc/interrupts | grep ":" | awk '{print $1}' | grep -o '[0-9]*' | grep -e '^$i$'`"\
== "" ]; then
ihk_irq=$i
break
fi
done
if [ "$ihk_irq" == "" ]; then
echo "error: no IRQ available" >&2
error_exit "ihk_loaded"
fi
fi
if ! taskset -c 0 insmod ${KMODDIR}/ihk-smp-x86.ko ihk_start_irq=$ihk_irq\
ihk_ikc_irq_core=$ihk_ikc_irq_core 2>/dev/null; then
echo "error: loading ihk-smp-x86" >&2
error_exit "ihk_loaded"
fi
# Offline-reonline RAM (special case for OFP SNC-4 mode)
if [ "`hostname | grep "c[0-9][0-9][0-9][0-9].ofp"`" != "" ] && [ "`cat /sys/devices/system/node/online`" == "0-7" ]; then
for i in 0 1 2 3; do
find /sys/devices/system/node/node$i/memory*/ -name "online" |\
while read f; do
echo 0 > $f 2>&1 > /dev/null;
done
find /sys/devices/system/node/node$i/memory*/ -name "online" |\
while read f; do
echo 1 > $f 2>&1 > /dev/null;
done
done
for i in 4 5 6 7; do
find /sys/devices/system/node/node$i/memory*/ -name "online" |\
while read f; do
echo 0 > $f 2>&1 > /dev/null;
done
find /sys/devices/system/node/node$i/memory*/ -name "online" |\
while read f; do
echo 1 > $f 2>&1 > /dev/null;
done
done
fi
if ! ${SBINDIR}/ihkconfig 0 reserve mem ${mem}; then
echo "error: reserving memory" >&2
error_exit "ihk_smp_loaded"
fi
if ! ${SBINDIR}/ihkconfig 0 reserve cpu ${cpus}; then
echo "error: reserving CPUs" >&2;
error_exit "mem_reserved"
fi
fi
# Load mcctrl if not loaded
if ! grep mcctrl /proc/modules &>/dev/null; then
if ! taskset -c 0 insmod ${KMODDIR}/mcctrl.ko 2>/dev/null; then
echo "error: inserting mcctrl.ko" >&2
error_exit "cpus_reserved"
fi
fi
# Destroy all LWK instances
if ls /dev/mcos* 1>/dev/null 2>&1; then
for i in /dev/mcos*; do
ind=`echo $i|cut -c10-`;
# Retry when conflicting with ihkmond
nretry=0
until ${SBINDIR}/ihkconfig 0 destroy $ind || [ $nretry -lt 4 ]; do
sleep 0.25
nretry=$[ $nretry + 1 ]
done
if [ $nretry -eq 4 ]; then
echo "error: destroying LWK instance $ind failed" >&2
error_exit "mcctrl_loaded"
fi
done
fi
# Create OS instance
if ! ${SBINDIR}/ihkconfig 0 create; then
echo "error: creating OS instance" >&2
error_exit "mcctrl_loaded"
fi
# Assign CPUs
if ! ${SBINDIR}/ihkosctl 0 assign cpu ${cpus}; then
echo "error: assign CPUs" >&2
error_exit "os_created"
fi
if [ "$ikc_map" != "" ]; then
# Specify IKC map
if ! ${SBINDIR}/ihkosctl 0 set ikc_map ${ikc_map}; then
echo "error: assign CPUs" >&2
error_exit "os_created"
fi
fi
# Assign memory
if ! ${SBINDIR}/ihkosctl 0 assign mem ${mem}; then
echo "error: assign memory" >&2
error_exit "os_created"
fi
# Load kernel image
if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then
echo "error: loading kernel image: ${KERNDIR}/mckernel.img" >&2
error_exit "os_created"
fi
# Set kernel arguments
if ! ${SBINDIR}/ihkosctl 0 kargs "hidos $turbo dump_level=${DUMP_LEVEL}"; then
echo "error: setting kernel arguments" >&2
error_exit "os_created"
fi
# Boot OS instance
if ! ${SBINDIR}/ihkosctl 0 boot; then
echo "error: booting" >&2
error_exit "os_created"
fi
# Set device file ownership
if ! chown ${chown_option} /dev/mcd* /dev/mcos*; then
echo "warning: failed to chown device files" >&2
fi
# Overlay /proc, /sys with McKernel specific contents
if [ "$enable_mcoverlay" == "yes" ]; then
if [ ! -e /tmp/mcos ]; then
mkdir -p /tmp/mcos;
fi
if ! mount -t tmpfs tmpfs /tmp/mcos; then
echo "error: mount /tmp/mcos" >&2
error_exit "tmp_mcos_created"
fi
if [ ! -e /tmp/mcos/linux_proc ]; then
mkdir -p /tmp/mcos/linux_proc;
fi
if ! mount --bind /proc /tmp/mcos/linux_proc; then
echo "error: mount /tmp/mcos/linux_proc" >&2
error_exit "tmp_mcos_mounted"
fi
if ! taskset -c 0 insmod ${KMODDIR}/mcoverlay.ko 2>/dev/null; then
echo "error: inserting mcoverlay.ko" >&2
error_exit "linux_proc_bind_mounted"
fi
while [ ! -e /proc/mcos0 ]
do
sleep 0.1
done
if [ ! -e /tmp/mcos/mcos0_proc ]; then
mkdir -p /tmp/mcos/mcos0_proc;
fi
if [ ! -e /tmp/mcos/mcos0_proc_upper ]; then
mkdir -p /tmp/mcos/mcos0_proc_upper;
fi
if [ ! -e /tmp/mcos/mcos0_proc_work ]; then
mkdir -p /tmp/mcos/mcos0_proc_work;
fi
if ! mount -t mcoverlay mcoverlay -o\
lowerdir=/proc/mcos0:/proc,upperdir=/tmp/mcos/mcos0_proc_upper,\
workdir=/tmp/mcos/mcos0_proc_work,nocopyupw,nofscheck /tmp/mcos/mcos0_proc; then
echo "error: mounting /tmp/mcos/mcos0_proc" >&2
error_exit "mcoverlayfs_loaded"
fi
# TODO: How de we revert this in case of failure??
mount --make-rprivate /proc
while [ ! -e /sys/devices/virtual/mcos/mcos0/sys/setup_complete ]
do
sleep 0.1
done
if [ ! -e /tmp/mcos/mcos0_sys ]; then
mkdir -p /tmp/mcos/mcos0_sys;
fi
if [ ! -e /tmp/mcos/mcos0_sys_upper ]; then
mkdir -p /tmp/mcos/mcos0_sys_upper;
fi
if [ ! -e /tmp/mcos/mcos0_sys_work ]; then
mkdir -p /tmp/mcos/mcos0_sys_work;
fi
if ! mount -t mcoverlay mcoverlay -o\
lowerdir=/sys/devices/virtual/mcos/mcos0/sys:/sys,upperdir=/tmp/mcos/mcos0_sys_upper,\
workdir=/tmp/mcos/mcos0_sys_work,nocopyupw,nofscheck /tmp/mcos/mcos0_sys; then
echo "error: mount /tmp/mcos/mcos0_sys" >&2
error_exit "mcos_proc_mounted"
fi
# TODO: How de we revert this in case of failure??
mount --make-rprivate /sys
touch /tmp/mcos/mcos0_proc/mckernel
rm -rf /tmp/mcos/mcos0_sys/setup_complete
# Hide NUMA related files which are outside the LWK partition
for cpuid in \
`find /sys/devices/system/cpu/* -maxdepth 0 -name "cpu[0123456789]*" -printf "%f "`; do
if [ ! -e "/sys/devices/virtual/mcos/mcos0/sys/devices/system/cpu/$cpuid" ]; then
rm -rf /tmp/mcos/mcos0_sys/devices/system/cpu/$cpuid
rm -rf /tmp/mcos/mcos0_sys/bus/cpu/devices/$cpuid
rm -rf /tmp/mcos/mcos0_sys/bus/cpu/drivers/processor/$cpuid
else
for nodeid in \
`find /sys/devices/system/cpu/$cpuid/* -maxdepth 0 -name "node[0123456789]*" -printf "%f "`; do
if [ ! -e \
"/sys/devices/virtual/mcos/mcos0/sys/devices/system/cpu/$cpuid/$nodeid" ]; then
rm -f \
/tmp/mcos/mcos0_sys/devices/system/cpu/$cpuid/$nodeid
fi
done
fi
done
for nodeid in \
`find /sys/devices/system/node/* -maxdepth 0 -name "node[0123456789]*" -printf "%f "`; do
if [ ! -e "/sys/devices/virtual/mcos/mcos0/sys/devices/system/node/$nodeid" ]; \
then
rm -rf /tmp/mcos/mcos0_sys/devices/system/node/$nodeid/*
rm -rf /tmp/mcos/mcos0_sys/bus/node/devices/$nodeid
else
# Delete non-existent symlinks
for cpuid in \
`find /sys/devices/system/node/$nodeid/* -maxdepth 0 -name "cpu[0123456789]*" -printf "%f "`; do
if [ ! -e \
"/sys/devices/virtual/mcos/mcos0/sys/devices/system/node/$nodeid/$cpuid" ]; then
rm -f \
/tmp/mcos/mcos0_sys/devices/system/node/$nodeid/$cpuid
fi
done
rm -f /tmp/mcos/mcos0_sys/devices/system/node/$nodeid/memory*
fi
done
rm -f /tmp/mcos/mcos0_sys/devices/system/node/has_*
for cpuid in \
`find /sys/bus/cpu/devices/* -maxdepth 0 -name "cpu[0123456789]*" -printf "%f "`; do
if [ ! -e "/sys/devices/virtual/mcos/mcos0/sys/bus/cpu/devices/$cpuid" ]; then
rm -rf /tmp/mcos/mcos0_sys/bus/cpu/devices/$cpuid
fi
done
fi
# Start irqbalance with CPUs and IRQ for McKernel banned
if [ "${irqbalance_used}" == "yes" ]; then
banirq=`cat /proc/interrupts| \
perl -e 'while(<>) { if(/^\s*(\d+).*IHK\-SMP\s*$/) {print $1;}}'`
sed "s/%mask%/$smp_affinity_mask/g" $ETCDIR/irqbalance_mck.in | \
sed "s/%banirq%/$banirq/g" > /tmp/irqbalance_mck
systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null
if ! systemctl link $ETCDIR/irqbalance_mck.service >/dev/null 2>/dev/null; then
echo "error: linking irqbalance_mck" >&2
error_exit "mcos_sys_mounted"
fi
if ! systemctl start irqbalance_mck.service 2>/dev/null ; then
echo "error: starting irqbalance_mck" >&2
error_exit "mcos_sys_mounted"
fi
# echo cpus=$cpus ncpus=$ncpus banirq=$banirq
fi
手順は以下の通り。
#. ihkmondを起動する。ihkmondは任意のタイミングで起動してよい。これは、ihkmondはOSインスタンスの作成を検知して動作を開始するためである。83行目
#. Linuxのカーネルバージョンが、mcoverlayfsが動作するものであるかを確認する。200216行目
#. irqbalanceを停止する。251257行目
#. /proc/irq/[n]/affinityの設定を保存した上でMcKernel
CPUを担当から外す。担当CPUが無くなる場合は、全てのLinux
CPUを指定する。269303行目
#. ihk.koをinsmodする。307行目
#. Linuxによるメモリフラグメンテーションを緩和するために以下を実施する。313320行目
#. アクティブでないプロセスを積極的にスワップアウトするように設定する
#. クリーンなページキャッシュを無効化し、またdentriesやinodeのslabオブジェクトのうち可能なものを破棄する
#. 連続する空き領域を結合してより大きな空き領域にまとめる
#. ihk-smp-x86.koをinsmodする。340行目ihk-smp-x86.koは関数をihk.koに登録する。このため、ihk-smp-x86.koはihk.koをinsmodした後にinsmodする必要がある。
#. メモリを予約する。370行目
#. CPUを予約する。374行目
#. McKernelのカーネルモジュールmcctrl.koをinsmodする。382行目mcctrl.koはMcKernelブート時に呼ばれる関数をihk.koに登録する。このため、mcctrl.koのinsmodはihk.koのinsmodの後に、またブートの前に行う必要がある。
#. OSインスタンスを作成する。406行目
#. OSインスタンスにCPUを割り当てる。412行目
#. McKernel CPUのIKCメッセージ送信先のLinux CPUを設定する。419行目
#. OSインスタンスにメモリを割り当てる。426行目
#. カーネルイメージをロードする。432行目
#. カーネル引数をカーネルに渡す。438行目
#. カーネルをブートする。444行目
#. /proc, /sysファイルの準備をする。また、その中でmcoverlayfs.koをinsmodする。mcoverlayfs.koは他モジュールとの依存関係を持たない。454行目から567行目なお、関数インターフェイスでの対応関数はihk_os_create_pseudofs()である。
#. irqbalanceを、Linux
CPUのみを対象とする設定で開始する。569587行目
シャットダウン手順
------------------
mcstop+release.shを用いてシャットダウン手順を説明する。
スクリプトは以下の通り。
.. code-block:: bash
:linenos:
#!/bin/bash
# IHK SMP-x86 example McKernel unload script.
# author: Balazs Gerofi <bgerofi@riken.jp>
# Copyright (C) 2015 RIKEN AICS
#
# This is an example script for destroying McKernel and releasing IHK resources
# Note that the script does no output anything unless an error occurs.
prefix="/home/takagi/project/os/install"
BINDIR="/home/takagi/project/os/install/bin"
SBINDIR="/home/takagi/project/os/install/sbin"
ETCDIR=/home/takagi/project/os/install/etc
KMODDIR="/home/takagi/project/os/install/kmod"
KERNDIR="/home/takagi/project/os/install/smp-x86/kernel"
mem=""
cpus=""
irqbalance_used=""
# No SMP module? Exit.
if ! grep ihk_smp_x86 /proc/modules &>/dev/null; then exit 0; fi
if [ "`systemctl status irqbalance_mck.service 2> /dev/null |grep -E 'Active: active'`" \
!= "" ]; then
irqbalance_used="yes"
if ! systemctl stop irqbalance_mck.service 2>/dev/null; then
echo "warning: failed to stop irqbalance_mck" >&2
fi
if ! systemctl disable irqbalance_mck.service >/dev/null 2>/dev/null; then
echo "warning: failed to disable irqbalance_mck" >&2
fi
fi
# Destroy all LWK instances
if ls /dev/mcos* 1>/dev/null 2>&1; then
for i in /dev/mcos*; do
ind=`echo $i|cut -c10-`;
# Retry when conflicting with ihkmond
nretry=0
until ${SBINDIR}/ihkconfig 0 destroy $ind || [ $nretry -lt 4 ]; do
sleep 0.25
nretry=$[ $nretry + 1 ]
done
if [ $nretry -eq 4 ]; then
echo "error: destroying LWK instance $ind failed" >&2
exit 1
fi
done
fi
# Query IHK-SMP resources and release them
if ! ${SBINDIR}/ihkconfig 0 query cpu > /dev/null; then
echo "error: querying cpus" >&2
exit 1
fi
cpus=`${SBINDIR}/ihkconfig 0 query cpu`
if [ "${cpus}" != "" ]; then
if ! ${SBINDIR}/ihkconfig 0 release cpu $cpus > /dev/null; then
echo "error: releasing CPUs" >&2
exit 1
fi
fi
if ! ${SBINDIR}/ihkconfig 0 query mem > /dev/null; then
echo "error: querying memory" >&2
exit 1
fi
mem=`${SBINDIR}/ihkconfig 0 query mem`
if [ "${mem}" != "" ]; then
if ! ${SBINDIR}/ihkconfig 0 release mem $mem > /dev/null; then
echo "error: releasing memory" >&2
exit 1
fi
fi
# Remove delegator if loaded
if grep mcctrl /proc/modules &>/dev/null; then
if ! rmmod mcctrl 2>/dev/null; then
echo "error: removing mcctrl" >&2
exit 1
fi
fi
# Remove mcoverlay if loaded
if grep mcoverlay /proc/modules &>/dev/null; then
if [ "`cat /proc/mounts | grep /tmp/mcos/mcos0_sys`" != "" ]; \
then umount -l /tmp/mcos/mcos0_sys; fi
if [ "`cat /proc/mounts | grep /tmp/mcos/mcos0_proc`" != "" ]; \
then umount -l /tmp/mcos/mcos0_proc; fi
if [ "`cat /proc/mounts | grep /tmp/mcos/linux_proc`" != "" ]; \
then umount -l /tmp/mcos/linux_proc; fi
if [ "`cat /proc/mounts | grep /tmp/mcos`" != "" ]; then umount -l /tmp/mcos; fi
if [ -e /tmp/mcos ]; then rm -rf /tmp/mcos; fi
if ! rmmod mcoverlay 2>/dev/null; then
echo "warning: failed to remove mcoverlay" >&2
fi
fi
# Remove SMP module
if grep ihk_smp_x86 /proc/modules &>/dev/null; then
if ! rmmod ihk_smp_x86 2>/dev/null; then
echo "error: removing ihk_smp_x86" >&2
exit 1
fi
fi
# Remove core module
if grep -E 'ihk\s' /proc/modules &>/dev/null; then
if ! rmmod ihk 2>/dev/null; then
echo "error: removing ihk" >&2
exit 1
fi
fi
# Stop ihkmond
pid=`pidof ihkmond`
if [ "${pid}" != "" ]; then
sudo kill -9 ${pid} > /dev/null 2> /dev/null
fi
# Start irqbalance with the original settings
if [ "${irqbalance_used}" != "" ]; then
if ! etcdir=/home/takagi/project/os/install/etc perl -e \
'$etcdir=$ENV{'etcdir'}; @files = grep { -f } glob "$etcdir/proc/irq/*/smp_affinity";'\
' foreach $file (@files) { $dest = substr($file, length($etcdir));'\
' if(0) {print "cp $file $dest\n";} system("cp $file $dest 2>/dev/null"); }'; then
echo "warning: failed to restore /proc/irq/*/smp_affinity" >&2
fi
if ! systemctl start irqbalance.service; then
echo "warning: failed to start irqbalance" >&2;
fi
fi
# Set back default swappiness
echo 60 > /proc/sys/vm/swappiness
手順は以下の通り。
#. ブート時にLinux
CPUのみを対象とする設定で開始されたirqbalanceを停止する。2433行目
#. 全てのOSインスタンスを破壊する。OSインスタンスに割り当てられていた資源はIHKがLWKのために予約した状態に移行する。3550行目
#. IHKがLWKのために予約していた資源を開放する。5277行目
#. mcctrl.koをrmmodする。81行目
#. /proc, /sysファイルの準備をする。また、その中でmcoverlayfs.koをrmmodする。87100行目なお、関数インターフェイスでの対応関数はihk_os_destroy_pseudofs()である。
#. ihk-smp-x86.koをrmmodする。104行目
#. ihk.koをrmmodする。112行目
#. ihkmondを停止する。121行目
#. /proc/irq/[n]/affinityの設定をブート時に保存しておいたものに戻し、ブート前の設定でirqbalanceを開始する。124135行目
#. Linuxカーネルのスワップアウト積極度の設定をデフォルトの値に戻す。138行目