Domanda

Ho cercato su Google e ho trovato la maggior parte delle persone che sostenevano l'uso di kmalloc , poiché sei sicuro di ottenere blocchi fisici contigui di memoria. Tuttavia, sembra anche che kmalloc possa fallire se un blocco contiguo fisico che desideri non può essere trovato.
Quali sono i vantaggi di avere un blocco di memoria contiguo? In particolare, perché dovrei avere un blocco di memoria fisico contiguo in una chiamata di sistema ? C'è qualche motivo per cui non potrei semplicemente usare vmalloc ?
Infine, se dovessi allocare memoria durante la gestione di una chiamata di sistema, dovrei specificare GFP_ATOMIC ? Una chiamata di sistema viene eseguita in un contesto atomico?

  

GFP_ATOMIC
  L'assegnazione è prioritaria e   non dorme. Questa è la bandiera di   utilizzare nei gestori di interrupt, in basso   metà e altre situazioni in cui tu   non riesco a dormire.

     

GFP_KERNEL   Questa è una normale allocazione e potrebbe bloccarsi. Questa è la bandiera da usare   nel codice di contesto del processo quando è sicuro dormire.

È stato utile?

Soluzione

Devi solo preoccuparti di usare la memoria fisicamente contigua se il buffer sarà accessibile da un dispositivo DMA su un bus indirizzato fisicamente (come PCI). Il problema è che molte chiamate di sistema non hanno modo di sapere se il loro buffer verrà eventualmente passato a un dispositivo DMA: una volta passato il buffer a un altro sottosistema kernel, non si può davvero sapere dove andrà. Anche se il kernel non utilizza il buffer per DMA oggi, uno sviluppo futuro potrebbe farlo.

vmalloc è spesso più lento di kmalloc, perché potrebbe essere necessario rimappare lo spazio del buffer in un intervallo praticamente contiguo. kmalloc non rimappa mai, sebbene se non chiamato con GFP_ATOMIC kmalloc può bloccare.

kmalloc ha dimensioni limitate del buffer che può fornire: 128 KBytes *) . Se hai bisogno di un buffer davvero grande, devi usare vmalloc o qualche altro meccanismo come riservare molta memoria all'avvio.

  

*) Questo era vero per i kernel precedenti. Sui kernel recenti (l'ho provato su 2.6.33.2), la dimensione massima di un singolo kmalloc è fino a 4 MB! (Ho scritto abbastanza post dettagliato su questo .) & # 8212; Kaiwan

Per una chiamata di sistema non è necessario passare GFP_ATOMIC a kmalloc (), è possibile utilizzare GFP_KERNEL. Non sei un gestore di interrupt: il codice dell'applicazione entra nel contesto del kernel per mezzo di una trap, non è un interrupt.

Altri suggerimenti

Risposta breve: scarica Driver di dispositivo Linux e leggi il capitolo sulla gestione della memoria.

Seriamente, ci sono un sacco di problemi sottili legati alla gestione della memoria del kernel che devi capire - dedico molto del mio tempo al debug di problemi con esso.

vmalloc () è usato molto raramente, perché il kernel usa raramente memoria virtuale. kmalloc () è ciò che viene generalmente utilizzato, ma devi sapere quali sono le conseguenze delle diverse bandiere e hai bisogno di una strategia per affrontare ciò che accade quando fallisce, in particolare se sei in un gestore di interrupt, come hai suggerito.

Linux Kernel Development di Robert Love (capitolo 12, pagina 244 della 3a edizione) risponde molto chiaramente.

Sì, la memoria fisicamente contigua non è richiesta in molti casi. Il motivo principale per cui kmalloc viene utilizzato più di vmalloc nel kernel è la prestazione. Il libro spiega che quando i grossi blocchi di memoria sono allocati usando vmalloc, il kernel deve mappare i blocchi (pagine) fisicamente non contigui in una singola regione di memoria virtuale contigua. Poiché la memoria è praticamente contigua e fisicamente non contigua, alla tabella della pagina dovranno essere aggiunti diversi mapping di indirizzi da virtuale a fisico. E nel peggiore dei casi, ci sarà (dimensione del buffer / dimensione della pagina) numero di mappature aggiunte alla tabella delle pagine.

Ciò aumenta anche la pressione su TLB (le voci della cache che memorizzano i recenti mapping di indirizzi da virtuale a fisico) quando si accede a questo buffer. Questo può portare a thrashing .

Il kmalloc () & amp; Le funzioni vmalloc () sono un'interfaccia semplice per ottenere la memoria del kernel in blocchi di dimensioni byte.

  1. La funzione kmalloc () garantisce che le pagine siano fisicamente contigue (e praticamente contigue).

  2. La funzione vmalloc () funziona in modo simile a kmalloc () , tranne che alloca memoria che è solo virtualmente contigua e non necessariamente fisicamente contigua.

Quali sono i vantaggi di avere un blocco di memoria contiguo? In particolare, perché dovrei avere un blocco fisico contiguo di memoria in una chiamata di sistema? C'è qualche motivo per cui non potrei semplicemente usare vmalloc?

Da Google " Mi sento fortunato " su vmalloc :

kmalloc è il modo preferito, purché non siano necessarie aree molto grandi. Il problema è che, se si desidera eseguire DMA da / verso un dispositivo hardware, è necessario utilizzare kmalloc e probabilmente sarà necessario un pezzo più grande. La soluzione è allocare la memoria il prima possibile, prima la memoria viene frammentata.

Su un sistema a 32 bit, kmalloc () restituisce l'indirizzo logico del kernel (è comunque un indirizzo virtuale) che ha il mapping diretto (in realtà con offset costante) sull'indirizzo fisico. Questa mappatura diretta assicura che otteniamo un pezzo fisico contiguo di RAM. Adatto per DMA in cui forniamo solo il puntatore iniziale e ci aspettiamo una mappatura fisica contigua successivamente per la nostra operazione.

vmalloc () restituisce l'indirizzo virtuale del kernel che a sua volta potrebbe non avere un mapping contiguo sulla RAM fisica. Utile per l'allocazione di memoria di grandi dimensioni e nei casi in cui non ci interessa che la memoria allocata al nostro processo sia continua anche nella RAM fisica.

Una delle altre differenze è che kmalloc restituirà l'indirizzo logico (altrimenti si specifica GPF_HIGHMEM). Gli indirizzi logici vengono inseriti in "memoria insufficiente" (nel primo gigabyte di memoria fisica) e vengono mappati direttamente su indirizzi fisici (utilizzare la macro __pa per convertirla). Questa proprietà implica che la memoria a km km è memoria continua.

D'altra parte, Vmalloc è in grado di restituire indirizzi virtuali da "alta memoria". Questi indirizzi non possono essere convertiti in indirizzi fisici in modo diretto (devi usare la funzione virt_to_page).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top