These annotations help to mitigate false sharing on multiprocessor
systems.
Variables annotated with __cacheline_aligned are placed into the
.data.cacheline_aligned section in the kernel. Each item in this
section is aligned on a cachline boundary - this avoids false
sharing. Highly contended global locks are a good candidate for
__cacheline_aligned annotation.
Variables annotated with __read_mostly are packed together tightly
into a .data.read_mostly section in the kernel. The idea here is that
we can pack infrequently modified data items into a cacheline and
avoid having to purge the cache, which would happen if read mostly
data and write mostly data shared a cachline. Initialisation variables
are a prime candiate for __read_mostly annotations.
Move the function+line printing into GRE_DPRINTF().
Retire gre_closef(). Retire gre_join(). Constify gre_reconf(),
and don't pass it an LWP any longer.
Make this work in the new file descriptor regime. Add a kernel
thread per gre(4) instance whose purpose is to install the socket
into proc0's file descriptor table. Add gre_fp_send() and
gre_fp_recv() for passing file_t pointers to proc0.
Fix locking: don't solock() in the socket upcall, where it is
already held. Do solock() before calling soconnect().
Simplify reconfiguration.
Update a comment that mentions finding a less specific route, since
we don't do that any more.
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
* Create the kernel thread in gre_clone_create() instead of trying
to create it in gre_ioctl(). (Thanks ad@ for suggesting it, and
pointing out that I can't kthread_create while I hold a spin
lock.) Run the thread always, but put it to sleep while the
gre(4) is not in UDP mode.
* Use sockaddr_in_init().
* Move some thread state off of the stack and into the softc.
* Extract subroutines gre_do_recv(), gre_do_send(), and gre_reconf()
from gre_thread1(), making the code more readable.
Fix a defect in the locking of file descriptors as we delegate a
UDP socket from userland to the kernel. Move sc_fp out of sc_soparm.
Synchronize access to sc_fp by gre_ioctl() and the kernel thread
using a condition variable. For simplicity's sake, make it the
kernel helper thread's responsibility to close its UDP socket.
increase ifi_noproto. If the GRE header contains routing options,
increase the input-error count, ifi_ierrors.
While I am here, make some cosmetic changes: remove unnecessary
'proto' argument from gre_input3(). Shorten some staircases.
compiles, where some other system header #defines sc_sp.
In gre_ioctl, GREDSOCK case, do not try to delete sc_fp if it is
NULL.
Move GREDSOCK and GRESSOCK definitions to where the other GRE ioctls
are defined.
Remove #ifdef GRESSOCK, it's unnecessary now that the feature is
complete.
Fix MOBILE encapsulation. Add many debugging printfs (mainly
concerning UDP mode). Clean up the gre(4) code a bit. Add the
capability to setup UDP tunnels to ifconfig. Update documentation.
In UDP mode, gre(4) puts a GRE header onto transmitted packets,
and hands them to a UDP socket for transmission. That is, the
encapsulation looks like this: IP+UDP+GRE+encapsulated packet.
There are two ways to set up a UDP tunnel. One way is to tell the
source and destination IP+port to gre(4), and let gre(4) create
the socket. The other way to create a UDP tunnel is for userland
to "delegate" a UDP socket to the kernel.
Don't copy ttl from the inner packet to the encapsulating packet. Make
the outer ttl sysctl'able. This should close PR 14269 from Jasper Wallace
(change partly from there) and it makes traceroute work over gre tunnels.