În multe operațiuni de alocare de memorie spațială de utilizator, în special, unele dintre exemplele discutate mai sus pot fi implementate folosind stiva, pentru că a priori dimensiunea zonei de memorie alocată cunoscută. În spațiul de utilizator disponibil pentru luxul unui teanc foarte mare și în creștere dinamică a sarcinilor, dar în modul de kernel nu este un lux - nucleu stiva este de dimensiuni mici și fixe. Când procesul este dat un mic și fix stivă mărimea, costurile de depozitare sunt reduse, iar kernel-ul nu este necesar să îndeplinească funcții suplimentare pentru gestionarea memoriei.
Dimensiunea stivei depinde atât de platforma hardware, cât și de parametrii de configurare specificați la etapa de compilare. Din punct de vedere istoric, mărimea stivei kernel-ului a fost de două pagini de memorie pentru fiecare proces. Acest lucru corespunde
8 KB pentru platforme hardware pe 32 de biți și 16 KB pentru platforme hardware pe 64 de biți.
În primele versiuni ale kernelului 2.6, a fost introdusă o opțiune de configurare, pentru care dimensiunea stivei kernel-ului este o pagină de memorie. Atunci când se stabilește o astfel de configurație, procesul primește un stack egal în mărime cu o singură pagină de memorie: 4 KB pe platforme hardware pe 32 de biți și 8 KB pe 64 de biți. Acest lucru se întâmplă din două motive. În primul rând, reduce costul de memorie pe pagină pentru fiecare proces. În al doilea rând, cel mai important, cu cât crește timpul de funcționare a sistemului (uptime), devine mai greu să căutați două pagini de memorie fizic adiacente. Memoria fizică devine din ce în ce mai fragmentată, iar încărcarea sistemului de gestionare a memoriei virtuale la crearea noilor procese devine din ce în ce mai semnificativă.
Există încă o dificultate (stați cu noi și veți afla totul despre stive de kernel). Întreaga secvență de apeluri de funcții imbricate în modul kernel trebuie să se potrivească în stivă. Din punct de vedere istoric, agenții de întrerupere folosesc un teanc de proces, execuția căruia au întrerupt. Aceasta înseamnă că, în cel mai rău scenariu
8 KB de stivă ar trebui să fie utilizate împreună de toate apelurile de funcții imbricate și o altă pereche de handlers de întrerupere. Toate acestea sunt eficiente și simple, dar impun și mai multe restricții asupra utilizării stivei de kernel. Când mărimea stivei a fost redusă la o pagină de memorie, operatorii de întrerupere nu au mai fost localizați.
Pentru a rezolva această problemă, a fost implementată o altă posibilitate: stivele de operatori de întrerupere. Stivele de întrerupere sunt un stack per procesor, care sunt folosite pentru procesarea întreruperilor. Cu această configurație, manipulatorii de întrerupere nu mai folosesc stivele de kernel ale proceselor terminate de aceștia. În schimb, își folosesc propriile stive. Aceasta necesită doar o singură pagină de memorie per procesor.
Să rezumăm. Stack-ul kernel-ului ocupă una sau două pagini de memorie, în funcție de configurația care se efectuează înainte de compilarea kernel-ului. Prin urmare, mărimea stivei kernel-ului poate varia de la 4 până la 16 KB. Din punct de vedere istoric, agenții de întrerupere au împărțit o mulțime de procese pe care le întrerupseră. Când au apărut stive de kernel dintr-o pagină de memorie, operatorii de întrerupere au primit propriile lor pachete. În orice caz, recursivitatea nerestricționată și utilizarea funcțiilor cum ar fi alloca () nu sunt în mod clar permise.
Joc cinstit cu stivă
În orice funcție, trebuie să reduceți la minim utilizarea teancului. Deși nu există reguli grele, trebuie să păstrați volumul total maxim al tuturor variabilelor locale (cunoscute și ca variabile automate sau variabile alocate în stivă) nu mai mult de câteva sute de octeți. Este periculos să alocați în mod static obiecte mari pe stivă, cum ar fi rețele mari de structuri. În caz contrar, alocarea memoriei în stivă va fi efectuată în același mod ca și în spațiul utilizatorului. Depășirea stivei apare neobservată și, de obicei, duce la probleme. Deoarece nucleul nu efectuează niciun management de stivă, datele stivei vor înlocui pur și simplu tot ceea ce se află în spatele stivei. Structura thread_info va fi afectată mai întâi. care se află chiar la capătul procesului (rețineți capitolul 3). În afara stivei, toate datele kernel-ului pot fi pierdute. În cel mai bun caz, atunci când stivuirea depășește, aparatul se blochează. În cele mai grave cazuri, poate apărea o corupție a datelor.
În acest sens, pentru a aloca cantități mari de memorie, trebuie să utilizați una dintre schemele de alocare dinamică a memoriei, discutate mai devreme în acest capitol.