Introduzione

Il valore nel registry "SystemPages" nella chiave "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" governa la dimensione assegnata alle System PTE, che ho descritto in un mio recente post, Windows Server 2003 & 2008 - System PTE e PTE (Page Table Entry), su questo argomento.

Il default di questo valore di tipo DWORD è 0, che significa che il dimensionamento delle System PTE viene lasciato al sistema. Valori differenti da zero indicano al Memory Manager un numero di System PTE desiderato e viene preso in considerazione in fase di boot per definire l'effettiva dimensione di questa area, che prima di Windows Vista era statica. In questa fase il valore viene letto ed eventualmente ridimensionato in base a certi massimi e minimi, inoltre viene arrotondato su delle soglie ed infine applicato alla definizione dei range di System PTE. Ulteriori dettagli su come viene interpretato questo valore possono anche dipendere da altri parametri di configurazione, ad esempio un ulteriore fatto che influenza in modo significativo le System PTE è lo switch /3GB nel boot.ini, la cui presenza, assieme al compagno /USERVA, articola ulteriormente il risultato finale del dimensionamento dei range di System PTE.

L'obiettivo di questo post è focalizzato su un particolare valore che spesso troviamo nelle nostre installazioni pari a 0xC3000 (798720).

"SystemPages" = 0xC3000

Questo valore è oltre il massimo che può essere accettato internamente al Memory Manager e verrà sicuramente ridimensionato prima di essere usato, come si diceva sopra, durante la fase di boot.

Esso viene scritto nel registry durante l'installazione della macchina, o di suoi dispositivi Plug and Play, in base all'hardware. In particolare vengono prese in considerazione certe caratteristiche hardware che potrebbero richiedere l'uso delle System PTE per il mapping di device memory (memoria presente sul dispositivo che si presenterà sullo spazio di indirizzi fisici). Il calcolo di questo numero ha un limite massimo a 0xC3000. Oggi ci troviamo spesso questo esatto valore in quanto l'hardware, avanzatissimo rispetto ai fini per cui l'algoritmo era stato originariamente definito, ci porta sempre al massimo.

È da osservare che sull'architettura x86, se il Memory Manager lo prendesse in considerazione così com’è (invece che ridimensionarlo come in effetti avviene), dovrebbe riservare 798720 System PTE, che corrispondono ad altrettante pagine di memoria negli indirizzi virtuali del kernel. Siccome ogni pagina ha dimensione di 4096 byte (0x1000) l'intero address space kernel a 32 bit non sarebbe sufficiente, si tratterebbe infatti di mappare circa 3GB solo per le System PTE, mentre al kernel ne sono riservati 1 o 2 a seconda della presenza o meno dello switch di configurazione /3GB nel boot.ini.

In base a questa osservazione in sostanza si deduce che sulla piattaforma a 32 bit, quando troviamo questo valore, lo possiamo tranquillamente sostituire con 0, che è il default e con le moderne dimensioni delle memorie porta normalmente ad una configurazione ottimale.

Nella configurazione senza lo switch /3GB nel boot.ini, qualsiasi valore può andare sostanzialmente bene perché, come si diceva, un massimo viene imposto dal memory manager e in 2GB per il kernel ci possiamo permettere di dimensionare le System PTE al loro valore massimo consentito. E' però da considerare anche che un'eccessiva disponibilità di System PTE può essere a discalpito della dimensione della Paged Pool e/o della System Cache, quindi la raccomandazione è comunque di riportarlo al suo default pari a zero.

Con la configurazione /3GB, invece, "SystemPages" = C3000 potrebbe suggerire al kernel un dimensionamento del primo range di System PTE eccessivamente dispendioso, che quasi sicuramente penalizzerebbe in modo significativo tutte le altre aree di memoria. In questo caso è sempre raccomandabile riportarlo al suo default (zero). Le eventuali System PTE perse dopo questa riconfigurazione possono essere recuperate con un'opportuno tuning dello switch /USERVA nel boot.ini, che abbassa la divisione tra user e kernel ad un valore prefissato espresso in megabyte. Tutto lo spazio tra la nuova divisione e quella originaria del /3GB (ovvero 3072) viene consegnata al secondo range di System PTE. Per esempio /USERVA=3000 dimensionerebbe un secondo range di System PTE a 3072MB-3000MB=72MB, corrispondente numericamente a 72*1024*1024/4096=18432 System PTE.

Avendo la disponibilità di recuperare altre System PTE tramite /USERVA talvolta è addirittura opportuno limitare fortemente il primo range di System PTE, con valori relativamente bassi del valore "SystemPages" qui descritto, e recuperarle dal secondo range come citato (abbassando /USERVA corrispondentemente). Questa tecnica evidentemente permetterà maggior spazio per le altre aree di memoria kernel, primariamente alla Paged Pool.

Conclusioni

Questo post aveva l'obiettivo di analizzare un particolare valore che nelle moderne installazioni ci troviamo nel registry per specificare il numero di System PTE ("SystemPages" = 0xC3000). Spesso non ci si sa spiegare da quale configurazione sia arrivato e perché assuma proprio questo numero.

In sintesi si è visto che il default, pari a zero, è più opportuno ed ottimizza altre aree di memoria del kernel.

Si è anche citato come ottenere più System PTE in una configurazione con lo switch /3GB ma i dettagli verranno illustrati in un prossimo post, dato che questa trattazione è particolarmente complessa ed articolata. Il ridimensionamento di un'area di memoria causa infatti effetti su tutte le altre e nello spazio ristretto di 1GB per il kernel (con /3GB) errori in questo tuning possono causare seri problemi di performance e/o stabilità.

Con Windows Server 2008 e Windows Server 2008 R2, che offrono aree di memoria kernel dinamicamente ridimensionabili, e con le architetture a 64 bit, che offrono gigantesche aree di memoria kernel, tutte queste limitazioni sono state completamente superate e quindi la nostra raccomandazione è sicuramente di spostarsi su queste installazioni, prediligendo x64 su tutti i server.

Riferimenti

Per definizioni delle risorse kernel citate in questo post ed il loro uso nel sistema, come ad esempio la Paged Pool, si consiglia questo altro post nel nostro blog: Kernel Memory Overview.

Fabio Lavatelli
Escalation Engineer
Microsoft Enterprise Platform Support