Оптимизация сборки ядра FreeBSD

6 января 2010 | Метки:

При сборке ядра, FreeBSD собирает всё имеющееся в /usr/src/sys/modules дерево модулей, вне зависимости от содержимого конфиг-файла ядра, что отрицательно сказывается на общем времени сборки. При этом далеко не все из собираемых модулей будут использованы при работе системы.
Способом ускорения процесса сборки ядра является использование переменной MODULES_OVERRIDE и соответственно очистка конфиг-файла ядра от ненужных драйверов. Список необходимых модулей для сборки ядра можно построить основываясь на данных dmesg и kldstat.
Как выглядит оптимизация на практике.

Исходные данные:
а) Custom конфиг ядра
б) на сервере используется ZFS, pf и netgraph
в) В /etc/make.conf указаны следующие оптимизирующие флаги компилятора gcc:

server# cat /etc/make.conf
CPUTYPE?=athlon64
CFLAGS= -O2 -pipe
COPTFLAGS= -O2 -pipe

Время потраченное на сборку ядра без какой-либо оптимизации:

server# make buildkernel KERNCONF=KERNEL
--------------------------------------------------------------
>>> Kernel build for KERNEL started on Mon Mar 30 20:40:29 MSD 2009
--------------------------------------------------------------
--------------------------------------------------------------
>>> Kernel build for KERNEL completed on Mon Mar 30 20:57:33 MSD 2009
--------------------------------------------------------------

Итого 17 минут и 4 секунды.
Теперь посмотрим на используемые системой модули после запуска всех необходимых служб и приложений. Выглядит это приблизительно так:

server# kldstat
Id Refs Address    Size     Name
1   23 0x80400000 359b2c   kernel
2    1 0x80796000 6b2b4    acpi.ko
3    1 0x8501e000 a8000    zfs.ko
4    1 0x850c6000 2000     opensolaris.ko
5    1 0x85e94000 2f000    pf.ko
6    1 0x86689000 4000     ng_socket.ko
7    7 0x8677e000 b000     netgraph.ko
8    1 0x867a4000 3000     ng_iface.ko
9    1 0x867a7000 7000     ng_ppp.ko
10    1 0x867b5000 5000     ng_l2tp.ko
11    1 0x867ba000 5000     ng_ksocket.ko
12    1 0x867c0000 3000     ng_tee.ko
13    1 0x873f7000 3000     ng_tcpmss.ko
14    1 0x874a2000 2000     warp_saver.ko

В системе присутствует два сетевых интерфейса – xl и nfe, оба использующие MII bus.
Все динамически загруженные модули ng_*.ko являются компонентами самого модуля netgraph.ko и будут собраны как зависимости.
Основываясь на именах модулей, которые можно посмотреть в /usr/src/sys/modules, результирующий файл /etc/make.conf будет выглядеть следующим образом:

server# cat /etc/make.conf
CPUTYPE?=athlon64
CFLAGS= -O2 -pipe
COPTFLAGS= -O2 -pipe
MODULES_OVERRIDE = nfe xl mii acpi pf zfs opensolaris netgraph syscons/warp

Теперь нужно отредактировать конфиг-файл ядра. Тут существует два варианта. Либо указать необходимые драйверы в конфиг-файле ядра и они будут вкомпилированы в ядро статически, либо использовать легковесное ядро и динамически загружаемые модули.
В описываемом здесь случае использован “гибридный” вариант(некоторые драйверы статически вкопилированы в ядро, а некоторые загружаются динамически). Конфиг-файл ядра после редактирования выглядел следующим образом:

server# cat /sys/i386/conf/KERNEL
cpu              I686_CPU
ident            KERNEL
options  SCHED_ULE                 # ULE scheduler
options  PREEMPTION                # Enable kernel thread preemption
options  INET                      # InterNETworking
options  FFS                       # Berkeley Fast Filesystem
options  SOFTUPDATES               # Enable FFS soft updates support
options  UFS_ACL                   # Support for access control lists
options  UFS_DIRHASH               # Improve performance on big directories
options  UFS_GJOURNAL              # Enable gjournal-based UFS journaling
options  MD_ROOT                   # MD is a potential root device
options  CD9660                    # ISO 9660 Filesystem
options  PROCFS                    # Process filesystem (requires PSEUDOFS)
options  PSEUDOFS         # Pseudo-filesystem framework
options  GEOM_PART_GPT             # GUID Partition Tables.
options  GEOM_LABEL                # Provides labelization
options  COMPAT_43TTY              # BSD 4.3 TTY compat [KEEP THIS!]
options  KTRACE                    # ktrace(1) support
options  STACK                     # stack(9) support
options  SYSVSHM                   # SYSV-style shared memory
options  SYSVMSG                   # SYSV-style message queues
options  SYSVSEM                   # SYSV-style semaphores
options  _KPOSIX_PRIORITY_SCHEDULING
options  KBD_INSTALL_CDEV # install a CDEV entry in /dev
options  ADAPTIVE_GIANT            # Giant mutex is adaptive.
options  STOP_NMI         # Stop CPUS using NMI instead of IPI
options  AUDIT                     # Security event auditing
options         DEVICE_POLLING
options         MROUTING
options         KVA_PAGES=512
options         ACCEPT_FILTER_HTTP
device           pci
device           ata
device           atadisk          # ATA disk drives
device           atapicd          # ATAPI CDROM drives
options  ATA_STATIC_ID    # Static device numbering
device           atkbdc           # AT keyboard controller
device           atkbd            # AT keyboard
device           kbdmux           # keyboard multiplexer
device           vga              # VGA video card driver
device           splash           # Splash screen and screen saver support
device           sc
device           pmtimer
# Pseudo devices.
device           loop             # Network loopback
device           random           # Entropy device
device           ether            # Ethernet support
device           ppp              # Kernel PPP
device           pty              # Pseudo-ttys (telnet etc)
device           md               # Memory “disks”
device           bpf              # Berkeley packet filter

И соответственно время сборки ядра с оптимизированным списком модулей:

server# make buildkernel KERNCONF=KERNEL
--------------------------------------------------------------
>>> Kernel build for KERNEL started on Mon Mar 30 21:03:09 MSD 2009
--------------------------------------------------------------
--------------------------------------------------------------
>>> Kernel build for KERNEL completed on Mon Mar 30 21:08:23 MSD 2009
--------------------------------------------------------------

Итого 5 минут и 14 секунд.
За счёт предпринятых выше мер, достигнута более чем троекратная экономия времени. Совсем неплохой результат.
Если модули собраны для загрузки динамически, то загружать их нужно из /boot/loader.conf:

server# cat /boot/loader.conf
miibus_load=”YES”
if_nfe_load=”YES”
if_xl_load=”YES”
  1. amd_miek
    5 июля 2010 в 17:31

    в make.conf
    KERNCONF= — указывает дефолтное ядро для компиляции
    WITHOUT_MODULES= — антипод MODULES_OVERRIDE, который указывает какие модули компилить точно не надо.

    Я раньше стремился тоже сократить время на компиляцию ядра потом эот прошло :) когда научишься с первого-второго раза компилить нужное ядро сразу. И еще всегда перемещаю дефолтное во что нить типа kernel.GENERIC на тот случай, когда придется переежжать с железа на железо чтобы можно было грузануться с него и уже перебрать систему по новой.
    Еще б посоветовал раскрыть тему оптимизации /etc/src.conf — появилось в 7ке и позволяет достаточно просто отключить ненужное при компиляции мира.

  2. doMidden
    30 июля 2010 в 08:24

    Благодарю!