[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230102183716.9698-1-federico.vaga@vaga.pv.it>
Date: Mon, 2 Jan 2023 19:37:16 +0100
From: Federico Vaga <federico.vaga@...a.pv.it>
To: Jonathan Corbet <corbet@....net>
Cc: Federico Vaga <federico.vaga@...a.pv.it>,
linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH V2] doc:it_IT: add translation for botching-up-ioctl.rst
This patch adds the translation for the botching up ioctl document.
Signed-off-by: Federico Vaga <federico.vaga@...a.pv.it>
---
V1 -> V2 use the kernel-doc mecanism to link functions in documents
.../it_IT/process/botching-up-ioctls.rst | 249 ++++++++++++++++++
.../translations/it_IT/process/index.rst | 1 +
2 files changed, 250 insertions(+)
create mode 100644 Documentation/translations/it_IT/process/botching-up-ioctls.rst
diff --git a/Documentation/translations/it_IT/process/botching-up-ioctls.rst b/Documentation/translations/it_IT/process/botching-up-ioctls.rst
new file mode 100644
index 000000000000..91732cdf808a
--- /dev/null
+++ b/Documentation/translations/it_IT/process/botching-up-ioctls.rst
@@ -0,0 +1,249 @@
+.. include:: ../disclaimer-ita.rst
+
+:Original: Documentation/process/botching-up-ioctls.rst
+
+==========================================
+(Come evitare di) Raffazzonare delle ioctl
+==========================================
+
+Preso da: https://blog.ffwll.ch/2013/11/botching-up-ioctls.html
+
+Scritto da : Daniel Vetter, Copyright © 2013 Intel Corporation
+
+Una cosa che gli sviluppatori del sottosistema grafico del kernel Linux hanno
+imparato negli ultimi anni è l'inutilità di cercare di creare un'interfaccia
+unificata per gestire la memoria e le unità esecutive di diverse GPU. Dunque,
+oggigiorno ogni driver ha il suo insieme di ioctl per allocare memoria ed
+inviare dei programmi alla GPU. Il che è va bene dato che non c'è più un insano
+sistema che finge di essere generico, ma al suo posto ci sono interfacce
+dedicate. Ma al tempo stesso è più facile incasinare le cose.
+
+Per evitare di ripetere gli stessi errori ho preso nota delle lezioni imparate
+mentre raffazzonavo il driver drm/i915. La maggior parte di queste lezioni si
+focalizzano sui tecnicismi e non sulla visione d'insieme, come le discussioni
+riguardo al modo migliore per implementare una ioctl per inviare compiti alla
+GPU. Probabilmente, ogni sviluppatore di driver per GPU dovrebbe imparare queste
+lezioni in autonomia.
+
+
+Prerequisiti
+------------
+
+Prima i prerequisiti. Seguite i seguenti suggerimenti se non volete fallire in
+partenza e ritrovarvi ad aggiungere un livello di compatibilità a 32-bit.
+
+* Usate solamente interi a lunghezza fissa. Per evitare i conflitti coi tipi
+ definiti nello spazio utente, il kernel definisce alcuni tipi speciali, come:
+ ``__u32``, ``__s64``. Usateli.
+
+* Allineate tutto alla lunghezza naturale delle piattaforma in uso e riempite
+ esplicitamente i vuoti. Non necessariamente le piattaforme a 32-bit allineano
+ i valori a 64-bit rispettandone l'allineamento, ma le piattaforme a 64-bit lo
+ fanno. Dunque, per farlo correttamente in entrambe i casi dobbiamo sempre
+ riempire i vuoti.
+
+* Se una struttura dati contiene valori a 64-bit, allora fate si che la sua
+ dimensione sia allineata a 64-bit, altrimenti la sua dimensione varierà su
+ sistemi a 32-bit e 64-bit. Avere una dimensione differente causa problemi
+ quando si passano vettori di strutture dati al kernel, o quando il kernel
+ effettua verifiche sulla dimensione (per esempio il sistema drm lo fa).
+
+* I puntatori sono di tipo ``__u64``, con un *cast* da/a ``uintptr_t`` da lato
+ spazio utente e da/a ``void __user *`` nello spazio kernel. Sforzatevi il più
+ possibile per non ritardare la conversione, o peggio maneggiare ``__u64`` nel
+ vostro codice perché questo riduce le verifiche che strumenti come sparse
+ possono effettuare. La macro u64_to_user_ptr() può essere usata nel kernel
+ per evitare avvisi riguardo interi e puntatori di dimensioni differenti.
+
+
+Le Basi
+-------
+
+Con la gioia d'aver evitato un livello di compatibilità, possiamo ora dare uno
+sguardo alle basi. Trascurare questi punti renderà difficile la gestione della
+compatibilità all'indietro ed in avanti. E dato che sbagliare al primo colpo è
+garantito, dovrete rivisitare il codice o estenderlo per ogni interfaccia.
+
+* Abbiate un modo chiaro per capire dallo spazio utente se una nuova ioctl, o
+ l'estensione di una esistente, sia supportata dal kernel in esecuzione. Se non
+ potete fidarvi del fatto che un vecchio kernel possa rifiutare correttamente
+ un nuovo *flag*, modalità, o ioctl, (probabilmente perché avevate raffazzonato
+ qualcosa nel passato) allora dovrete implementare nel driver un meccanismo per
+ notificare quali funzionalità sono supportate, o in alternativa un numero di
+ versione.
+
+* Abbiate un piano per estendere le ioctl con nuovi *flag* o campi alla fine di
+ una struttura dati. Il sistema drm verifica la dimensione di ogni ioctl in
+ arrivo, ed estende con zeri ogni incongruenza fra kernel e spazio utente.
+ Questo aiuta, ma non è una soluzione completa dato che uno spazio utente nuovo
+ su un kernel vecchio non noterebbe che i campi nuovi alla fine della struttura
+ vengono ignorati. Dunque, anche questo avrà bisogno di essere notificato dal
+ driver allo spazio utente.
+
+* Verificate tutti i campi e *flag* inutilizzati ed i riempimenti siano a 0,
+ altrimenti rifiutare la ioctl. Se non lo fate il vostro bel piano per
+ estendere le ioctl andrà a rotoli dato che qualcuno userà delle ioctl con
+ strutture dati con valori casuali dallo stack nei campi inutilizzati. Il che
+ si traduce nell'avere questi campi nell'ABI, e la cui unica utilità sarà
+ quella di contenere spazzatura. Per questo dovrete esplicitamente riempire i
+ vuoti di tutte le vostre strutture dati, anche se non le userete in un
+ vettore. Il riempimento fatto dal compilatore potrebbe contenere valori
+ casuali.
+
+* Abbiate un semplice codice di test per ognuno dei casi sopracitati.
+
+
+Divertirsi coi percorsi d'errore
+--------------------------------
+
+Oggigiorno non ci sono più scuse rimaste per permettere ai driver drm di essere
+sfruttati per diventare root. Questo significa che dobbiamo avere una completa
+validazione degli input e gestire in modo robusto i percorsi - tanto le GPU
+moriranno comunque nel più strano dei casi particolari:
+
+ * Le ioctl devono verificare l'overflow dei vettori. Inoltre, per i valori
+ interi si devono verificare *overflow*, *underflow*, e *clamping*. Il
+ classico esempio è l'inserimento direttamente nell'hardware di valori di
+ posizionamento di un'immagine *sprite* quando l'hardware supporta giusto 12
+ bit, o qualcosa del genere. Tutto funzionerà finché qualche strano *display
+ server* non decide di preoccuparsi lui stesso del *clamping* e il cursore
+ farà il giro dello schermo.
+
+ * Avere un test semplice per ogni possibile fallimento della vostra ioctl.
+ Verificate che il codice di errore rispetti le aspettative. Ed infine,
+ assicuratevi che verifichiate un solo percorso sbagliato per ogni sotto-test
+ inviando comunque dati corretti. Senza questo, verifiche precedenti
+ potrebbero rigettare la ioctl troppo presto, impedendo l'esecuzione del
+ codice che si voleva effettivamente verificare, rischiando quindi di
+ mascherare bachi e regressioni.
+
+ * Fate si che tutte le vostre ioctl siano rieseguibili. Prima di tutto X adora
+ i segnali; secondo questo vi permetterà di verificare il 90% dei percorsi
+ d'errore interrompendo i vostri test con dei segnali. Grazie all'amore di X
+ per i segnali, otterrete gratuitamente un eccellente copertura di base per
+ tutti i vostri percorsi d'errore. Inoltre, siate consistenti sul modo di
+ gestire la riesecuzione delle ioctl - per esempio, drm ha una piccola
+ funzione di supporto `drmIoctl` nella sua librerie in spazio utente. Il
+ driver i915 l'abbozza con l'ioctl `set_tiling`, ed ora siamo inchiodati per
+ sempre con una semantica arcana sia nel kernel che nello spazio utente.
+
+
+ * Se non potete rendere un pezzo di codice rieseguibile, almeno rendete
+ possibile la sua interruzione. Le GPU moriranno e i vostri utenti non vi
+ apprezzeranno affatto se tenete in ostaggio il loro scatolotto (mediante un
+ processo X insopprimibile). Se anche recuperare lo stato è troppo complicato,
+ allora implementate una scadenza oppure come ultima spiaggia una rete di
+ sicurezza per rilevare situazioni di stallo quando l'hardware da di matto.
+
+ * Preparate dei test riguardo ai casi particolarmente estremi nel codice di
+ recupero del sistema - è troppo facile create uno stallo fra il vostro codice
+ anti-stallo e un processo scrittore.
+
+
+Tempi, attese e mancate scadenze
+--------------------------------
+
+Le GPU fanno quasi tutto in modo asincrono, dunque dobbiamo regolare le
+operazioni ed attendere quelle in sospeso. Questo è davvero difficile; al
+momento nessuna delle ioctl supportante dal driver drm/i915 riesce a farlo
+perfettamente, il che significa che qui ci sono ancora una valanga di lezioni da
+apprendere.
+
+ * Per fare riferimento al tempo usate sempre ``CLOCK_MONOTONIC``. Oggigiorno
+ questo è quello che viene usato di base da alsa, drm, e v4l. Tuttavia,
+ lasciate allo spazio utente la possibilità di capire quali *timestamp*
+ derivano da domini temporali diversi come il vostro orologio di sistema
+ (fornito dal kernel) oppure un contatore hardware indipendente da qualche
+ parte. Gli orologi divergeranno, ma con questa informazione gli strumenti di
+ analisi delle prestazioni possono compensare il problema. Se il vostro spazio
+ utente può ottenere i valori grezzi degli orologi, allora considerate di
+ esporre anch'essi.
+
+ * Per descrivere il tempo, usate ``__s64`` per i secondi e ``__u64`` per i
+ nanosecondi. Non è il modo migliore per specificare il tempo, ma è
+ praticamente uno standard.
+
+ * Verificate che gli input di valori temporali siano normalizzati, e se non lo
+ sono scartateli. Fate attenzione perché la struttura dati ``struct ktime``
+ del kernel usa interi con segni sia per i secondi che per i nanosecondi.
+
+ * Per le scadenze (*timeout*) usate valori temporali assoluti. Se siete dei
+ bravi ragazzi e avete reso la vostra ioctl rieseguibile, allora i tempi
+ relativi tendono ad essere troppo grossolani e a causa degli arrotondamenti
+ potrebbero estendere in modo indefinito i tempi di attesa ad ogni
+ riesecuzione. Particolarmente vero se il vostro orologio di riferimento è
+ qualcosa di molto lento come il contatore di *frame*. Con la giacca da
+ avvocato delle specifiche diremmo che questo non è un baco perché tutte le
+ scadenze potrebbero essere estese - ma sicuramente gli utenti vi odieranno
+ quando le animazioni singhiozzano.
+
+ * Considerate l'idea di eliminare tutte le ioctl sincrone con scadenze, e di
+ sostituirle con una versione asincrona il cui stato può essere consultato
+ attraverso il descrittore di file mediante ``poll``. Questo approccio si
+ sposa meglio in un applicazione guidata dagli eventi.
+
+ * Sviluppate dei test per i casi estremi, specialmente verificate che i valori
+ di ritorno per gli eventi già completati, le attese terminate con successo, e
+ le attese scadute abbiano senso e servano ai vostri scopi.
+
+
+Non perdere risorse
+-------------------
+Nel suo piccolo il driver drm implementa un sistema operativo specializzato per
+certe GPU. Questo significa che il driver deve esporre verso lo spazio
+utente tonnellate di agganci per accedere ad oggetti e altre risorse. Farlo
+correttamente porterà con se alcune insidie:
+
+ * Collegate sempre la vita di una risorsa creata dinamicamente, a quella del
+ descrittore di file. Considerate una mappatura 1:1 se la vostra risorsa
+ dev'essere condivisa fra processi - passarsi descrittori di file sul socket
+ unix semplifica la gestione anche per lo spazio utente.
+
+ * Dev'esserci sempre Il supporto ``O_CLOEXEC``.
+
+ * Assicuratevi di avere abbastanza isolamento fra utenti diversi. Di base
+ impostate uno spazio dei nomi riservato per ogni descrittore di file, il che
+ forzerà ogni condivisione ad essere esplicita. Usate uno spazio più globale
+ per dispositivo solo se gli oggetti sono effettivamente unici per quel
+ dispositivo. Un controesempio viene dall'interfaccia drm modeset, dove
+ oggetti specifici di dispositivo, come i connettori, condividono uno spazio
+ dei nomi con oggetti per il *framebuffer*, ma questi non sono per niente
+ condivisi. Uno spazio separato, privato di base, per i *framebuffer* sarebbe
+ stato meglio.
+
+ * Pensate all'identificazione univoca degli agganci verso lo spazio utente. Per
+ esempio, per la maggior parte dei driver drm, si considera fallace la doppia
+ sottomissione di un oggetto allo stesso comando ioctl. Ma per evitarlo, se
+ gli oggetti sono condivisibili, lo spazio utente ha bisogno di sapere se il
+ driver ha importato un oggetto da un altro processo. Non l'ho ancora provato,
+ ma considerate l'idea di usare il numero di inode come identificatore per i
+ descrittori di file condivisi - che poi è come si distinguono i veri file.
+ Sfortunatamente, questo richiederebbe lo sviluppo di un vero e proprio
+ filesystem virtuale nel kernel.
+
+
+Ultimo, ma non meno importante
+------------------------------
+
+Non tutti i problemi si risolvono con una nuova ioctl:
+
+* Pensateci su due o tre volte prima di implementare un'interfaccia privata per
+ un driver. Ovviamente è molto più veloce seguire questa via piuttosto che
+ buttarsi in lunghe discussioni alla ricerca di una soluzione più generica. Ed
+ a volte un'interfaccia privata è quello che serve per sviluppare un nuovo
+ concetto. Ma alla fine, una volta che c'è un'interfaccia generica a
+ disposizione finirete per mantenere due interfacce. Per sempre.
+
+* Considerate interfacce alternative alle ioctl. Gli attributi sysfs sono molto
+ meglio per impostazioni che sono specifiche di un dispositivo, o per
+ sotto-oggetti con una vita piuttosto statica (come le uscite dei connettori in
+ drm con tutti gli attributi per la sovrascrittura delle rilevazioni). O magari
+ solo il vostro sistema di test ha bisogno di una certa interfaccia, e allora
+ debugfs (che non ha un'interfaccia stabile) sarà la soluzione migliore.
+
+Per concludere. Questo gioco consiste nel fare le cose giuste fin da subito,
+dato che se il vostro driver diventa popolare e la piattaforma hardware longeva
+finirete per mantenere le vostre ioctl per sempre. Potrete tentare di deprecare
+alcune orribili ioctl, ma ci vorranno anni per riuscirci effettivamente. E
+ancora, altri anni prima che sparisca l'ultimo utente capace di lamentarsi per
+una regressione.
diff --git a/Documentation/translations/it_IT/process/index.rst b/Documentation/translations/it_IT/process/index.rst
index 8d4e36a07ff4..25602c1a97d1 100644
--- a/Documentation/translations/it_IT/process/index.rst
+++ b/Documentation/translations/it_IT/process/index.rst
@@ -58,6 +58,7 @@ perché non si è trovato un posto migliore.
adding-syscalls
magic-number
volatile-considered-harmful
+ botching-up-ioctls
clang-format
../riscv/patch-acceptance
--
2.30.2
Powered by blists - more mailing lists