Re: Networking Timers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



To answer your question to kernelnewbies:

Any kernel timer that goes off runs in the timer bottom half context.
kernel timers are registered with the add_timer() call.

So, yes since the TCP retransmit timer is simply a generic kernel timer,
the function that gets called when the timer goes off is running in
bottom half context.

In bottom half context you have to be careful to realize that it can
interrupt code that runs in kernel space that was entered by a process
making a system call.  You also need to use GFP_ATOMIC when allocating
memory in bottom half context with kmalloc() or alloc_skb() for
example.  You do not want to call anything that can sleep in bottom half
context either (hence the need for GFP_ATOMIC for memory allocation
level).

So if you've got a data structure that is shared between code that runs
in "user context" -- a process entering a system call like for example a
read operation on a socket and code that runs in bottom half context
(like a timer or network packet received), then the bottom half context
code can just access the data structure normally and the user space
context code can call start_bh_atomic(), do it's stuff w/ the shared
data structure, and end_bh_atomic() when done w/ the data structure.
When start_bh_atomic() is active, all of the bottom halves don't run
until end_bh_atomic() is called.  Be careful when you call
start_bh_atomic() to not forget to end_bh_atmoic() eventually or you
will hang your system.  It's good practice to keep code between
start/end_bh_atomic pairs short and sweet to not make the system
sluggish or back the bottom halves up too much.

Also bottom halves are atomic from one another.  So for example if you
have a data structure that's shared between timer bottom half, network
bottom half, and kernel context code, both the timer bottom half context
function and network bottom half function don't have to worry about
stomping on each other and the user context code uses start_bh_atomic()
to keep the timer and network BHs out while it mucks with any shared
structure.  I've seen words that state that BHs are even atomic on SMP
systems (which can have interrupts on different CPUs occurring and it's
the interrupt service routines that usually schedule the BHs to run).

As mentioned above, add_timer() adds a function to be called when a
timer goes off.  In case you're curious, to register a function to be
called in the network BH, you can use dev_add_pack() to select something
to be called when a particular packet type comes in off an ethernet
device.  The function you register will run in network BH context when
it's called.

This all applies to kernel 2.2.X.  I'm not sure what additional
provisions might need to be taken in the 2.4.X kernel series.  I haven't
had to port any of my code to 2.4.X yet, but I anticipate I'll make the
plunge eventually.

I'm cc'ing this to the list in case something I said isn't 100%
accurate.  Paul Russell's guides are essential when making sure your
code isn't going to have problems with race conditions and proofing it
to make sure it follows the rules of programming in kernel space such
that you don't have to worry about hanging up your machine in a
mysterious manner.

Good luck,

-Eric Malkowski

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
IRC Channel:   irc.openprojects.net / #kernelnewbies
Web Page:      http://www.kernelnewbies.org/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux