Ubuntu 19.10 server è stato rilasciato recentemente con il supporto ufficiale per Raspberry Pi 4 SBC.
I primi utenti ad averlo installato hanno da subito iniziato a lamentare problemi di utilizzo delle porte USB; Canonical ha immediatamente spiegato che il bug riguarda solo le board Raspberry Pi 4 con 4 GB di RAM, poichè in seguito ad alcuni test, l’interfaccia USB si è rivelata perfettamente funzionante sui Raspberry Pi 4 da 1 GB e 2 GB di RAM.
Il problema è stato identificato ed è stato riscontrato un bug del kernel. Nel frattempo, nel caso in cui si intenda lavorare su una board da 4 GB, è possibile ripristinare l’accesso alle porte USB limitando la memoria a 3 GB in /boot/firmware/usercfg.txt come segue:
total_mem=3072
Dopo attenta riflessione e gran parlare all’interno della community, il problema sembra essere stato identificato in quello che è normalmente conosciuto come “Bounce Buffer” o “Buffer di rimbalzo“.
I buffer di rimbalzo sono necessari per i dispositivi che non possono accedere all’intera gamma di memoria disponibile per la CPU. Un esempio sono i dispositivi a 32 bit su architetture a 64 bit o recenti processori Intel con PAE abilitato.
Un buffer di rimbalzo si trova in una porzione bassa di memoria in modo da consentire a un dispositivo di copiare e scrivere i dati. Viene quindi copiato nella pagina utente desiderata in memoria alta. Questa copia aggiuntiva non è esente dal creare problemi, tuttavia è inevitabile. Le pagine sono allocate in memoria è vengono utilizzate come pagine buffer per l’accesso diretto alla memoria (DMA) da e verso il dispositivo. Questo viene quindi copiato dal kernel nella pagina del buffer nella parte alta della memoria utente, quando viene completato l’I/O. Il buffer di rimbalzo funge praticamente da “ponte” tra le aree della memoria accessibile alla CPU e le aree nelle quali la CPU non riesce ad arrivare. Il problema di fondo è dato dal notevole consumo di risorse per questa operazione. il consumo di risorse, comunque elevato, risulta inferiore alla copia (swap) di un’intera pagina in memoria virtuale, ed è quindi più conveniente.
Quando un’applicazione deve inviare dati alle porte USB, un puntatore dello spazio utente verrà passato a una chiamata di sistema. A questo punto, il driver o il framework possono scegliere se copiare i dati in un buffer intermedio per la trasmissione o se tentare di utilizzarli direttamente. L’utilizzo del DMA aiuta nel primo caso perché può garantire che il buffer intermedio si trovi in una posizione sicura. Non aiuta invece nel secondo caso perché quelle pagine utente potrebbero trovarsi in un indirizzo della RAM inaccessibile al processo. pertanto il driver PCIe si aggancia ai metodi DMA per il dispositivo USB eseguendo una copia nel punto in cui il buffer viene mappato per DMA, restituendo l’indirizzo del buffer di rimbalzo anziché le pagine utente.
In poche parole, la versione 19.10 di Ubuntu Server per Raspberry PI 4 non implementa nativamente i bounce buffers per la memoria da 4 GB, rendendo pertanto inaccessibile l’USB.
In attesa di una patch ufficiale Canonical che risolva il problema, è possibile installare una patch non ufficiale al seguente link.