Linux Kernel (Ядро линукса) (часть 1)


Функция rebalance_tick()

Функция rebalance_tick() вызывается на каждом тике функцией scheduler_ tick о для поддержания сбалансированности очередей в системе. Она принимает в качестве параметров индекс локального this cpu, адрес локальной очереди на выполнение this rq и флаг idle, который может иметь следующие значения:
- sched idle — процессор не занят, т. е. текущим является процесс swapper;
- not idle — процессор занят, т. е. текущим является процесс, отличный от swapper.

Функция rebaiance ticko вначале определяет количество процессов в очереди на выполнение и обновляет значение средней нагрузки на эту очередь. С этой целью функция обращается к полям nr running и cpu ioad дескриптора очереди на выполнение.

Затем функция rebaiance ticko входит в цикл по всем областям планирования на пути от базовой области (на которую ссылается поле sd дескриптора локальной очереди на выполнение) до области верхнего уровня. На каждом шаге цикла функция определяет, настало ли время вызывать функцию load baiance для выполнения перебалансировки данной области планирования. Значение параметра idle и некоторые другие значения, хранящиеся в дескрипторе sched domain, определяют частоту вызовов функции load baiance . Если параметр idle равен sched idle, значит, очередь на выполнение пуста, и функция rebaiance ticko вызывает функцию load_ balance довольно часто (приблизительно каждый тик или раз в два тика для областей планирования, соответствующих логическим и физическим процессорам). Если, наоборот, параметр idle равен not idle, то функция rebaiance tick о вызывает функцию load baiance о гораздо реже (примерно раз в Юме для областей планирования, соответствующих логическим про
цессорам и раз в 100 мс для областей, соответствующих физическим процессорам).

Функция loadJbaianceQ

Функция load baiance проверяет, является ли область планирования сильно разбалансированной. Точнее говоря, она проверяет, можно ли уменьшить разбалансированность, удалив несколько процессов из самой занятой группы в очередь на выполнение, принадлежащую локальному процессору. Если такое действительно возможно, функция пытается произвести миграцию процессов. Она принимает четыре параметра:
- this cpu — индекс локального процессора;
- this rq — адрес дескриптора локальной очереди на выполнение;
- sd — указатель на дескриптор проверяемой области планирования;
- idle — флаг, принимающий значение sched idle (локальный процессор не занят) или not_idle.
Функция выполняет следующие действия:
1. Получает спин-блокировку this_rq->lock.
2. Вызывает функцию find busiest group , чтобы проанализировать рабочую нагрузку на группы внутри области планирования. Функция возвращает адрес дескриптора sched group самой загруженной группы, при условии, что она не включает в себя локальный процессор; кроме того, функция возвращает количество процессов, подлежащих переносу в локальную очередь на выполнение для восстановления баланса. В противном случае, если самая загруженная группа включает в себя локальный процессор или все группы сбалансированы, функция возвращает null. Это не тривиальная процедура, потому что функция, по возможности, фильтрует статистические флуктуации рабочей нагрузки.
3. Если функция find busiest group не нашла группу, которая не содержит локальный процессор и загружена значительно сильнее других групп в этой области планирования, описываемая функция освобождает спин- блокировку this_rq->iock, настраивает параметры дескриптора области планирования так, чтобы отсрочить следующий вызов функции load baiance на локальном процессоре, и завершает работу.
4. Вызывает функцию find busiest queue , чтобы найти самые загруженные процессоры в группе, найденной на шаге . Функция возвращает адрес дескриптора busiest соответствующей очереди на выполнение.
5. Получает вторую спин-блокировку, а именно busiest->iock. Чтобы избежать взаимных блокировок, это нужно делать аккуратно: вначале освобо
ждается this_rq->iock, а затем обе блокировки захватываются в порядке возрастания индекса процессора.
6. Вызывает функцию move tasksO в попытке перенести некоторые процессы ИЗ ОЧереДИ busiest В ЛОКаЛЬНуЮ ОЧереДЬ this_rq.
7. Если функции move tasks о не удалось произвести миграцию процессов в локальную очередь на выполнение, область планирования осталась разбалансированной. Функция устанавливает флаг busiest->active_balance и будит поток ядра migration, дескриптор которого хранится в поле busiest-> migration thread. Поток migration проходит по всей цепочке областей планирования от базовой области, соответствующей очереди busiest, до области самого верхнего уровня и ищет свободный процессор. Если такой процессор обнаруживается, поток ядра вызывает функцию move tasks о, чтобы перенести один процесс в свободную очередь на выполнение.
8. Освобождает спин-блокировки busiest->lock И this_rq->lock.
9. Завершает работу.

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без про...

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга...

Linux Kernel (Ядро линукса) (ч...

Спин-блокировкаСпин-блокировка необходима в многопроцессорной системе, потому что могут возникнуть...

Linux Kernel (Ядро линукса) (ч...

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно...

Linux Kernel (Ядро линукса) (ч...

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer...