Статичний виділення пам’яті в стеку

У просторі користувача багато операцій виділення памяті, зокрема деякі розглянуті раніше приклади, можуть бути виконані з використанням стека, тому що апріорі відомий розмір виділеної області памяті У просторі користувача доступна така розкіш, як дуже великий і динамічно збільшується стек завдання, проте в режимі ядра такої розкоші немає – стек ядра маленький і фіксований за розміром Коли процесу виділяється невеликий і фіксований за розміром стек, то витрати памяті зменшуються і ядру немає необхідності виконувати додаткові функції з управління памяттю

Розмір стека залежить як від апаратної платформи, так і від конфігураційних параметрів, які були вказані на етапі компіляції Історично розмір стека ядра дорівнював двом сторінкам памяті для кожного процесу Це відповідає

8 Кбайт для 32-розрядних апаратних платформ і 16 Кбайт для 64-розрядних апаратних платформ

У перших версіях ядер серії 26 була введена можливість конфігурації, для якої розмір стека ядра дорівнює одній сторінці памяті Коли встановлюється така конфігурація, то процес отримує стек, за розміром рівний всього одній сторінці памяті: 4 Кбайт на 32-розрядних апаратних платформах і 8 Кбайт – на 64-розрядних Це зроблено з двох причин По-перше це зменшує витрати памяті на одну сторінку для кожного процесу По-друге, що найбільш важливо, при збільшенні часу роботи системи (uptime) стає все важче шукати дві фізично суміжні сторінки памяті Фізична память стає все більш фрагментованою, і навантаження на систему управління віртуальною памяттю при створенні нових процесів стає все більш істотною

Існує ще одна складність (залишайтеся з нами, і Ви дізнаєтеся все про стеках ядра) Вся послідовність вкладених викликів функцій в режимі ядра повинна поміститися в стек Історично обробники переривань використовують стек того процесу, виконання якого вони перервали Це означає, що в гіршому випадку

8 Кбайт стека має використовуватися спільно всіма вкладеними викликами функцій і ще парою обробників переривань Все це ефективно і просто, але це накладає ще більше обмежень на використання стека ядра Коли розмір стека скоротився до однієї сторінки памяті, обробники переривань туди перестали поміщатися

Для вирішення зазначеної проблеми була реалізована ще одна можливість – стеки обробників переривань Стеки переривань являють собою один стек на кожен процесор, які використовуються для обробки переривань При такій конфігурації обробники переривань більше не використовують стеки ядра тих процесів, які цими обработчиками перериваються Замість цього вони використовують свої власні стеки Це вимагає тільки одну сторінку памяті на процесор

Підібємо підсумки Стек ядра займає одну або дві сторінки памяті, залежно від конфігурації, яка виконується перед компіляцією ядра Отже, розмір стека ядра може мати діапазон від 4 до 16 Кбайт Історично обробники переривань спільно використовували стек перерваного ними процесу При появі стеків ядра розміром в одну сторінку памяті обробникам переривань були призначені свої стеки У будь-якому випадку необмежена рекурсія і використання функцій на зразок alloca () явно не допустимі

Чесна гра зі стеком

У будь-якої функції необхідно скорочувати використання стека до мінімуму Хоча не існує твердих правил, проте слід підтримувати максимальний сумарний обсяг усіх локальних змінних (Також відомих як автоматичні змінні або змінні, виділені в стеці) щонайбільше кількох сотень байтів Небезпечно статично виділяти великі обєкти в стеку, такі як великі масиви структур В іншому випадку виділення памяті в стеку буде виконуватися так само, як і в просторі користувача Переповнення стека відбувається непомітно і зазвичай призводить до проблем Так як ядро не виконує ніякого управління стеком, то дані стека просто перепишуть все, що знаходиться за стеком У першу чергу постраждає структура thread_info, яка розташована в самому кінці стека процесу (згадайте главу 3) За межами стека всі дані ядра можуть пропасти У кращому випадку при переповненні стека відбудеться збій у роботі машини У найгірших випадках може відбутися пошкодження даних

У звязку з цим, для виділення великих обсягів памяті необхідно використовувати одну з динамічних схем виділення памяті, які були розглянуті раніше в цій главі

Джерело: Лав, Роберт Розробка ядра Linux, 2-е видання : Пер з англ – М: ТОВ «ІД Вільямс »2006 – 448 с : Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*