Automazione di Test di Sistemi Embedded UNIVERSITA’ DEGLI STUDI DI MILANO BICOCCA FACOLTA’ DI SCIENZE MATEMATICHE, FISICHE E NATURALI Corso di Laurea Magistrale in Informatica Automazione di Test di Sistemi Embedded Relatore: Prof. Mauro PEZZE’ Correlatori: Lorena SIMONI Giuseppe GORGOGLIONE Relazione della prova finale di: Carmine Carella Matricola: 055465 Anno Accademico 2009/2010
Indice Il Software nei sistemi embedded Testing nei sistemi embedded Automazione del Testing Il Progetto Cartesio Contributo della Tesi Attività di testing Conclusioni
Il SW nei Sistemi Embedded TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Il SW nei Sistemi Embedded Incidenza percentuale dei sistemi embedded nel costo finale dei prodotti (1) Mercato globale dei sistemi embedded in miliardi di dollari (1) Sistemi embedded I sistemi embedded sono sistemi di elaborazione progettati per una determinata applicazione e supportati da una piattaforma hardware dedicata. La loro diffusione è inarrestabile, sono ormai rilevanti in ogni settore applicativo. I dati mostrano che circa la metà del costo finale di un prodotto è rappresentato dal sistema embedded (animazione) Sono una combinazione di hardware e software, tra loro fortemente integrati. Software Sono diventati molto complessi e il software contenuto in essi è diventato un elemento chiave, perfino più importante dell'hardware stesso, in quanto è la componente che permette di aumentare le funzionalità del sistema e di ottenere un minimo di flessibilità, in questi sistemi caratterizzati dall'essere poco versatili. Il software è la componente che negli ultimi anni ha avuto il tasso di crescita maggiore. (animazione) Tipologie software Esso, comprende i sistemi operativi, gli ambienti di sviluppo, gli strumenti per il testing. Gli strumenti per il testing sono quelli che hanno la crescita minore. (animazione) Questi dati non tengono conto degli strumenti realizzati ad-hoc, in quanto non sono componenti standard, ma specifici per un dato progetto. Come vedremo successivamente questo è uno dei principali problemi del testing in ambito embedded. Sono sempre più utilizzati sistemi operativi (animazione) e questo testimonia l'interesse dei produttori, oltre che verso i tradizionali microcontrollori, anche nella direzione dei processori di classe superiore (i più diffusi PowerPC e ARM), in grado di ospitare un sistema operativo con interfacce utente evolute. Tipologie Sistemi Operativi I sistemi operativi vanno dalle soluzioni commerciali e proprietarie, come WinCE e Windriver all'open source di Linux. L'utilizzo di quest’ultimo è cresciuto negli anni e risulta il più utilizzato nell'ambito embedded. (animazione) La tesi si focalizza sul testing nell’ambito Linux embedded. Utilizzo recente dei sistemi operativi per sistemi embedded (1) Fatturato del software embedded per categoria(1) (AAGR - Average Annual Growth Rate) (1) Brandolese, C. and Fornaciari, W., Sistemi Embedded - sviluppo hardware e software per sistemi dedicati, 2007, Mondadori
Testing nei Sistemi Embedded TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Testing nei Sistemi Embedded Fasi Tipologie di Testing Software Processore Sistema Ambiente Simulazione One way Simulato - Feedback Rapid prototyping Sperimentale Reale Prototipazione Test unità/integrazione sw (1) Sperimentale/reale (host) Host Test unità/integrazione sw (2) Reale (finale) Emulatore Test unità/integrazione hw Test integrazione hw/sw Reale(finale) Test di sistema Prototipo Test ambientale Prototipo maturo Pre-produzione Post-produzione Test mantenimento Conseguenza diretta dell'evoluzione e della criticità del software, è la crescita dell'importanza del processo di testing. Rispetto ad altri ambiti, quello embedded introduce requisiti di criticità da un lato e prestazionali dall’altro, che hanno bisogno di maggiore attenzione. Il testing permette valutare questi requisiti e garantire la qualità. Il processo di testing di sistemi embedded consiste di diverse fasi. In ogni fase sono applicate diverse tipologie di test, che si differenziano in base all’ambiente di test caratterizzato dalle diverse componenti hw e dal fatto che esse siano simulate, reali, sperimentali o prototipali. La fase di prototipazione è quella in cui almeno il sw e il processore sono reali e corrisponde alla fase dell’ambiente sperimentale della tesi. In particolare il test di integrazione hw/sw e il test di sistema sono quelli su cui è concentrato il lavoro, attraverso la sperimentazione di strumenti per questi tipi di test.
Gli ambienti di Testing TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Gli ambienti di Testing Ambiente Host Ambiente di sviluppo Host-testing Ambiente Target Ambiente di esecuzione Target-testing Cross-compilazione Approccio simulativo tramite emulazione di piattaforma Test integrazione hw/sw Test di sistema La fase di prototipazione è quella in cui emerge la principale differenza con il testing di software tradizionale, in quanto è la fase in cui si ha il passaggio verso un sistema che diventa sempre più reale. La modalità di sviluppo del sw embedded, prevede host e target (descrizione), porta ad avere due ambienti per il test, in cui applicare tecniche diverse per valutare requisiti di qualità differenti. Il testing nell’ambiente host segue approcci simulativi, a causa della indisponibilità della piattaforma specifica. Il testing nell’ambiente Target è importante in quanto la forte relazione tra hw e sw, rende pressoché impossibile sviluppare e testare il software indipendentemente dall'hardware su cui dovrà essere eseguito. Si deve verificare che il codice operi correttamente sulla piattaforma sotto condizioni realistiche. Il test di integrazione hw/sw e il test di sistema sono eseguiti nell’ambiente target e permettono di verificare le caratteristiche non funzionali del sw. Quello su cui si focalizza il lavoro è il testing nell’ambiente target. Verifica delle caratteristiche non funzionali del SW
Automazione del testing TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Automazione del testing Importanza: migliora efficacia ed efficienza del testing Problema: Soluzioni ad-hoc (application-specific) Metodologie interne aziendali Letteratura scarsa e approcci poco concreti Soluzione proposta: personalizzazione di strumenti off-the-shelf per adattarli all’architettura specifica in modo garantire il corretto funzionamento dello strumento di automazione Per supportare il processo di testing l’Automazione è fondamentale, in quanto permette di migliorare l'efficacia e l'accuratezza delle attività, rilevando un maggior numero di difetti, e l'efficienza, diminuendo il costo e il tempo dell'esecuzione. L'automazione permettere di eseguire attività che manualmente non sarebbero fattibili. Essa si concretizza attraverso attraverso l’utilizzo di strumenti. Nell’ambiente target soffre di diversi problemi. Problema - Approcci ad-hoc Data la specificità dei sistemi embedded, ogni sistema ha aspetti peculiari (architettura hw/sw si differenziano da un sistema ad un altro), l’approccio corrente è sviluppare strumenti per ogni ambiente specifico che funzionano solo su quel particolare sistema. Questa è una soluzione molto costosa e poco efficiente. Attualmente, il test di sw embedded è formalizzato soltanto con metodologie aziendali interne (non diffuse) e quindi tecniche e strumenti proprietari, che non sono applicabili in qualunque contesto. Per questo la letteratura sul testing di software embedded, è molto scarsa e contiene approcci poco concreti. Soluzione La soluzione che viene proposta, è un approccio che consiste nello scegliere strumenti off-the-shelf(scielf) e personalizzarli per il sistema specifico. Si tratta di considerare strumenti generali-soluzioni esistenti (application-independent), ben collaudati, e adattarli all’architettura del sistema. La personalizzazione consiste di adattamenti di basso livello all'architettura di uno specifico processore per rendere funzionante lo strumento. [Quindi, se con l’approccio ad-hoc, l’automazione è garantita costruendo uno strumento per il problema specifico, l’approccio proposto consiste nel adattare al problema specifico uno strumento generale.]
Test funzionali e strutturali TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Il Progetto Cartesio Board ST PND Customer SERIAL PORT GPIO USB CLCD TOUCHPANEL SDCARD GPS AUDIO NAND KEYBOARD GUI e applicazioni proprietarie BSP customizzato Graphic POWER MANAGEMENT ETHERNET BSP linux Cartesio Sviluppo e testing sw in STM PROCESSO TESTING Test object: device driver manual and automatic test suite Test funzionali e strutturali Test report: excel Sviluppo BSP LINUX CARTESIO Firmware Bootloader Kernel + (BSP) device driver Command line interface La soluzione proposta è stata valutata in modo concreto in un’ambiente sperimentale che è quello della divisione Automotive di STMicroelectronics (STM), Hardware la quale ha ideato una nuova famiglia di System-on-Chip dal nome Cartesio con un alto livello di integrazione di device su un singolo chip. Il core è costituito dal microcontrollore ARM che permette il supporto per un vasto insieme di periferiche. Comprende un chip GPS. Prodotto ideale per navigatori satellitari e per l'infotainment. Per lo sviluppo, Cartesio è montato su board di validazione, progettate da STM. Queste board, permettono di verificare il funzionamento del SOC con le periferiche esterne. Software Lo sviluppo software del sistema embedded, consiste nel porting del sistema operativo Linux per la piattaforma Cartesio; intendiamo il kernel, senza ulteriori strati software, quali interfacce grafiche e applicazioni. Effettuare il porting vuol dire configurare in modo corretto il kernel, ma soprattutto sviluppare il base port (BSP), lo strato software di base che contiene i device driver che astraggono il SOC e la board e consentono di eseguire il kernel linux sulla piattaforma specifica. Customer Il BSP viene fornito al cliente come strato software di base che può essere personalizzato per il proprio prodotto, ed esteso con livelli software di più alto livello, come ad esempio interfacce grafiche (GUI) e applicazioni. Processo di testing Oltre allo sviluppo, il gruppo APG svolge anche un attività di testing del BSP, sulla piattaforma hardware di riferimento, al fine di garantire la piena qualità del prodotto finale. I test verificano le funzionalità dei driver, ovvero che essi gestiscano le periferiche relative offrendo le corrette operazioni per interagire. Ci sono due tipi di test: test funzionale: verifica che il driver di una periferica operi correttamente (ad esempio, l'operazione di scrittura di un file su un device USB); test strutturale: verifica di funzionalità più complesse che coinvolgono più driver (ad esempio il playback di un file audio da un device MMC). Device Driver Il focus dei test esistenti ma anche delle attività sperimentate, non è tanto il kernel Linux che può essere considerato un elemento standard, di buona qualità, ma lo strato software che viene sviluppato da zero nel porting di un sistema operativo, ovvero i device driver.
prestazioni codice in fase di boot dispositivi di mass storage TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Contributo della Tesi Analisi fattibilità e costi della soluzione adottata: Valutazione caratteristiche non funzionali del sw nell’ambiente target attraverso 4 attivita’ di testing rilevanti nel processo di testing del BSP Linux Cartesio Attività di Testing Classe problemi analizzati Requisiti di Qualità prestazioni codice in fase di boot punti critici del software con maggiore tempo di esecuzione nella fase di boot prestazioni uso e gestione della memoria memory leak prestazioni, affidabilità prestazioni di I/O su dispositivi di mass storage scarsa efficienza delle operazioni di I/O (lettura, scrittura) test di copertura problemi nell’efficacia dei test funzionali e strutturali dell’ambiente sperimentale copertura Scopo della tesi è analizzare la fattibilità e i costi della soluzione proposta, limitatamente a 4 attività di testing, per la valutazione di caratteristiche non funzionali del sw. Attività non scelte a caso, Rilevanti nei sistemi embedded, Analizzando Il processo di testing del BSP Cartesio in ST, non sono coperte, La loro introduzione permette di aumentare il perimetro del processo e anche la qualità del BSP. Per ogni attività considerata: viene effettuata una scelta di uno strumento per automatizzarla, in funzione di una serie parametri derivati dall’ambiente sperimentale. Le risorse computazionali disponibili nell’ambiente target, ridotte rispetto all'ambiente host, influenzano la scelta. Successivamente è valutata la personalizzazione dello strumento per il sistema specifico. Infine è applicato per derivare i risultati. Le attività di testing sperimentate nell’ambiente target sono: la valutazione delle prestazioni del codice nella fase di boot del sistema la verifica del corretto utilizzo e gestione della memoria da parte del sw la valutazione delle prestazioni del codice nell’esecuzione delle operazioni sui dispositivi di memorizzazione la valutazione della copertura dei test funzionali e strutturali utilizzati nell’ambiente sperimentale. Per motivi di tempo, in questa presentazione metto a fuoco solo la valutazione delle prestazioni del codice nella fase di boot. Le altre le presento rapidamente.
Valutazione delle Prestazioni del Codice nella Fase di Boot (1) TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Valutazione delle Prestazioni del Codice nella Fase di Boot (1) Obiettivi e Scelta Strumento: Profiling: strategia per valutare le prestazioni del codice Function Tracing - tecnica di profiling per valutazione di: Prestazioni funzioni kernel eseguite al boot Funzioni dei device driver Analisi e scelta strumento di automazione Bootchart Ftrace Ftrace: framework del kernel Linux Function Graph Tracer: Misura il tempo di esecuzione delle funzioni (durata delle funzioni) Costruisce il grafo delle chiamate Debug filesystem per esportare i risultati nello user-space Obiettivi La prima attività di testing sperimentata è utile per valutare e migliorare il tempo di boot del sistema. Per fare questo, utilizziamo il profiling (strategia) e per identificare percorsi critici e colli di bottiglia sui quali vale la pena concentrarsi maggiormente per eseguire ottimizzazioni e migliorare le prestazioni. In particolare è utilizzata una tecnica di profiling (Function Tracing) per valutare le prestazioni delle funzioni del kernel eseguite nella fase di boot, con attenzione particolare alle funzioni del codice dell’architettura specifica (device driver). Scelta strumento Nell’ambito open–source sono stati individuati due strumenti che soddisfano gli obiettivi. Dei due è stato scelto Ftrace, in quanto Bootchart: strumento per sistemi desktop Linux, dall’analisi effettuata introduce, a causa della sua implementazione (interazione con uno shell-script lato user), delle perturbazioni nella misurazione dei tempi di esecuzione che sono trascurabili per sistemi desktop dove i tempi di boot sono dell’ordine delle decine di millisecondi, ma non per i sistemi embedded dove i tempi di boot sono dell’ordine delle centinai di millisecondi. La scelta è ricaduta su Ftrace. Quello che ci interessa è il Function Graph Tracer. Durata delle funzioni: tempo impiegato dal kernel per eseguire le funzioni. Differenza tra l’istante in cui il kernel entra nella funzione e l’istante in cui il kernel esce dalla funzione. Grafo delle chiamate per osservare le relazioni tra le funzioni e identificare il percorso intrapreso da esse. Debug filesystem di Linux (Ram-based)
Valutazione delle Prestazioni del Codice nella Fase di Boot (2) TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Valutazione delle Prestazioni del Codice nella Fase di Boot (2) Personalizzazione di Function Graph Tracer per l’applicazione su architettura ARM KERNEL Function{ probe } Mcount arch/arm/kernel/entry-common.S __gnu_mcount_mc invoca invoca Il Function Graph Tracer è sviluppato originariamente per l’architettura x86, non funziona in modo nativo per ARM. Necessaria la personalizzazione. In questa slide e nella successiva entro nei dettagli della personalizzazione di questo strumento per il nostro sistema, per mostrare quanto essa sia un lavoro non banale. Vediamo in cosa consiste. Il tracer utilizza l’instrumentazione implicita (automatica). L’instrumentazioe è eseguita dal compilatore GCC, che fa parte della toolchain di cross-compilazione. GCC compila il kernel e inserisce nel prologo di ciascuna funzione un probe, ovvero delle istruzioni per la chiamata alla routine mcount. Tale routine è invocata ogni volta che il kernel entra ed esce dalla funzione (perchè) essa chiama le funzioni del Function Graph Tracer per eseguire il tracciamento e calcolarne la durata di esecuzione. Il primo passo della personalizzazione dipende dal fatto che la routine mcount è specifica per ogni architettura (arch/arm/kernel/entry-common.S) e nel nostro caso quindi deve essere estesa per poter invocare il tracer scelto. Il secondo passo, consiste nell’inserire nel kernel la funzione __gnu_mcount_mc che sostituisce la mcount. Il motivo è che le versioni più recenti del compilatore instrumentano il codice con chiamate a questa funzione, come il compilatore utilizzato nella toolchain Cartesio. compila Function Graph Tracer GCC
Valutazione delle Prestazioni del Codice nella Fase di Boot (3) TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Valutazione delle Prestazioni del Codice nella Fase di Boot (3) Problema: valori durata non accurati Soluzione: utilizzo di un timer ad alta risoluzione Sottosistema time-management kernel Modifica driver del timer: arch/arm/mach-cartesio/time.c LR/HR Timer Framework Dopo l'applicazione di questi primi passi, il function graph tracer risulta configurabile nel kernel ed utilizzabile. Problema Ma durante l’applicazione mi sono accorto di un problema relativo all’accuratezza dei valori di durata delle funzioni. Il campo durata, conteneva sempre il valore zero microsecondi per circa 39.000 righe del risultato. Soluzione Per la risoluzione del problema è stato utile capire come il function graph tracer, recupera i valori temporali da utilizzare nel calcolo della durata delle funzioni. Lo fa sfruttando il sottosistema di gestione del tempo del kernel, che consiste di differenti livelli: Struttura sottosistema time-management Al livello più basso è presente l'hardware. In base all'architettura specifica, di solito ci sono più dispositivi timer, implementati da diversi clock chip, che forniscono valori di temporizzazione e sono utilizzati come sorgenti di clock di sistema. Alcuni sono a bassa risoluzione, altri ad alta risoluzione. I clock chip hardware devono essere gestiti dai driver platform-specific. Il sottosistema del kernel fornisce un livello di astrazione (dei framework) per garantire un interfaccia generica per tutti i clock chip, per effettuare ad esempio l'operazione di lettura del valore del timer. Vengono definite le API che il driver deve implementare. Il kernel Linux distingue due framework che forniscono timer differenti: timer a bassa risoluzione (LRTimer) dell’ordine dei millisecondi timer ad alta risoluzione (HRTimer), con una risoluzione nell'ordine dei nanosecondi. Sono arrivato alla conclusione quindi che la causa del problema era relativa al fatto che non veniva utilizzato dal tracer un timer ad alta risoluzione. Il terzo passo della personalizzazione consiste nel: Verificare che la piattaforma hardware disponga di un clock chip che fornisce valori ad alta risoluzione. Sulla piattaforma Cartesio è presente un timer con risoluzione di 1ns. Bisogna comprendere con quale API il tracer recupera le informazioni sul tempo. Lo fa attraverso la funzione sched_clock, messa a disposizione dal framework HR, che il driver del timer deve implementare. Per questo bisogna modificare il driver della piattaforma specifica per implementare tale funzione. L’implementazione consiste nel utilizzare la struttura di stato del driver che rappresenta il timer ad alta risoluzione. La struttura di stato, permette di astrarre i clock chip presenti sulla piattaforma hardware e implementa la funzione di più basso livello per interagire con l’hw. Struttura di Stato Struct clock_source Clock_source_read() invoca definisce API Sched-clock() API implementa Device driver timer chiama astrae Function Duration Tracer Hardware HR timer clock chip LR/HR Hardware clock chips
Strumento Post-Analisi TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Valutazione delle Prestazioni del Codice nella Fase di Boot (4) Risultati Sperimentali Ambiente Target Ambiete Host Debug file system User-space Risultati Strumento Post-Analisi FDD Startup sistema Risultati MMC Function Graph Tracer Kernel-space (Valori temporali in microsecondi) 0.18sec Dopo aver portato a termine la personalizzazione dello strumento sull’architettura specifica, è stato utilizzato per valutare la fase di boot con l’attenzione posta sulle funzioni dei driver. L’infrastruttura di test messa in piedi con Ftrace consiste nel Function Graph Tracer eseguito nella fase di boot sulla macchina target che esporta i risultati salvati su un file di testo nello user-space e successivamente questi sono portati sulla macchina host e analizzati da uno strumento di post-analisi come FDD che permette di effettuare un'analisi statistica dei dati, per una migliore interpretazione e rilevazione dei problemi. Analisi Risultati L’analisi dei risultati mostra che, Tra le prime 20 funzioni con la durata maggiore, ve ne sono molte relative al codice dei driver specifici. La funzione con durata maggiore è quella di inizializzazione del driver dell’interfaccia seriale con un tempo di 0.18 sec rispetto alle funzioni di init degli altri driver che impiegano tra i 0.02 sec ai 0.05 sec. La causa di questo (grafo delle chiamate), è relativa al fatto che la funzione durante l’esecuzione invoca le funzioni di associazione e registrazione del driver ben 4 volte (valore campo Count) poichè nella piattaforma Cartesio sono presenti 4 controllori seriali. Inoltre, nell'esecuzione avviene anche la gestione di un interrupt per la stampa su console dei dati di trace. Gli interrupt sono uno dei principali motivi che influenzano il profiling. [console abilitata su driver seriale. Boot non provato senza la console perché si tende a tenerla abilitata anche nei sistemi in fase di produzione per diagnostica] In conclusione, gran parte del tempo di boot è dedicato all'inizializzazione della seriale. Considerando che questa interfaccia è molto utile in fase di sviluppo e debugging ma raramente è presente in un prodotto finale, al contrario di un'interfaccia USB, come risultato di quest'analisi possiamo affermare che in fase di produzione i driver dell'interfaccia seriale possono essere disabilitati dal BSP Linux Cartesio per velocizzare la fase di boot. Questa attività di test, mancava nella validazione del BSP Cartesio in STM, la sua introduzione è stata utile per introdurre un test di regressione, per verificare le prestazioni del boot a fronte di modifiche ai driver del BSP. 0.05sec 0.04sec 0.02sec 0.02sec
Rilevazione di Memory Leak TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Rilevazione di Memory Leak Memory leakage: consumo di memoria Zona di memoria non più necessaria, non deallocata Errore di programmazione Rilevanza nei sistemi embedded Impatto negativo prestazioni e affidabilità sistema Scelto e personalizzato kmemleak Memory leak nei device driver Fase inizializzazione driver Funzione init Funzione exit La seconda attività sperimentata riguarda la rilevazione dei memory leak. Memory Leakage: è uno dei principali difetti di software aging, è un consumo di memoria causato da un programma che non è più in grado di liberare un zona di memoria che ha acquisito e non più necessaria. Questa condizione è il risultato di un errore software che impedisce di rilasciare la memoria dopo il suo utilizzo. Sistemi Embedded Nei sistemi embedded, la limitata quantità di memoria fisica disponibile rende il memory leakage un problema da affrontare maggiormente che in altri ambiti. Esso può avere un impatto negativo sulle prestazioni e sull’ affidabilità del sistema. Strumento Anche per questa attività è stata eseguita la scelta dello strumento, prendendo i principali e confrontandoli e ho scelto kmemleak in quanto è l’unico che permette la rilevazione nello spazio del kernel. Dopo la personalizzazione per il sistema specifico, Risultati E’ stato utilizzato per analizzare i difetti di memory leak nei device driver. Dai risultati ottenuti, è emerso che i difetti di memory leak sono concentrati nelle fasi di inizializzazione e de-inizializzazione dei driver, dove avvengono la maggior parte delle allocazioni e de-allocazioni di risorse, per diminuire la deframmentazione della memoria. In particolare i memory leak sono causati da errori di programmazione nelle funzioni di init e exit del driver, come si nota dall’esempio riportato. Anche questo strumento è risultato utile per il processo di validazione del BSP di STM, e può essere utilizzato per eseguire test di regressione nel sistema dopo l’aggiunta o modifica di driver. cartesio_sga_probe cartesio_sga_init
Valutazione delle Prestazioni di I/O su Dispositivi di Mass Storage TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Valutazione delle Prestazioni di I/O su Dispositivi di Mass Storage Device driver MMC su release BSP 2.3 e 2.4 Obiettivi: Valutare le prestazioni Ottimizzazione Strumenti base time cp source dest Limite: scarsa efficacia per processi di ottimizzazione Strumenti complessi per correlare le prestazioni ad altri parametri: cpu cache, buffer cache, ecc. IOzone 50.207 KB/s (media) 1018 KB/s (media) 57.642 KB/s (media) L’ultima attività di testing che presento ha l’ Obiettivo di valutare le prestazioni delle operazioni di I/O, eseguite dai device driver, sui dispositivi di memorizzazione e valutare eventuali possibilità di ottimizzazione. L’esigenza di eseguire questa attività nasce dal fatto che il processo di validazione per Cartesio manca di uno strumento che permetta di misurare in modo oggettivo questo tipo di prestazioni. La mia analisi è partita da strumenti di base messi a disposizione dalla shell linux, time, strumento semplice ed efficace per ricavare informazioni di durata ed eseguire delle comparazioni di una sistema hw con se stesso al variare della versione del software o con altre piattaforme hw e sw concorrenti. Il limite di questi strumenti base è che non sono efficaci per attuare dei processi di ottimizzazione, in quanto l’informazione temporale che si ottiene (non è correlata con la configurazione del sw che ha prodotto quei tempi) non è correlata con ulteriori parametri hw e sw noti per influire sulle prestazioni di IO, dim cache cpu, dim cache filesystem, ecc. Per questo motivo è stato necessario trovare strumenti più complessi che permettono di misurare le prestazioni ma anche di correlarli a questi parametri, per capire su quali agire per migliorarle. Strumento Iozone è lo strumento scelto, dopo il confronto, per eseguire l’attività, che è stato personalizzato per il sistema specifico. Iozone: operazioni read e write. Ogni operazione è effettuata con dimensioni di file differenti (per default con file da 64KB a 512MB) trasferiti con record di diverse dimensioni (per default i file sono trasferiti con record da 4K a 16MB). Un risultato pratico del utilizzo dello strumento è mostrato dal grafico che evidenzia un’anomalia presente in una specifica versione del driver mmc-card della piattaforma Cartesio. L’anomalia consiste in un throughput molto basso nella lettura di file di piccole dimensioni. Risolta l’anomalia il throughput si è assestato su valori più uniformi, benchè pregiudicati di effetti dovuti alla dimensione della cache cpu, buffer cache e altre cause ancora sotto analisi. 9.204 KB/s (media)
AMBIENTE SPERIMENTALE TESTING EMBEDDED AUTOMAZIONE AMBIENTE SPERIMENTALE ATTIVITA’ TESTING CONCLUSIONI SW SISTEMI EMBEDDED CONTRIBUTO TESI Conclusioni Problema: Approcci ad-hoc Soluzione: Personalizzazione di strumenti generali Risultati: Approccio ad-hoc superato Personalizzazione, può influenzare la raccolta e l'analisi dei risultati per valutare la qualità Migliorato il processo di testing STM aree di qualità non esplorate strumenti di automazione La soluzione proposta per migliorare l’automazione del testing in ambito embedded è stata valutata attraverso la sperimentazione in una realtà industriale affermata con attività di testing utili al processo di validazione di ST. Il lavoro permette di affermare che che l’approccio ad-hoc può essere superato, con un approccio generale che si può ottenere personalizzando degli strumenti off-the-shelf, per il sistema specifico. Inoltre ha messo in luce come in alcuni casi, la complessità della personalizzazione può influenzare la raccolta e l'analisi dei risultati per valutare e migliorare la qualità. Il lavoro ha permesso infine di migliorare il processo di validazione di ST, aumentando il perimetro, con l'individuazione di aree di qualità non ancora esplorate e introducendo, per la valutazione di queste, strumenti di automazione che riduco i costi e i tempi del processo.
Criteri Scelta Strumenti di Automazione Instrumentazione (implicita o esplicita), Licenza degli strumenti Linguaggio di programmazione con il quale è scritto il sw da testare Sistema operativo Architettura hw utilizzata Ambito di utilizzo e integrazione (strumenti user-space e kernel-space) Interfaccia e reporting (GUI/command-line)
Rilevazione di Memory Leak (1) Scelta dello Strumento Non necessaria la personalizzazione per l’architettura ARM Facilmente integrabile nel kernel
Rilevazione di Memory Leak (2) nei device driver Fasi di un device driver: Esecuzione Inizializzazione Fase Inizializzazione Fase platform-dependet del processo di boot del kernel Registrazione dei device Registrazione dei driver Associazione tra device e driver Associazione tra device e driver Nell’ambiente sperimentale, la rilevazione è focalizzata sui difetti nei device driver. Ho studiato gli errori di programmazione che possono essere commessi nello sviluppo di un driver e che causano difetti di memory leak. Ho applicato lo strumento per la loro rilevazione. Inizializzazione Per comprendere la tipologia di errore, bisogna studiare la fase di inizializzazione di un driver Un device driver ha due fasi principali: esecuzione: interazione con la periferica inizializzazione: più interessante dal punto di vista della rilevazione dei memory leakage, in quanto è in essa che avvengono la maggior parte delle allocazioni di risorse, per diminuire la deframmentazione della memoria. L’inizializzazione del driver avviene nella fase platform dependent del processo di boot del kernel. Si divide in tre passi. Dopo la registrazione dei device e dei driver il kernel ha in memoria: Una tabella dei device della piattaforma Una tabella dei driver con cui gestirli. Appena un driver non associato viene rilevato, è avviata l’associazione tra device e driver. Associazione tra device e driver il kernel crea un’istanza della struttura device che rappresenta una generica periferica. E’ costituita da una parte platform-independent gestita completamente dal kernel e una parte che estende la struttura con informazioni sul particolare device che servono al driver per gestirlo correttamente. crea un’istanza del device specifico, una struttura che contiene informazioni sulla periferica specifica presente sulla piattaforma. E’ una derivazione di device. Esecuzione della funzione probe: funzione di inizializzazione Allocazione della struttura di stato: definita all’interno del driver, contiene informazioni sul device. Contesto di utilizzo del driver. Considerando che il driver può gestire più device (modalità di sviluppo) dello stesso tipo, la struttura di stato permette di personalizzare il driver per la gestione di quella particolare periferica. Associazione tra l’istanza della struttura di stato e l’istanza di device: il kernel gestisce una periferica attraverso il device generico. Fino a questo momento sa che quel device generico corrisponde a quel tipo di device specifico, ma non sa ancora con quale driver gestirlo. Affinchè questo sia possibile bisogna associare la struttura di stato con il device.
Rilevazione di Memory Leak (3) Risultati Sperimentali Errore programmazione: mancanza dell’istruzione di deallocazione della struttura di stato Funzione probe e funzione remove FUNZIONE PROBE struct cartesio_sga *sga sga=kzalloc(struct cartesio_sga) FUNZIONE REMOVE kfree (sga) MEMORIA struttura di stato struttura di stato Rilevazione dell'errore con kmemleak sga struttura di stato struttura di stato Coinvolte le funzioni probe e remove del driver. Funzione remove: funzione di deinizializzazione, chiamata quando il driver (caricato come modulo) viene rimosso. Disfare tutte le operazioni fatte nella probe. Il primo errore riguarda: La struttura di stato è allocata nella funzione probe La funzione remove dealloca la struttura di stato, liberando la zona di memoria Quando il driver viene rimosso, se l’istruzione di deallocazione della struttura di stato non viene inserita nella remove, si ha la situazione in cui il puntatore sga (variabile locale nella probe) alla struttura di stato viene eliminato e la struttura di stato rimane in una zona della memoria non referenziata che non può essere più liberata, escludendo l'uso di quella stessa parte di memoria per altri scopi. Considerando la quantità di driver esistenti per le diverse periferiche e considerando che un singolo driver può gestire più periferiche, allocando più di una struttura di stato, questo errore può velocemente saturare la memoria e compromettere le prestazioni e la stabilità del kernel. La rilevazione dell'errore da parte di kmemleak: zona di memoria non referenziata (dimensione) Hexdump: primi 32 byte della zona di memoria in questione in formato esadecimale Backtrace: stack di chiamate a funzioni che ha portato alla rilevazione del memory leak. Esso si legge dal basso verso l'alto. In questa sequenza vi è la funzione del driver che contiene l’errore che ha provocato il leakage e si può risalire alla causa. Problema con i driver caricati come modulo: Le funzioni proprie di un driver non vengono esplicitate con il nome ma indicate con l’indirizzo di memoria esadecimale. Problema causato dalla compilazione separata del driver dal resto del kernel. Le funzioni mancanti nell’esempio sono proprio quelle relative al driver specifico cartesio_sga_init e cartesio_sga_probe (dove avviene il leakage). Problema con i driver caricati come modulo cartesio_sga_probe cartesio_sga_init
Rilevazione di Memory Leak (4) Risultati Sperimentali Errore programmazione: mancanza salvataggio dell’handle della struttura di stato allocata Funzione probe MEMORIA FUNZIONE PROBE struct cartesio_sga *sga sga=kzalloc(struct cartesio_sga) amba_set_drvdata(dev,sga) struttura di stato sga Struct device Struct device_private *p Coinvolta la funzione probe. Nella funzione probe viene allocata la struttura di stato. il puntatore alla struttura di stato restituito dalla funzione di allocazione, detto handle, viene salvato in una variabile locale *sga, la quale cessa di esistere dopo l'esecuzione della funzione probe. Per non perdere il riferimento alla struttura di stato, il kernel viene in aiuto, salvando l'handle in una struttura stabile che sopravvive alla terminazione della funzione probe. Questa è la struttura device generico. Con la funzione che salva l’handle nel device, viene creato un altro riferimento, oltre al puntatore sga, alla struttura di stato, ovvero il campo private della struttura device generico. Se questa funzione non viene inserita: L’handle non viene salvato in una struttura che sopravvive alla funzione probe. La variabile locale viene distrutta alla terminazione della probe. la zona di memoria allocata alla struttura di stato diventa orfana, causando un memory leak. La rilevazione di questo memory leakage da parte di kememleak. Gli errori individuati risultano importanti, considerando la quantità di driver esistenti all'interno del kernel per le diverse periferiche che vengono inizializzati e le risorse che questi allocano, questi errori possono veramente compromettere le prestazioni e la stabilità del kernel. Rilevazione dell'errore con kmemleak cartesio_sga_probe cartesio_sga_init
Risultati compatibili excel Valutazione delle Prestazioni di I/O su Dispositivi a Blocchi Scelta dello Strumento e Personalizzazione Scelta dello strumento di automazione: Bonnie e Bonnie++: valutazione di prestazioni su hard disk (tempi di seek) Tiobench: stress test multi-thread Iozone: verificare le prestazioni con l’influenza della gerarchia di memorie. Più completo diverse operazioni: read, write dimensioni di file differenti (da 64KB a 512MB) trasferiti con record di diverse dimensioni (da 4K a 16MB) Ambiente Target Ambiete Host IOzone Risultati compatibili excel User-space Excel MMC Risultati In questo contesto, esiste un numero importante di strumenti. Un confronto approfondito era al di là di quelli che erano i tempi di tesi. I principali strumenti sono stati scelti in basa ai vincoli dell'ambiente sperimentale, quali supporto per il sistema operativo Linux, disponibilità di un'interfaccia a riga di comando, licenza free e architettura supportata. Bonnie e Bonnie++ sono orientati verso la valutazione di prestazioni su dispositivi quali hard disk, infatti includono la valutazione dei tempi di seek. Tiobench, permette di valutare le prestazioni con uno stress test di letture e scritture eseguite da più thread contemporaneamente. Il nostro obiettivo è valutare le operazioni su dispositivi a blocchi, in cui non esistono i tempi di seek dovuti alla rotazione dei dischi e al posizionamento delle testina sul settore corretto. Inoltre poiché lavoriamo in ambiente embedded dove l'utilizzo di uno strumento multi-threading può saturare la limitata quantità di memoria, abbiamo scelto IOzone, in quanto dalla nostra analisi risulta lo strumento più completo e adatto in questo contesto e ai nostri obiettivi. IOzone Moltitutine di operazioni sui file: read (lettura file esistente), write (nuovo file-overhead metadati) Ogni operazione è effettuata con dimensioni di file differenti (per default con file da 64KB a 512MB) trasferiti con record di diverse dimensioni (per default i file sono trasferiti con record da 4K a 16MB). Un'altra caratteristica di IOzone è che è possibile generare output compatibili con Excel per la creazione di grafici. Personalizzazione: L'architettura ARM, è supportata dallo strumento. Ma bisogna modificare il makefile prima della compilazione. In particolare, bisogna sostituire il valore della variabile CC del makefile specificando il cross-compilatore utilizzato per la propria architettura. Personalizzazione CC= cc C89= c89 GCC= gcc CCS= /usr/ccs/bin/cc NACC= /opt/ansic/bin/cc CC= arm-stm-linux-gnueabi-gcc C89= c89 GCC= gcc CCS= /usr/ccs/bin/cc NACC= /opt/ansic/bin/cc