CS 498: Network Systems Laboratory
Laboratory Assignment 3
Jennifer C. Hou
Department of Computer Science
University of Illinois at Urbana-Champaign
Distribution date: February 17, 2004; Due date: March 3, 2004
The objective of this laboratory assignment is to learn (i) how to build, compile, and load kernel
modules in Linux 2.4 (or 2.6) kernel, (ii) how to create and utilize the /proc file system for
exporting information from inside the kernel, and (iii) how to use kernel timers and schedule
II. Project Description
You are required to write a kernel module that will be loaded into the kernel. The kernel module
will create two entries, cs498info1 and cs498info2, in the /proc directory. Whenever a user
makes read access to either file (via, for example, cat /proc/cs498info1), the current time, the
current value of jiffies, and several interesting TCP statistics will be displayed periodically for a
1) You need to write a kernel module that creates two entries for read-only access in /proc.
The two files are named cs498info1 and cs498info2. Essentially they give the same
information, but are implemented with different timing mechanisms.
2) Whenever either of the information files is accessed, it provides the current time, the
current value of jiffies, and the TCP statistics (to be elaborated on below) will be
displayed periodically for a pre-specified duration. The period, period, and the duration,
duration, for displaying the information are specified and passed to the kernel module as
module parameters at the module loading time. For example, if period=10, and
duration=60, then the required information will be displayed 7 times, once every 10
3) Check out the function do_gettimeofday() and the variable xtime for getting the current
time. There are multiple ways by which the TCP statistics can be obtained, but the easiest
way is perhaps via reading /proc/net/netstat and/or /proc/net/tcp. The TCP statistics we
are interested in collecting are TCPLoss, TCPLostRetransmit, TCPFastRetrans,
TCPForwardRetrans, TCPSlowStartRetrans, and TCPTimeouts. You can display the
information in any desirable (human readable) format.
4) There are multiple ways of scheduling periodic events, and you are required to implement
this with the busy wait approach (for /proc/cs498info1) and with the use of kernel timer
utilities provided in Linux (for /proc/cs498info2). To schedule events in a busy-wait
fashion, you simply do
/* schedule the event period seconds later */
unsigned long j = jiffies + period * HZ;
while (jiffies < j)
/* nothing */;
/* The event to be carried out */
On the other hand, check out the timer_list data structure in <linux/timer.h> and use the
following kernel timer functions for realizing the proc_read() function for /proc/cs498info2
(i) void init_timer(struct timer_list *timer): Initializes the
(ii) void add_timer(struct timer_list *timer): Inserts a timer
into the global list of active timers.
(iii) mod_timer(struct timer_list *timer, unsigned long expires):
Changes the time at which a timer expires.
(iv) int del_timer(struct timer_list *timer): Removes a timer
from the list before it expires.
(v) int del_timer_sync(struct timer_list *timer): Same as
del_timer, and guarantees that when the function returns,
the timer function is not running on any CPU.
Also, check out the utilities available for putting processes into sleep and awakening them (in
init_waitqueue_head(&my_queue); or DECLARE_WAIT_QUEUE_HEAD(my_queue)
(i) sleep_on(wait_queue_head_t *queue): puts the process to
sleep on this queue; not interruptible.
(ii) interruptible_sleep_on(wait_queue_head_t *queue)
(iii) sleep_on_timeout(wait_queue_head_t *queue, long timeout):
puts the process into sleep on this queue, but the sleep
will not be longer than timeout.
(iv) interruptible_sleep_on_timeout(wait_queue_head_t *queue,
(v) wake_up(wait_queue_head_t *queue): wakes up all the
processes that are waiting on this event queue.
(vi) wake_up_interruptible(wait_queue_head_t *queue): wakes up on
the processes that are in interruptible sleeps.
(vii) wake_up_sync(wait_queue_head_t *queue)
(viii) wake_up_interruptible_sync(wait_queue_head_t *queue)
Refer to the sample program jiq_read_run_timer in jiq.c for an
example of how to use the above utilities.
III. Items to be Turned in
Each group needs to schedule an appointment with the TA. The TA will test your kernel module on
line and ask questions about the way you write your kernel module (e.g., how you schedule the
kernel events). In addition, each group needs to turn in, along with the kernel module source code
and makefile, a written report that
(i) documents the kernel module;
(ii) compares the results obtained under two implementations. Which implementation is
more efficient? Which implementation gives more accurate results? (For one thing,
you need to check if (the difference between two readings of the current time /
period)= HZ?) If there exists discrepancy between the two results, what would be the
IV. Helpful Resources
The following URL contains very comprehensive resources for Linux kernel hacking and
programming, including the link to Linux cross-references (at which you can access the Linux
source code on-line)
 Wehrle et al., “Linux Networking Architecture: Design and Implementation of Network
Protocols in the Linux Kernel,” Chapters 1-2.
 P. J Salzman and O. Pomerantz, “Linux Kernel Module Programming Guide,”
 A. Rubini & J. Corbet, “Linux Device Driver,” Chapter 2: Building and Running Modules,
 Erick Mouw, Linux Kernel Procfs Guide, http://kernelnewbies.org/documents/kdoc/procfs-
 A. Rubini & J. Corbet, “Linux Device Driver,” Chapter 6: Flow of Time,