Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 17: Data Synchronization


❑ The worker function is invoked with the stored argument so that it can set about its task.
❑ Upon termination of the worker function, the kernel checks whether there are too many or
too few worker threads. If no idle worker thread was available for longer than 1 second,^2
start_one_pdflush_threadgenerates a new thread. If the sleepiest thread (which is at the end
of thepdflush_listlist) has been asleep for more than 1 second, thecurrentthread is removed
from the system by exiting the endless loop. In this case, the only clean-up action required
besides handling locking is to decrementnr_pdflush_threads—onepdflushthread less is
available.

17.5 Performing Actual Work


pdflush_operationassigns a worker function to apdflushthread and wakes it up. If no thread is
available,−1 is returned; otherwise, a thread is removed from the list and woken. To simplify matters,
we have omitted the required locking in the code:

mm/pdflush.c
int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0)
{
unsigned long flags;
int ret = 0;

if (list_empty(&pdflush_list)) {
ret = -1;
} else {
struct pdflush_work *pdf;

pdf = list_entry(pdflush_list.next, struct pdflush_work, list);
list_del_init(&pdf->list);
if (list_empty(&pdflush_list))
last_empty_jifs = jiffies;
pdf->fn = fn;
pdf->arg0 = arg0;
wake_up_process(pdf->who);
}
return ret;
}

pdflush_operationaccepts two arguments that specify the worker function and its argument.

If the listpdflush_listis empty and thus nopdflushdaemon can be awoken, an error code is returned.
If a sleepingpdflushinstance is in the queue, it is removed and is no longer available to any other part
of the kernel. The values for the worker function and argument are assigned to the corresponding fields
ofpdflush_work, and immediately thereafter the thread is woken withwake_up_process. Thanks to the
whoelement inpdflush_work, the kernel knows which process is meant.

To ensure that there are always enough worker threads, the kernel checks whether thepdflush_list
list is empty after removing the current instance, but before waking the thread. If it is,last_empty_jifs
is set to the current system time. When a thread terminates, the kernel uses this information to
check the period during which no surplus threads were available — it can then start a new thread as
described above.

(^2) The time thepdflush_listlist was last empty is noted in the global variablelast_empty_jifs.

Free download pdf