Specifications

D
evice Driver Programming
17-12
Overview of Synchronization Issues 17
During development of a user-level device driver, you must address a number of
synchronization issues. These include synchronization of processes’ access to the device
register region and the driver status region described in “Overview of Data Structures” on
page 17-5 and synchronization of a user-level interrupt process’s access to the driver status
region with other processes’ access to that region. Guidelines for addressing these issues
are presented in the paragraphs that follow.
You must ensure that access to structures in the driver status region that can be accessed
and modified by more than one lightweight process or process is synchronized. Ensuring
exclusive access to the device does not provide sufficient protection. The reason is that a
user process can open the device and then make a fork(2) system call--thereby granting
another process access to the device. A multithreaded application has multiple lightweight
processes, which all have access to the device. In some environments, it is acceptable to
require that an application that uses a user-level device driver not invoke fork(2).It
might also be acceptable to ignore inter-process synchronization by requiring that only
one process open the device. This approach is not acceptable for user-level device drivers
written by Concurrent Computer Corporation personnel, however. The synchronization
tools that you can use to protect the driver status region adequately are spin locks and
semaphores. These tools are described in “Process Synchronization Tools” on page 17-19.
Some devices do not function properly if more than one process has access to the device
registers at a time. To use the real-time clock (rtc(7)), for example, a process must
write a command to one register and read the results of that command from another
register. If more than one process has access to the registers, the results that are read might
not be the expected ones.
You must determine whether or not you need to guarantee exclusive access to the registers
of the device controlled by the user-level driver. If you need to synchronize processes’
access to the registers, you can, in most cases, use a spin lock to do so. If the spin lock is
not to be locked at interrupt level, then you must set the processor IPL (interrupt priority
level) to PLSWTCH (as defined in /usr/include/sys/ipl.h), to prevent preemption
of the running process while the lock is held. You can modify the IPL from user level by
using the spl support routines. These routines are described in “The spl Support Rou-
tines” on page 17-19. You can also use a rescheduling variable, the resched_cntl(2)
system call, and the resched_lock macro to prevent preemption. These tools are
described in “Process Synchronization Tools” on page 17-19. You should use them with
caution, however, because the user application program might also be using them.
If you are incorporating a user-level interrupt routine in your driver, the synchronization
issues are more complex. You cannot use semaphores to protect a structure at interrupt
level because it is illegal to block in an interrupt routine. You can use spin locks at
interrupt level. If a spin lock is to be locked at interrupt level, you must ensure that a
process that locks the spin lock at program level raises the processor IPL to a level that is
high enough to block out the interrupt while the lock is held. Doing so prevents the
interrupt-handling routine from spinning forever while attempting to lock the spin lock
that is locked at program level. You should not lock a spin lock or raise the IPL for a long
period of time. You should not call kernel services while a spin lock is held or while the
IPL is raised. You must unlock the spin lock before lowering the IPL.
There are other synchronization issues related to use of a user-level interrupt routine that
are explained in “Developing the Driver’s Interrupt Service Routine” on page 17-34. They
involve use of the server_block(2) and server_wake1(2) system calls. An