Understanding Modern Device Drivers

Slides:



Advertisements
Similar presentations
Simplifications of Context-Free Grammars
Advertisements

Chapter 13: I/O Systems I/O Hardware Application I/O Interface
Process Description and Control
AP STUDY SESSION 2.
1
Distributed Systems Architectures
Chapter 10 Architectural Design.
Chapter 7 System Models.
Copyright © 2003 Pearson Education, Inc. Slide 1 Computer Systems Organization & Architecture Chapters 8-12 John D. Carpinelli.
1 Copyright © 2013 Elsevier Inc. All rights reserved. Chapter 4 Computing Platforms.
Processes and Operating Systems
1 Copyright © 2013 Elsevier Inc. All rights reserved. Chapter 3 CPUs.
Myra Shields Training Manager Introduction to OvidSP.
Slide 1 FastFacts Feature Presentation October 16 th, 2008 We are using audio during this session, so please dial in to our conference line… Phone number:
David Burdett May 11, 2004 Package Binding for WS CDL.
1 Introducing the Specifications of the Metro Ethernet Forum MEF 19 Abstract Test Suite for UNI Type 1 February 2008.
Local Customization Chapter 2. Local Customization 2-2 Objectives Customization Considerations Types of Data Elements Location for Locally Defined Data.
Create an Application Title 1Y - Youth Chapter 5.
Process a Customer Chapter 2. Process a Customer 2-2 Objectives Understand what defines a Customer Learn how to check for an existing Customer Learn how.
Chapter 5 Input/Output 5.1 Principles of I/O hardware
1 Chapter 11 I/O Management and Disk Scheduling Patricia Roy Manatee Community College, Venice, FL ©2008, Prentice Hall Operating Systems: Internals and.
1 Chapter 12 File Management Patricia Roy Manatee Community College, Venice, FL ©2008, Prentice Hall Operating Systems: Internals and Design Principles,
Photo Slideshow Instructions (delete before presenting or this page will show when slideshow loops) 1.Set PowerPoint to work in Outline. View/Normal click.
© Tally Solutions Pvt. Ltd. All Rights Reserved Shoper 9 License Management December 09.
Knowledge Extraction from Technical Documents Knowledge Extraction from Technical Documents *With first class-support for Feature Modeling Rehan Rauf,
Chapter 7: Steady-State Errors 1 ©2000, John Wiley & Sons, Inc. Nise/Control Systems Engineering, 3/e Chapter 7 Steady-State Errors.
Version 1.0 digitaloffice.intel.com Intel ® vPro Technology Intel ® Active Management Technology Setup and Configuration HP Laptop – Compaq 6910p Small.
Break Time Remaining 10:00.
Troubleshooting Startup Problems
Debugging operating systems with time-traveling virtual machines Sam King George Dunlap Peter Chen CoVirt Project, University of Michigan.
Turing Machines.
Table 12.1: Cash Flows to a Cash and Carry Trading Strategy.
Red Tag Date 13/12/11 5S.
Database Performance Tuning and Query Optimization
ETS4 - What's new? - How to start? - Any questions?
PP Test Review Sections 6-1 to 6-6
EIS Bridge Tool and Staging Tables September 1, 2009 Instructor: Way Poteat Slide: 1.
Chapter 3 Logic Gates.
© Copyright by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. 1 Outline 24.1 Test-Driving the Ticket Information Application.
INTRODUCTION Lesson 1 – Microsoft Word Word Basics
Operating Systems Operating Systems - Winter 2011 Dr. Melanie Rieback Design and Implementation.
Operating Systems Operating Systems - Winter 2012 Dr. Melanie Rieback Design and Implementation.
Operating Systems Operating Systems - Winter 2010 Chapter 3 – Input/Output Vrije Universiteit Amsterdam.
Exarte Bezoek aan de Mediacampus Bachelor in de grafische en digitale media April 2014.
Chapter 20 Network Layer: Internet Protocol
Copyright © 2012, Elsevier Inc. All rights Reserved. 1 Chapter 7 Modeling Structure with Blocks.
 Copyright I/O International, 2013 Visit us at: A Feature Within from Item Class User Friendly Maintenance  Copyright.
1 © 2004, Cisco Systems, Inc. All rights reserved. CCNA 1 v3.1 Module 10 Routing Fundamentals and Subnets.
Adding Up In Chunks.
MaK_Full ahead loaded 1 Alarm Page Directory (F11)
1 Processes and Threads Chapter Processes 2.2 Threads 2.3 Interprocess communication 2.4 Classical IPC problems 2.5 Scheduling.
KAIST Computer Architecture Lab. The Effect of Multi-core on HPC Applications in Virtualized Systems Jaeung Han¹, Jeongseob Ahn¹, Changdae Kim¹, Youngjin.
2004 EBSCO Publishing Presentation on EBSCOadmin.
: 3 00.
5 minutes.
1 hi at no doifpi me be go we of at be do go hi if me no of pi we Inorder Traversal Inorder traversal. n Visit the left subtree. n Visit the node. n Visit.
Types of selection structures
Breaking Up is Hard to Do Security and Functionality in a Commodity Hypervisor 1 Patrick Colp†, Mihir Nanavati†, Jun Zhu‡ William Aiello†, George Coker*,
Speak Up for Safety Dr. Susan Strauss Harassment & Bullying Consultant November 9, 2012.
1 Titre de la diapositive SDMO Industries – Training Département MICS KERYS 09- MICS KERYS – WEBSITE.
Essential Cell Biology
Clock will move after 1 minute
1 © 2004, Cisco Systems, Inc. All rights reserved. CCNA 1 v3.1 Module 9 TCP/IP Protocol Suite and IP Addressing.
PSSA Preparation.
Chapter 11 Creating Framed Layouts Principles of Web Design, 4 th Edition.
Physics for Scientists & Engineers, 3rd Edition
Select a time to count down from the clock above
Murach’s OS/390 and z/OS JCLChapter 16, Slide 1 © 2002, Mike Murach & Associates, Inc.
Import Tracking and Landed Cost Processing An Enhancement For AS/400 DMAS from  Copyright I/O International, 2001, 2005, 2008, 2012 Skip Intro Version.
Presentation transcript:

Understanding Modern Device Drivers Thank you – today I will be presenting a study of device drivers. This is a project done in collaboration with my advisor Prof Mike Swift. Asim Kadav and Michael M. Swift University of Wisconsin-Madison

Why study device drivers? Linux drivers constitute ~5 million LOC and 70% of kernel Little exposure to this breadth of driver code from research Better understanding of drivers can lead to better driver model Large code base discourages major changes Hard to generalize about driver properties Slow architectural innovation in driver subsystems Existing architecture: Error prone drivers Many developers, privileged execution, C language Recipe for complex system with reliability problems Device drivers are the single largest contributor to kernel code with over 5 million lines in Linux yet little is known about the breadth of this code apart from a small set of drivers used for research. Getting a broad exposure of driver code will help us improve driver model which will benefit operating systems reliability and performance. ENTER The large, unknown code base makes it hard to generalize about drivers and also discourages major changes to driver model and the overall organization of drivers. ENTER The existing driver model is also hard to get right. Hundreds of developers contribute thousands of lines of privileged code in a rather unsafe language into the kernel. This is a recipe for complex system with reliability problems.

Our view of drivers is narrow Driver research is focused on reliability Focus limited to fault/bug detection and tolerance Little attention to architecture/structure Driver research only explores a small set of drivers Systems evaluate with mature drivers Volume of driver code limits breadth Necessary to review current drivers in modern settings And has resulted n a flurry of research on driver reliability making our perception about drivers - largely reliability centric. Within reliability, driver research over the past decade has significantly focused on solving reliability problems using fault isolation techniques, bug detection tools and programming language techniques. There has been limited research that avoids failures by design or structure and applies to a broad set of drivers Furthermore these research solutions often studies a small set and makes generalizations about driver behavior across whole set of drivers. The volume of driver code has limited this ability and it necessary to review the driver code in modern settings such as advancements in hardware and PL techniques.

Difficult to validate research on all drivers Improvement System Validation Drivers Bus Classes New functionality Shadow driver migration [OSR09] 1 RevNIC [Eurosys 10] Reliability Nooks [SOSP 03] 6 2 XFI [ OSDI 06] CuriOS [OSDI 08] Type Safety SafeDrive [OSDI 06] 3 Singularity [Eurosys 06] Specification Nexus [OSDI 08] Termite [SOSP 09] Static analysis tools SDV [Eurosys 06] All Carburizer [SOSP 09] All/1 Cocinelle [Eurosys 08] We first noticed this problem of limited representation with our research on drivers and when we looked at other systems to learn more broadly about drivers, we find they they too ,focus on a small subset of devices PRESS ENTER, typically a network card, sound card, and storage device, all using the PCI bus. These are a small subset of all drivers, and results from these devices may not generalize to the full set of drivers. For example, many devices for consumer PCs are connected over USB which are not appropriately represented in research Device availability/slow driver development restrict our research runtime solutions to a small set of drivers

Difficult to validate research on all drivers Improvement System Validation Drivers Bus Classes New functionality Shadow driver migration [OSR09] 1 RevNIC [Eurosys 10] Reliability Nooks [SOSP 03] 6 2 XFI [ OSDI 06] CuriOS [OSDI 08] Type Safety SafeDrive [OSDI 06] 3 Singularity [Eurosys 06] Specification Nexus [OSDI 08] Termite [SOSP 09] Static analysis tools SDV [Eurosys 06] All Carburizer [SOSP 09] All/1 Cocinelle [Eurosys 08] “...Please do not misuse these tools!(Coverity).... If you focus too much on fixing the problems quickly rather than fixing them cleanly, then we forever lose the opportunity to clean our code, because the problems will then be hidden.” LKML mailing list http://lkml.org/lkml/2005/3/27/131 However, an exception to this rule are static analysis tools which are primarily used for bug finding. One might expect static analysis to provide broad information about drivers since they validate their results on a much larger set. Unfortunately, static analysis tools only look for buggy patterns such invalid pointer dereference and do not focus on structural issues.This email in LKML about Coverity analysis tool tells us static analysis tools perhaps miss the broad picture in drivers and hide the bigger problem underlying the occurance of these bugs

Understanding Modern Device Drivers Study source of all Linux drivers for x86 (~3200 drivers) Understand properties of driver code What are common code characteristics? Do driver research assumptions generalize? Understand driver interactions with outside world Can drivers be easily re-architected or migrated ? Can we develop more efficient fault-isolation mechanisms? Understand driver code similarity Do we really need all 5 million lines of code? Can we build better abstractions? To understand the broad picture, we present a study of all drivers in the Linux operating system. We look at 3200 device drivers and understand them in the context of modern driver research and future research opportunities. We first look at properties of driver code. The goal is to verify the driver research assumptions and to identify major driver functions that could benefit from additional research. Next we look at driver interactions with the outside world to understand how current set of drivers adapt to new powerful devices or virtual machine environments and the efficiency of fault isolation mechanisms. Finally we look at why drivers need 5 million lines of driver code and identify if improved abstractions can help reduce the size of the driver code base

Outline Methodology Driver code characteristics Driver interactions Driver redundancy This is the outline of my talk. I will first briefly describe the methodology and then describe only some of the results from each of the three analyses. For detailed results, please refer to our paper

Methodology of our study Target Linux 2.6.37.6 (May 2011) kernel Use static source analyses to gather information Perform multiple dataflow/control-flow analyses Detect driver properties of the drive code Detect driver code interactions with environment Detect driver code similarities within classes Since static analysis tools can study a broad set of drivers, we perform static source analyses over all drivers that compile on Linux 2.6.37.6 distributed as a part of kernel sources. We use a combination of dataflow analyses to detect driver properties, interactions and code similarities.

Extract driver wide properties for individual drivers For each driver, we merge all files required by the driver to a single file, and then identify different driver attributes such as each driver entry point registered with kernel structures using the function pointers. Step 1: Determine driver code characteristics for each driver from driver data structures registered with the kernel

Determine code characteristics of each driver function Next, we propagate this information through the control flow graph to label each and very function with additional information such as its purpose based on entry point information. This helps us understand the purpose served by different driver functions.We also measure many driver wide properties, like module parameters, device and bus operations etc. Step 2: Propagate the required information to driver functions and collect information about each function

Determining interactions of each driver function Using a list of known kernel, bus and device functions, we calculate and propagate the information about driver interactions in the call graph towards all registered entry points. This helps us answer questions such as - what are the number of bus calls along configuration entry points or core I/O entry points? We store all the results about each of the driver functions of 3200 drivers in a database and issue queries to slice the data across any dimensions, say class, entrypoints, bus etc Step 3: Determine driver interactions from I/O operations and calls to kernel and bus for each function and propagate to entry points

Outline Methodology Driver code characteristics Driver interactions Driver redundancy I will now talk about our results from driver code characteristics

Part 1: Driver Code Behavior A device driver can be thought of as a translator. Its input consists of high level commands such as “retrieve block 123”. Its output consists of low level, hardware specific instructions that are used by the hardware controller, which interfaces the I/O device to the rest of the system. -- Operating System Concepts VIII edition Drivers are commonly defined as translators from kernel to device and vice versa. They are considered to mostly consist of code that performs I/O. From our analyses, we try to understand where is the significant portion of the driver code dedicated to and where is the driver code complexity resulting from. Driver code complexity and size is assumed to be a result of its I/O function.

1-a) Driver Code Characteristics Core I/O & interrupts – 23% Initialization/cleanup – 36 % Device configuration – 15% Power management – 7.4% Device ioctl – 6.2% Here are our results from identifying the amount of driver code for about 25 device classes based on our taxonomy. The Y axis … the x-axis represents the different purpose of the reachable driver code. The darkness of the box represents the percentage of the driver code

Driver Code Characteristics Core I/O & interrupts – 23% Initialization/cleanup – 36 % Device configuration – 15% Power management – 7.4% Device ioctl – 6.2% First, we find that only 23% of overall driver code is dedicated to perform core I/O and interrupt processing. This means bulk of code in a driver is not towards core I/O and hence driver improvement should also look at non I/O code for improving the quality of drivers. Only 23% of driver code is dedicated to I/O and interrupts

Driver Code Characteristics Core I/O & interrupts – 23% Initialization/cleanup – 36 % Device configuration – 15% Power management – 7.4% Device ioctl – 6.2% Next, we find that majority of driver code – about 36% is dedicated towards driver initialization and cleanup. Efforts at reducing the complexity of drivers should also focus on better mechanisms for driver initialization and cleanup. For example, as devices are increasingly becoming virtualization aware, quick ways to initialize devices are critical for important I/O virtualization features such as re-assignment of devices. Driver code complexity stems mostly from initialization/cleanup code.

Driver Code Characteristics Core I/O & interrupts – 23% Initialization/cleanup – 36 % Device configuration – 15% Power management – 7.4% Device ioctl – 6.2% We also find, that the device configuration is the third biggest contributor to driver code. Network and video drivers have upto 30% of their code as device configuration. OS research should also look at better mechanisms for managing shared configuration code. About 6% of driver code is also exposed as opaque iocts. There are oppurtunites to make better interfaces and present more informed view of this part of configuration code to the kernel Better ways needed to manage device configuration code

1-b) Do drivers belong to classes? Drivers registers a class interface with kernel Example: Ethernet drivers register with bus and net device library Class definition includes: Callbacks registered with the bus, device and kernel subsystem Exported APIs of the kernel to use kernel resources and services Most research assumes drivers obey class behavior We next look at whether drivers can be described based on their class definitions. Most drivers register a class interface with kernel to utilize device library services of that class. For example, PCI network drivers register with the network device subsystem and PCI bus subsystem to use its services. It is often assumed that drivers will behave within the boundaries of the class definition and the complete semantics of drivers can be understood by its registered calls to and from the kernel. However, many vendors introduce non-class behavior in driver to introduce non-standard features for competetive advantage in their products.

Class definition used to record state Modern research assumes drivers conform to class behavior Example: Driver recovery (Shadow drivers[OSDI 04] ) Driver state is recorded based on interfaces defined by class State is replayed upon restart after failure to restore state Most research assumes that drivers observe class behavior. For example, shadow drivers which automatically recovers device state after failures, records driver state based on class definition. It then replays this state upon failure, to bring back the driver to its previous state. ENTER. Non class behavior can lead to incomplete restore after failure since the state via non-class behavior is not recorded Non-class behavior can lead to incomplete restore after failure Figure from Shadow drivers paper

Class definition used to infer driver behavior Example2 : Reverse engineering of drivers - Revnic[Eurosys 10] Driver behavior is reverse engineered based on interfaces defined by class Driver entry points are invoked to record driver operations Code is synthesized for another OS based on this behavior Another example is reverse engineering of drivers.For example, a recent system, RevNIC records driver behavior state for one operating system and synthesizes it for another operating system by observing the traces. The traces are generated by invoking driver operations based on class behavior. PRESS Hence, non class behavior can lead to synthesis of incomplete driver. ----- Meeting Notes (3/1/12 16:20) ----- Drop this revnic Figure from Revnic paper Non-class behavior can lead to incomplete reverse engineering of device driver behavior

Do drivers belong to classes? Non-class behavior stems from: Load time parameters, unique ioctls, procfs and sysfs interactions ... qlcnic_sysfs_write_esw_config (...) { ... switch (esw_cfg[i].op_mode) { case QLCNIC_PORT_DEFAULTS: qlcnic_set_eswitch_...(...,&esw_cfg[i]); case QLCNIC_ADD_VLAN: qlcnic_set_vlan_config(...,&esw_cfg[i]); case QLCNIC_DEL_VLAN: esw_cfg[i].vlan_id = 0; In Linux drivers, non class behavior manifests as load time parameters to the driver, unique ioctols to the device and interactions with the sys and proc file system. For, example, the Qlogic network driver shown in the figure, was detected by our analysis as an example of non-class behavior. The driver configuration settings are read from the sysfs and appropriate driver functions are called to change the driver state. This behavior is not recorded or invoked if one is only tracking class behavior operations. Drivers/net/qlcnic/qlcnic_main.c: Qlogic driver(network class)

Many drivers do not conform to class definition Results as measured by our analyses: 16% of drivers use proc /sysfs support 36% of drivers use load time parameters 16% of drivers use ioctl that may include non-standard behavior Breaks systems that assume driver semantics can be completely determined from class behavior We used our analyses to identify such behavior across all drivers and find that code supporting /proc and /sys is present in 16% of drivers. 36% of drivers have atleast one parameter to control behavior and configuration options not available through the class interface. Additionally, 16% of driver code contains ioctl, which can cause non-class behavior. Overall, 44% of drivers use one of the first two non-class features and such code breaks systems that use class behavior to interpret the semantics of drivers Overall, 44% of drivers do not conform to class behavior Systems based on class definitions may not work properly when such non-class extensions are used

1-c) Do drivers perform significant processing? Drivers are considered only a conduit of data Example: Synthesis of drivers (Termite[SOSP09]) State machine model only allows passing of data Does not support transformations/processing But: drivers perform checksums for RAID, networking, or calculate display geometry data in VMs Another common assumption is that drivers perform little processing and just shuttle data between OS and device. For example, automatic synthesis of drivers only allows operations primarily based on communicating data. It does not support memory transformations or processing made by drivers. However, if drivers perform processing for example to compute checksums for RAID, or to calculate display data, then automatic synthesis is unable to generate code for these parts of the driver

Instances of processing loops in drivers Detect loops in driver code that: do no I/O, do not interact with kernel lie on the core I/O path static u8 e1000_calculate_checksum(...) { u32 i; u8 sum = 0; ... for (i = 0; i < length; i++) sum += buffer[i]; return (u8) (0 - sum); } In order to detect processing, we detect loops in driver code that do not perform I/O, do not interact with kernel and lie on the core I/O path. The goal here was to detect driver code that transforms incoming or outgoing driver data in a loop without invoking a kernel service or making device calls. ENTER For example, in this figure, in the processing instance detected by our driver, we can see that the network driver is computing checksum for the network packets. drivers/net/e1000e/lib.c: e1000e network driver

Many instances of processing across classes static void _cx18_process_vbi_data(...) { // Process header & check endianess // Obtain RAW and sliced VBI data // Compress data, remove spaces, insert mpg info. } void cx18_process_vbi_data(...) // Loop over incoming buffer // and call above function We also find other classes of drivers that perform processing. Here in this figure, we can see video processing being done by media drivers on the incoming video data. Other forms of processing include, wireless drivers which use processing to calculate power levels at different frequencies. Even CDROM drivers, use computation to analyze table of content information for CD-ROMS drivers/media/video/cx18/cx18-vbi.c:cx18 IVTV driver

Drivers do perform processing of data Processing results from our analyses: 15% of all drivers perform processing 28% of sound and network drivers perform processing Driver behavior models should include processing semantics Implications in automatic generation of driver code Implications in accounting for CPU time in virtualized environment We also see that higher percentage of network and sound drivers perform processing. These results have implications in not just automatic generation of drivers but also in virtualized settings where heavy I/O from one guest VM can substantially reduce CPU for other guest VMs without proper accounting. Driver behavior models should consider processing

Outline Methodology Driver code characteristics Driver interactions Driver redundancy We next looks at couple of results from our driver interactions study.

Part 2: Driver interactions a) What are the opportunities to redesign drivers? Can we learn from drivers that communicate efficiently? Can driver code be moved to user mode, a VM, or the device for improved performance/reliability? b) How portable are modern device drivers? What are the kernel services drivers most rely on? c) Can we develop more efficient fault-tolerance mechanisms? Study drivers interaction with kernel, bus, device, concurrency In this section, we look at how drivers use the kernel and how drivers communicate with devices? We see three reasons to study these interactions. First, extra processing power on devices or extra cores on host CPU provide an oppurtunity to redesign the driver architecture for improved reliability and performance Second, much of the difficulty in moving drivers comes from the driver/kernel interface, so investigating what drivers request from kernel can aid in designing more portable drivers. Third the cost of isolation and reliability are proportional to the size of the interface and the frequency of interactions, so understanding the interface can lead to more efficient fault tolerance mechanisms

2-a) Driver kernel interaction Calls/driver from all entry points We use our analyses to detect driver interactions with the kernel. The yaxis.. We classify these invocations based on 5 categories using static analysis: First is : Memory management (e.g. allocation): Second is Synchronization (e.g. Locks), Third is Kernel Library (generic stateless support routines – like timers, checksums, reporting etc. Fourth is Kernel Services (access to other subsystems like vfs, cpu, etc) Finally,Device Library (device subsystem supporting a class such as the network drivers)

Driver kernel interaction Calls/driver from all entry points While we expect diversity in kernel interaction, we see that some of the drivers such as ATA, IDE, gpio, drivers make limited use of kernel services.We look closely and find that in these drivers, rather than having a driver that invokes support routines, these drivers are a small set of device specific routines called from a much larger common driver. This design is similar to miniport drivers in Windows. ENTERConverting more drivers into this architecture can be benefical in reducing driver code as we see in the last part of the talk ----- Meeting Notes (3/1/12 16:20) ----- remove uwb double check acpi and gpio (and thats why they have simple) Common drivers invoking device specific routines reduces driver code significantly (and more classes can benefit)

Driver kernel interaction Calls/driver from all entry points Many classes are portable: Limited interaction with device library and kernel services We next look at portability of drivers? We look at what does the driver need the kernel for? If we want to run driver code elsewhere, such as user-mode, what does it need? Device library and kernel services require core kernel features which can be difficult to provide outside the kernel. Drivers with rich device library support are fairly limited (like network and sound) while other drivers such as video drivers have limited device library support and are more common From our results, we see that most invocations are for kernel library routines, memory management and synchronization which are primary local to the driver and a driver executing in a separate execution context will not need to call into the kernel for these services. ENTER. Hence many driver classes such as crypto, firewire, media, mtd are portable to other environments.

2-b) Driver-bus interaction Compare driver structure across buses Look for lessons in driver simplicity and performance Can they support new architectures to move drivers out of kernel? Efficiency of bus interfaces (higher devices/driver) Interface standardization helps move code away from kernel Granularity of interaction with kernel/device when using a bus Coarse grained interface helps move code away from kernel We now study structural properties of drivers to identify differences between buses. We look for lessons on driver simplicity and performance. And review which buses support newer architectures that move drivers out of the kernel. We do so by looking at interface standardization and granularity of accesses across drivers from different buses. Both features are good indicators of portability of driver code

PCI drivers: Fine grained & few devices/driver BUS Kernel Interactions (network drivers) Device Interactions (network drivers) mem sync dev lib kern lib services port/mmio DMA bus Devices/driver PCI 29.3 91.1 46.7 103 12 302 22 40.4 9.6 PCI drivers have fine grained access to kernel and device Support low number of devices per driver (same vendor) Support performance sensitive devices Provide little isolation due to heavy interaction with kernel Extend support for a device with a completely new driver We first look to quantify efficiency of PCI devices. We intentionally pick a single class and compare how devices belong to a single class differ according to the bus. The table shows kernal and device interactions across all entrypoints for network drivers. The data about all classes is in the paper. PCI devices have fine grained and heavy access to kernel and driver. They support only 10 devices per driver which are usually from the same vendor. In order to support a new device, in most cases, one needs to write a new driver.Hence, we see that high performance of PCI drivers comes at a cost: increased driver complexity, and less interface standardization, and supporting a new device usually means writing a new driver

USB: Coarse grained & higher devices/driver BUS Kernel Interactions (network drivers) Device Interactions (network drivers) mem sync dev lib kern lib services port/mmio DMA bus Devices/driver PCI 29.3 91.1 46.7 103 12 302 22 40.4 9.6 USB 24.5 72.7 10.8 25.3 11.5 0.0 6.2* 36.0 15.5 USB devices support far more devices/driver Bus offers significant functionality enabling standardization Simpler drivers (like, DMA via bus) with coarse grained access Extend device specific functionality for most drivers by only providing code for extra features USB drivers are slightly more efficient and support almost 60% as many devices per driver often from many vendors. While the USB standardization efforts have been instrumental in increasing the bus efficiency The coarse grained interface to kernel and device offered by the bus also helps reducing driver code and produces better drivers. Here, a vendor can add non-standard code just for the features without creating new drivers in order to support a new device. * accessed via bus

Xen : Extreme standardization, limit device features BUS Kernel Interactions (network drivers) Device Interactions (network drivers) mem sync dev lib kern lib services port/mmio DMA bus Devices/driver PCI 29.3 91.1 46.7 103 12 302 22 40.4 9.6 USB 24.5 72.7 10.8 25.3 11.5 0.0 6.2* 36.0 15.5 Xen 11.0 7.0 27.0 24.0 1/All Xen represents extreme in device standardization Xen can support very high number of devices/driver Device functionality limited to a set of standard features Non-standard device features accessed from domain executing the driver Xen pushes standardization further by supporting all drivers of a class using a single driver in the guest domain. Additional non-standard features can only be accessed from the domain executing the driver and are not available to guest OS. Hence, XEN can be more efficient than USB but one loses the ability to support non-standard driver code. Addition of non-standard behavior requires separate messaging protocol from outside the driver such as RPC. These results imply that Xen and USB provide interface standardization that could help move driver code away from the kernel and also provide a coarse grained accesses, reducing the cost of isolation. Efficient remote access to devices and efficient device driver support offered by USB and Xen

Outline Methodology Driver code characteristics Driver interactions Driver redundancy I will now talk about redundancy in driver code

Part 3: Can we reduce the amount of driver code? Are 5 million lines of code needed to support all devices? Are there opportunities for better abstractions? Better abstractions reduce incidence of bugs Better abstractions improve software composability Goal: Identify the missing abstraction types in drivers Quantify the savings by using better abstractions Identify opportunities for improving abstractions/interfaces Given that all the drivers for a class perform essentially the same task, one may ask why so much code is needed. The problem of writing similar/repeated code is well documented. It causes bugs, prevents standardization and causes maintainability issues. Our goal in this section is to quantify the repeated code in drivers and what are the missing abstractions in that are creating repeated code.

Finding out similar code in drivers We are not just looking for cloned code but similar code in drivers. To do so, we use an existing clustering technique from machine learning, called shape analysis, often used to cluster related documents. We generate a set of multi dimensonal coordinates representing the statement type and edit distance to represent the shape of every driver function. We then use a euclidean function to reduce these coordinates to a single signature value. This methodology helps us scale better to whole set of drivers since we are only comparing signature values. It also gives us a knob to control the amount of similarity that we wish to see by clustering signature values appropriately in the results obtained Determine similar driver code by identifying clusters of code that invoke similar device, kernel interactions and driver operations

Drivers within subclasses often differ by reg values .. nv_mcp55_thaw(...) { void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR]; int shift = ap->port_no * NV_INT_PORT_SHIFT_MCP55; ... writel(NV_INT_ALL_MCP55 << shift, mmio_base+NV_INT_STATUS_MCP55); mask = readl(mmio_base + NV_INT_ENABLE_MCP55); mask |= (NV_INT_MASK_MCP55 << shift); writel(mask, mmio_base + NV_INT_ENABLE_MCP55); .. nv_ck804_thaw(...) { void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR]; int shift = ap->port_no * NV_INT_PORT_SHIFT; ... writeb(NV_INT_ALL << shift, mmio_base + NV_INT_STATUS_CK804); mask = readb(mmio_base + NV_INT_ENABLE_CK804); mask |= (NV_INT_MASK << shift); writeb(mask, mmio_base + NV_INT_ENABLE_CK804); We now look at two of the most common similarity types identified by our analyses. Here is an example of similar code where we see drivers invoking device by using different register values! drivers/ata/sata_nv.c

Wrappers around device/bus functions static int nv_pre_reset(...) {.. struct pci_bits nv_enable_bits[] = { { 0x50, 1, 0x02, 0x02 }, { 0x50, 1, 0x01, 0x01 } }; struct ata_port *ap = link->ap; struct pci_dev *pdev = to_pci_dev(...); if (!pci_test_config_bits (pdev,&nv_enable_bits[ap->port_no])) return -ENOENT; return ata_sff_prereset(..); } static int amd_pre_reset(...) {.. struct pci_bits amd_enable_bits[] = { { 0x40, 1, 0x02, 0x02 }, { 0x40, 1, 0x01, 0x01 } }; struct ata_port *ap = link->ap; struct pci_dev *pdev = to_pci_dev(...); if (!pci_test_config_bits (pdev,&amd_enable_bits[ap->port_no])) return -ENOENT; return ata_sff_prereset(..); } This is an example of similar code found in drivers. We find here drivers are in many cases repeating wrappers around kernel functions in same sequence. drivers/ata/pata_amd.c

Significant opportunities to improve abstractions At least 8% of all driver code is similar to other code Sources of redundancy Potential applicable solutions Calls to device/bus with different register values Table/data driven programming models Wrappers around kernel/device library calls Procedural abstraction for device classes Code in family of devices from one vendor Layered design/subclass libraries Overall we find 8% of driver code is very similar (which is approximately 400, 000 lines!) we find three cateogaries of similar code. First is calls to device/bus with different register values. Many drivers have a similar pattern of communicating with device, except using a different register values. This can be abstracted out by using a table driven programming, where common code executes and looks up tables to invoke appropriate device. Next is wrappers around kernel libraries, where kernel libraries are either missing interfaces or provide incomplete interfaces for accomplishing a task. For example, suspending a device requires holding appropriate locks, saving state, disabling device. Such wrappers are common across large number of drivers. Providing a common procedural abstraction for these kernel functions can help reduce driver code. Finally, we also see lots of repeated code amongst family of devices within a class. Provding object oriented design features or sub class librarries can further reduce this driver code. By removing these sources, one can reduce driver code, reduce incidence of bugs and improve software composability to support newer features such as power management.

Conclusions Many driver assumptions do not hold Bulk of driver code dedicated to initialization/cleanup 44% of drivers have behavior outside class definition 15% of drivers perform computation over drivers USB/Xen drivers can be offered as services away from kernel 8% of driver code can be reduced by better abstractions More results in the paper! To summarize, we review the large body of driver code and revisited generalizations about them and find that many assumptions about driver code do not hold. We also study interactions and reviewed how drive code can be moved away from kernel. We also, find missing interfaces in driver code, and providing them can reduce the driver code significantly.

Thank You Contact Email Driver research webpage kadav@cs.wisc.edu Driver research webpage http://cs.wisc.edu/sonar Taxonomy of Linux drivers developed using static analysis to find out important classes for all our results (details in the paper)

Extra slides

Drivers repeat functionality around kernel wrappers ... delkin_cb_resume(...) { struct ide_host *host = pci_get_drvdata(dev); int rc; pci_set_power_state(dev, PCI_D0); rc = pci_enable_device(dev); if (rc) return rc; pci_restore_state(dev); pci_set_master(dev); if (host->init_chipset) host->init_chipset(dev); return 0; } ... ide_pci_resume(...) { struct ide_host *host = pci_get_drvdata(dev); int rc; pci_set_power_state(dev, PCI_D0); rc = pci_enable_device(dev); if (rc) return rc; pci_restore_state(dev); pci_set_master(dev); if (host->init_chipset) host->init_chipset(dev); return 0; } This is an example of similar code in family of drivers. We see that much of the code is same, except for difference for driver data structures for different devices. ----- Meeting Notes (2/28/12 16:28) ----- example is bad not initialziing is not good look for wrappers (before and afer calls)? Look in paper ----- Meeting Notes (3/1/12 16:20) ----- add ide (in delkin_cb.c) FIX swap titles CODE CAN BE ABSTRACTED (NOT CLEAR - REPEAT WRAPPERS AROUND KENRLE FNCITONS) drivers/ide/ide.c drivers/delkin_cb.c

Drivers covered by our analysis All drivers that compile on x86 platform in Linux 2.6.37.6 Consider driver, bus and virtual drivers Skip drivers/staging directory Incomplete/buggy drivers may skew analysis Non x86 drivers may have similar kernel interactions Windows drivers may have similar device interactions New driver model introduced (WDM), improvement over vxd The Windows Driver Model, while a significant improvement over the VxD and Windows NT driver model used before it, has been criticised by driver software developers [1], most significantly for the following: WDM has a very steep learning curve. Interactions with power management events and plug and play are difficult. This leads to a variety of situations where Windows machines cannot go to sleep or wake up correctly due to bugs in driver code. I/O cancellation is almost impossible to get right. Thousands of lines of support code are required for every driver. No support for writing pure user-mode drivers.

Limitations of our analyses Hard to be sound/complete over ALL Linux drivers Examples of incomplete/unsound behavior Driver maintains private structures to perform tasks and exposes opaque operations to the kernel

Repeated code in family of devices (e.g initialization) ... asd_aic9405_setup(...) { int err = asd_common_setup(...); if (err) return err; asd_ha->hw_prof.addr_range = 4; asd_ha->hw_prof.port_name... = 0; asd_ha->hw_prof.dev_name... = 4; asd_ha->hw_prof.sata_name... = 8; return 0; } ... asd_aic9410_setup(...) { int err = asd_common_setup(...); if (err) return err; asd_ha->hw_prof.addr_range = 8; asd_ha->hw_prof.port_name_...= 0; asd_ha->hw_prof.dev_name_... = 8; asd_ha->hw_prof.sata_name_...= 16; return 0; } This is an example of similar code in family of drivers. We see that much of the code is same, except for difference for driver data structures for different devices. ----- Meeting Notes (2/28/12 16:28) ----- example is bad not initialziing is not good look for wrappers (before and afer calls)? Look in paper drivers/scsi/aic94xx driver

How many devices does a driver support? Many research projects generate code for specific device/driver Example, safety specifications for a specific driver

How many devices does a driver support? static int __devinit cy_pci_probe(...) { if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { ... if (pci_resource_flags(pdev,2)&IORESOURCE_IO){ ... if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {... }else if (device_id==PCI_DEVICE_ID_CYCLOM_Z_Hi) .... device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { switch (plx_ver) { case PLX_9050: … default: /* Old boards, use PLX_9060 */ } Cut out devices/driver drivers/char/cyclades.c: Cyclades character driver

How many devices does a driver support? 28% of drivers support more than one chipset

How many devices does a driver support? 28% of drivers support more than one chipset 83% of the total devices are supported by these drivers Linux drivers support ~14000 devices with 3200 drivers Number of chipsets weakly correlated to the size of the driver (not just initialization code) Introduces complexity in driver code Any system that generates unique drivers/specs per chipset will lead in expansion in code

Driver device interaction Portio/mmio: Access to memory mapped I/O or x86 ports DMA: When pages are mapped Bus: When bus actions are invoked Varying style of interactions Varying frequency of operations Gpu drivers do many register reads/wrtites before performing a DMA

Class definition used to record state Modern research assumes drivers conform to class behavior Most research assumes that drivers observe class behavior. For example, shadow drivers which automatically recovers device state after failures, records driver state based on class definition. It then replays this state upon failure, to bring back the driver to its previous state. ENTER. Non class behavior…since the state via non-class behavior is not recorded Driver behavior is reverse engineered based on interfaces defined by class Code is synthesized for another OS based on this behavior Driver state is recorded based on interfaces defined by class State is replayed upon restart after failure to restore state