IBM 10 SP1 EAL4 User Manual

Page of 246
The following code snippet demonstrates the per-CPU data structure problem, in an SMP system: 
int arr[NR_CPUS];
arr[smp_processor_id()] = i;
/* kernel preemption could happen here */
j = arr[smp_processor_id()];  
/* i and j are not equal as smp_processor_id() may not be the same */
In this situation, if kernel preemption had happened at the specified point, the task would have been assigned 
to some other processor upon re-schedule, in which case smp_processor_id() would have returned a 
different value.  This situation should be prevented by locking. 
FPU mode is another case where the state of the CPU should be protected from preemption. When the kernel 
is executing floating point instructions, the FPU state is not saved.  If preemption happens here, then upon 
reschedule, the FPU state is completely different from what was there before preemption.  So, FPU code must 
always be locked against kernel preemption. 
Locking can be done by disabling preemption for the critical section and re-enabling it afterwards.  The Linux 
2.6 kernel has provided the following #defines to disable and enable preemption: 
preempt_enable() -- decrements the preempt counter
preempt_disable() -- increments the preempt counter
get_cpu() -- calls preempt_disable() followed by a call to smp_processor_id()
put_cpu() -- re-enables preemption
Using these #defines we could rewrite the above code as 
int cpu, arr[NR_CPUS];
arr[get_cpu()] = i;  /* disable preemption */
j = arr[smp_processor_id()];
/* do some critical stuff here */
put_cpu();    /* re-enable preemption */
Note that preempt_disable() and preempt_enable() calls are nested.  That is, 
preempt_disable() can be called n number of times, and preemption will only be re-enabled when the 
nth preempt_enable() is encountered. 
Preemption is implicitly disabled if any spin locks are held.  For instance, a call to 
spin_lock_irqsave() implicitly prevents preemption by calling preempt_disable(); a call to 
spin_unlock_irqrestore() re-enables preemption by calling preempt_enable().
 5.3  Inter-process communication 
The SLES kernel provides a number of Inter-process communication (IPC) mechanisms that allow processes 
to exchange arbitrary amounts of data and synchronize execution.  The IPC mechanisms include unnamed 
pipes, named pipes (FIFOs), the System V IPC mechanisms (consisting of message queues, semaphores and 
shared memory regions), signals, and sockets.
This section describes the general functionality and implementation of each IPC mechanism and focuses on 
DAC and object reuse handling.
61