Category Archives: Kernel

Il driver Nvidia e il problema di num_physpages

A luglio Linus Torvald rimosse la variabile num_physpages dalla versione 3.11 del kernel di Linux. Questa decisione ha però determinato una conflittualità tra il codice sorgente del driver fornito da Nvidia e il kernel stesso. La num_physpages era definita nel gestore mm della memoria di Linux.

Oggi, l’ultimo driver stabile di Nvidia è il 319.60 e ci sono ancora i riferimenti alla variabile suddetta nel file d’intestazione nv-linux.h. Se anche voi avete una distribuzione con il kernel 3.11 (o più recente) e tentate, come ho fatto io, di compilare il driver per le schede video, otterrete il seguente messaggio di errore:


In file included from /tmp/selfgz4790/NVIDIA-Linux-x86_64-319.49/kernel/os-interface.c:26:0:
   /tmp/selfgz4790/NVIDIA-Linux-x86_64-319.49/kernel/os-interface.c: In function ‘os_get_system_memory_size’:
   /tmp/selfgz4790/NVIDIA-Linux-x86_64-319.49/kernel/nv-linux.h:1040:41: error: ‘num_physpages’ undeclared (first use in this function)
    #define NV_NUM_PHYSPAGES                num_physpages
                                            ^

Come già detto, num_physpages è stata tolta da Torvalds, quindi per il momento non c’è altra soluzione che correggere il file nv-linux.h del driver con una patch oppure un editor di testo. Potete scaricare la patch dalla Rete, ma si tratta di un file specifico per una particolare versione del driver di Nvidia che dovreste adattare alla vostra situazione. A questo indirizzo troverete le istruzioni per procedere nel modo corretto. Oltre a servirvi di una patch, in alternativa potete modificare il file nv-linux.h durante l’installazione del driver, per esempio seguendo questa procedura:

  1. Eseguite l’installer di Nvidia con l’opzione -x, il comando decomprirà l’archivio che contiene il codice sorgente del driver.
  2. Modificate il file nv-linux.h, che trovate nella directory kernel, con un editor, vi oppure gedit vanno benissimo.
  3. Cercate la riga che ha la seguente definizione in linguaggio C #define NV_NUM_PHYSPAGES   num_physpages, dovreste trovarla inserita fra altre definizioni, esattamente come nell’esempio sottostante:
    
    #if !defined(NV_VMWARE):
    #define NV_NUM_PHYSPAGES                num_physpages
    #define NV_GET_CURRENT_PROCESS()        current->tgid
    #define NV_IN_ATOMIC()                  in_atomic()
    
  4. Dopo la riga corrispondente all’istruzione condizionale #if, ma prima della definizione #define NV_GET_CURRENT_PROCESS ecc. dovete creare un nuovo blocco che corrisponda al seguente codice per il preprocessore C:
    
    #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(3, 11, 0)</p>
    #define NV_NUM_PHYSPAGES                get_num_physpages()
    #else</p>
    #define NV_NUM_PHYSPAGES                num_physpages
    #endif
    
  5. Ultimate le vostre modifiche, avrete esattamente questo:
    
    #if !defined(NV_VMWARE)
    #if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(3, 11, 0)</p>
    #define NV_NUM_PHYSPAGES                get_num_physpages()
    #else
    #define NV_NUM_PHYSPAGES                num_physpages
    #endif</p>
    #define NV_GET_CURRENT_PROCESS()        current-&gt;tgid
    #define NV_IN_ATOMIC()
    
  6. Potete ora chiudere l’editor ed eseguire il comando nvidia-installer che trovate nella directory principale del driver.

Ubuntu 13.10 è in circolazione da poco tempo e utilizza un kernel recentissimo che non è compatibile con il driver per le schede video GeForce. Il bug dovrebbe essere ormai già noto ai programmatori di Nvidia, anche se il problema non sembra molto diffuso fra gli utenti. In questo caso è bastato cercare la patch con un motore di ricerca, usando i termini num_physpage, kernel 3.11 e Nvidia. Vista l’importanza raggiunta da Linux, e in particolare dalla distribuzione Ubuntu, mi aspetto da un giorno all’altro un driver che sia compatibile con il recente kernel 3.11 e 3.12.