 | Уровень сложности: средний Кристиан Кайзер, Стажёр, IBM Кристиан Рунд, исследователь-разработчик, IBM
12.02.2008 В этой серии из трёх частей представлена форма программной виртуализации, ориентированная на аппаратные ресурсы, известная как контейнерная виртуализация (или виртуализация операционной системы), для демонстрации которой используется проект с открытым исходным кодом OpenVZ. В серии представлен исчерпывающий обзор всех компонентов и методик, необходимых для виртуализации процессора Cell/B.E. программными методами. Эта статья, вторая в серии, подробно описывает реализацию выделенной виртуализации и разбиения на разделы, описанных в первой части серии..
В статье описывается реализация понятия выделенной виртуализации (разбиения на разделы), показанного в первой статье (часть 1, рисунок 3).
В этой статье не рассматривается концепция устройств общего пользования (показанная в части 1, на рисунке 4).
Чтобы продемонстрировать реализацию системы, в этой статье будут освещены следующие вопросы:
- Виртуализация spufs: предотвращение использования одного root-inode для всех точек монтирования
- Корректировки sysfs: записи необходимо корректировать в реальном времени
- Модификация планировщика SPU: добавление шага реализации виртуализации
- Модификация инструментов OpenVZ: использование новых функций
Виртуализация spufs
По умолчанию spufs использует один и тот же root-inode при каждом монтировании. Например, у вас может быть две среды chroot (A и B), и spufs обоих будет смонтирована по пути /spu. Если вы создадите потоки SPE в среде A, после чего выведете содержимое /spu, вы увидите только что созданные потоки SPE. Однако в среде B вы увидите тот же листинг /spu, поскольку вы обращаетесь к тому же root-inode, что и в среде A.
Чтобы изменить такое поведение, т.е. чтобы в обеих средах можно было увидеть только созданные в них потоки SPE, необходимо изменить тот факт, что spufs всегда использует один и тот же root-inode для всех точек монтирования. При монтировании spufs она вызывает функцию ядра, которая возвращает системный блок. Обычно используется функция get_sb_single(), которая всегда возвращает один и тот же системный блок. Функция get_sb_nodev() всегда возвращает различные системные блоки, что приводит к нужному нам результату. (На рисунке 1 показана spufs до и после выполнения виртуализации.)
Рисунок 1. Spufs до и после выполнения виртуализации
OpenVZ позволяет смонтировать внутри контейнера только несколько файловых систем. Каждая система реализует экземпляр struct file_system_type
, который определяет аспекты, связанные с файлами. OpenVZ расширяет эту структуру (наряду с другими), дополняя ее компонентом, определяющим, может ли быть смонтирована файловая система. Таким образом, компоненту .fs_flags должно быть установлено значение FS_VIRTUALIZED.
У процесса, созданного внутри контейнера, есть два PID. (Вспомните часть 1
, в которой говорилось, что у каждого контейнера есть собственное множество ресурсов, предоставляемых ядром. У дерева процессов было одно множество ресурсов, а контейнер мог видеть только собственное множество процессов с виртуализованными PID.) Внутри контейнера есть виртуализованный PID, а в базовой системе тот же процесс идентифицируется другим PID, который называется глобальным PID. Как уже упоминалось, название директорий spufs задаётся в виде spethread-<PID>-<thread-ID>, где <PID> - идентификатор процесса потока SPE, а <thread-ID>> соответствующий идентификатор потока. Поскольку в среде контейнера используются виртуализованные PID, листинг spufs внутри контейнера должен показывать виртуализованные, а не глобальные PID. К счастью, такой алгоритм уже реализован в OpenVZ.
Измените файл arch/powerpc/platforms/cell/spufs/inode.c в ядре Linux®.
Корректировка sysfs
sysfs уже виртуализована, поэтому ее можно использовать внутри контейнеров. Она является не копией sysfs, видимой в базовой системе, а её частью. Цель состоит в том, чтобы выделять SPU контейнерам и освобождать их в реальном времени. Это означает, что записи sysfs также необходимо адаптировать в реальном времени. Перед этим создайте директорию, в которой перечислены SPU.
Это директория /sys/devices/system/spu. По умолчанию в sysfs в среде контейнера нет директорий /sys/devices/system/spu, /sys/devices/system и /sys/devices. Эти три записи необходимо создать во время инициализации (запуска) контейнера. Поддиректории /sys/devices/system/spu могут иметь вид от spu0 до spu<N>, где <N> - количество доступных SPU в системе минус 1. Директории необходимо создавать, когда SPU назначается контейнеру, и удалять, когда они открепляются от контейнера.
Каждой директории в листинге sysfs должен соответствовать экземпляр kobject в пространстве ядра. kobject - это структура, которая определяет название директории и её родительский kobject (другими словами, соответствующую родительскую директорию). Например, у kobject, который отображается как директория /sys/devices/system/spu/spu3, есть два параметра, которые нужно изменить:
- Название spu3.
- Родитель (указатель на kobject, представляющий /sys/devices/system/spu).
После регистрации kobject в sysfs посредством вызова subsystem_register(), он становится видимым из пространства пользователя. Обратное действие состоит в удалении директории из sysfs. Для этого можно вызвать функцию subsystem_unregister(), указав kobject, который необходимо удалить. На рисунке 2 показан пример.
Рисунок 2. Sysfs и kobjects
У kobject с названием spu3 есть указатель на родительский kobject с названием spu.
Основные изменения необходимо сделать в файле ядра kernel/ve/vecalls.c. Это файл OpenVZ, в котором реализовано большинство функций, которые вызываются во время инициализации и настройки параметров контейнеров.
Модификация планировщика SPU
Каждый физический SPU системы представлен экземпляром структуры spu в пространстве ядра. В этой структуре хранится несколько параметров, в число которых входят:
- Идентификатор (номер) SPU
- К какому узлу Cell/B.E. он принадлежит
- Указатель на LS SPU
Новая переменная хранит владельца SPU в виде идентификатора контейнера. Планировщик SPU реализует функцию spu_alloc(), которая ищет свободный SPU, на котором будет выполняться поток SPE. Таким образом, он ищет список доступных в системе SPU (на которых в данный момент не выполняется потоков SPE).
Обычно берется первый SPU в списке и на нём запускается поток SPE. Чтобы реализовать виртуализацию, функция должна проверить, совпадает ли идентификатор контейнера свободного SPU с идентификатором контейнера потока SPE, который предполагается на нем выполнить. На рисунке 3 показано, как работает spu_alloc() до и после модификации.
Рисунок 3. Spu_alloc() до и после модификации
Если эта дополнительная проверка дает негативный результат, функция проверяет следующий элемент в списке свободных SPU. Если свободных SPU для контейнера, запускающего поток SPE, нет, планировщик SPU ведет себя так же, как если бы список был пуст, и ждёт освобождения SPU.
Функция spu_alloc() реализована в исходном файле ядра Linux arch/powerpc/platforms/cell/spu_base.c.
Модификация инструментов OpenVZ
Большая часть нужной функциональности уже реализована, но для того, чтобы использовать новые функции, необходимо модифицировать инструменты OpenVZ. Инструмент vzctl управляет выделением SPU в реальном времени. Это основной инструмент для настройки параметров в OpenVZ. Новый параметр для установки количества SPU, выделенных контейнеру, - --spus <nr_spus>.
Значение <nr_spus> представляет количество SPU, выделенных контейнеру. Это абсолютное значение, поэтому если контейнеру с восемью SPU присваивается значение 6, то от процессора открепляются 2 SPU, а не добавляются 6 SPU (8 - 6 = 2).
Например, вот результат работы команды, когда контейнер с ID, равным 101, получает восемь SPU:
[root@c02b12-0 ~]# vzctl set 101 --spus 8
Setting SPUs: 8
Configure meminfo: 1024000
WARNING: Settings were not saved and will be reset to original
values on next start (use --save flag)
[root@c02b12-0 ~]#
|
Для реализации такого алгоритма инструмент vzctl должен перейти барьер пространства пользователя и выполнить ряд операций управления в пространстве ядра. Инструмент должен найти SPU, которые не используются другими контейнерами. Инструмент vzctl выполняет поиск по списку доступных SPU и проверяет идентификатор контейнера в структуре нового spu (описана в разделе модификации планировщика SPU). Если это значение равно 0, SPU может быть назначен рассматриваемому контейнеру. Значение 0 используется потому, что значение идентификатора контейнера должно быть больше 0, т.е. значение 0 указывает на то, что SPU не назначен ни одному из контейнеров. Если функция не может найти нужного для выполнения запроса количества свободных SPU, процедура завершается и не назначает контейнеру ни одного SPU. Если количество SPU, уже назначенных контейнеру, больше запрошенного количества SPU, разница открепляется.
Чтобы преодолеть барьер между пространством пользователя и пространством ядра, можно использовать различные модели реализации. (Дополнительную информацию о моделях реализации можно найти в статье Арнда Бергмана "Как не изобрести интерфейсы ядра", ссылка на которую приведена в разделе Ресурсы.) Наиболее простой способ состоит в реализации нового системного вызова, который накладывает параметры <containerID> и <nr_spus> на параметры системного вызова.
Функции, которые выполняют настройку параметров SPU контейнера, должны реализовываться в той части ядра, которая может быть реализована в модуле ядра. Это представляет большую проблему. Если модуль ядра не загружен, функция обработки системного вызова в пространстве ядра ничего не сделает. Однако если модуль загружен, он вызовет функцию, реализованную в модуле. Это нетривиальная задача, поскольку таблица системных вызовов (где хранятся указатели функции на функции обработки системных вызовов) является частью статической сборки ядра.
Модуль не является частью этой статической функции, и поэтому статическая встроенная функция обработки системного вызова не может вызвать функцию, являющуюся частью модуля. Решение состоит в реализации оболочки функции, которая копирует указатель на функции модуля в переменную встроенной статической функции обработки системного вызова таким образом, чтобы встроенный статический обработчик системного вызова мог вызвать функцию модуля. Эта оболочка функции вызывается во время инициализации и очистки модуля. Чёрная стрелка на рисунке 4 показывает наш метод оболочки функции.
Рисунок 4. Функции модуля и системный вызов
Вы видите, как указатель функции, реализованной в модуле, копируется во встроенную статическую функцию пространства ядра. Пунктирные стрелки показывают, как приложения пространства пользователя вызывают функцию модуля, передавая встроенную статическую функцию обработчика системного вызова.
Необходимо изменить исходный код ядра в следующих файлах:
- include/asm-powerpc/systbl.h
- include/asm-powerpc/unistd.h
- include/linux/syscalls.h
- kernel/sys.c
- kernel/sys_ni.c
- kernel/ve/vecalls.c
Кроме того, обновляются файлы исходного кода vzctl OpenVZ:
- include/res.h
- include/vzctl_param.h
- include/vzsyscalls.h
- src/lib/config.c
- src/lib/res.c
- src/vzctl.c
В систему сборки OpenVZ добавляется два новых файла:
- include/spu.h
- src/lib/spu.c
Подготовка к третьей части
В третьей части серии описывается использование и тестирование системы, а также приводится анализ производительности контейнерной виртуализации по сравнению с другими программными методами виртуализации – в частности, паравиртуализацией и полной виртуализацией.
Ресурсы Научиться
- Оригинал статьи "Cell/B.E. container virtualization, Part 2" (EN).
- Используйте канал RSS(EN) для получения уведомлений о новых статьях в этой серии. (Подробная информация о каналах RSS для контента developerWorks .)
- Познакомьтесь с работой "Виртуализация в Linux" (сентябрь 2006 г.), где описываются OpenVZ и виртуализация. Она связывает три основных подхода к виртуализации —эмуляция, паравиртуализация и виртуализация на уровне ОС—с OpenVZ. (EN)
- Познакомьтесь со статьёй Арнда Бергмана "Spufs: синергический процессор Cell как виртуальная файловая система" (EN) (developerWorks, июнь 2005 г.), где изложена подробная информация об интерфейсе файловой системы SPU, который позволяет Linux работать на платформе Cell/B.E. Статья Бергмана "Как не изобрести интерфейсы ядра" (статья на конференцию LinuxConf Europe, июль 2007 г.) объясняет, как выбрать форму интерфейса пространства пользователя для использования в коде ядра. Бергман также ведет виртуальный учебный курс по Linux на платформе Cell/B.E.
, который охватывает модель формирования потоков, стратегию работы Linux в реальном времени, требования к работе PPU/SPU, spufs, обработку сигналов и многое другое. (EN)
- В презентации Дэниэля Хакенберга "Измерение производительности систем Cell SMP" (С конференции Центра информационных служб и высокопроизводительных вычислений, посвящённой кластерам Cell/B.E., май 2007 г.) приведен анализ показателей производительности операций по умножению матриц, полосе пропускания DMA к XDR и полосе пропускания DMA между SPE. (EN)
- Познакомьтесь с презентацией Дака Вьянни "Модель создания программных решений Cell" (март 2006 г.), где рассмотрены вопросы модели программирования для Cell/B.E., сравнение моделей, основанных на PPE и SPE, перенос функциональной нагрузки, перекрытие DMA и вычислений, а также гетерогенная многопоточность. (EN)
- Основные понятия виртуализации на примере обычных шаблонов в "Справочнике по виртуализации" (EN) (developerWorks, июнь 2006 г.). mВиртуальный Linux" (developerWorks, декабрь 2006) - описывает различные виды виртуализации (а также текущие проекты виртуализации) с точки зрения Linux.
- Дополнительную информацию о пара-виртуализации можно найти в статьях "Виртуализация в coLinux" (developerWorks, март 2007 г.) и "Эмуляция систем с помощью QEMU" (сентябрь 2007 г.). (EN)
- Изучите серию вводных руководств в блоге по SDK —
Infobombs. Три первых руководства знакомят со средой Accelerated Library Framework (ALF) ,
иллюстрируют 10 наиболее важных понятий ALF и знакомят со службами библиотеки Data Communication and Synchronization (DaCS) . (EN)
- Изучите статью "Изменения в libspe: как libspe2 влияет на программирование Cell Broadband Engine" (developerWorks, июль 2007 г.), где приведено описание понятий libspe2 и способов организации базового управления процессами SPE и связи с libspe2.
- В статье "Введение в многопроцессорные системы Cell"
в журнале IBM Journal of Research and Development , 2005 г.) приводится обзорное введение в историю многопроцессорных систем Cell/B.E., целей и трудностей программы, проектных решений, программных и архитектурных моделей, а также реализаций. (EN)
- Чтобы больше узнать о программировании Cell/B.E., познакомьтесь со следующими сериями статей developerWorks:
(EN)
- Множество руководств, спецификаций и многого другого можно загрузить из раздела документации Cell Broadband Engine технической библиотеки решений IBM Semiconductor Solutions. (EN)
- Подпишитесь на новостную рассылку developerWorks и получайте по почте последние новости для разработчиков и о событиях Cell/B.E. каждую неделю. Если вы хотите подписаться на новости Cell/B.E., отметьте раздел Power Architecture. (EN)
- Посетите другие ресурсы developerWorks, которые могут вас заинтересовать в связи с их виртуализацией: раздел Linux и раздел Open Source.
Получить продукты и технологии
Обсудить
Об авторах  | |  | Кристиан Кайзер (Christian Kaiser) изучает вычислительную технику в университете RWTH в Ахене в Германии. В 2007 году он проходил стажировку в исследовательской лаборатории IBM в Германии, в городе Бёблинген. Во время стажировки в IBM он исследовал методы виртуализации для процессора Cell Broadband Engine. После завершения стажировки Кристиан Кайзер начал работу над диссертацией на кафедре операционных систем в университете RWTH в Ахене. Тема его диссертации - "Анализ коллективной асинхронной связи в высокоскоростных сетях, организованных в памяти" |
 | |  | Кристиан Рунд (Christian Rund) - сотрудник исследовательской лаборатории IBM в Бёблингене, в Германии. Он изучал теорию вычислительных систем в университете Штутгарта и в Упсальском университете в Швеции, закончив обучение в 1997 году. Во время учебы он проходил стажировку в IBM в Херренберге и Штутгарте в Германии. В 1998 году он поступил на работу в департамент разработки систем банка Landeszentralbank в Штутгарте (Deutsche Bundesbank). В 2001 году Кристиан перешел в команду разработчиков канала FCP zSeries корпорации IBM в качестве исследователя-разработчика. С середины 2006 года он занимается исследованием и разработкой микропрограммного обеспечения хост-контроллера Cell/B.E. |
Выскажите мнение об этой странице
|  |