Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 4154
b: refs/heads/master
c: fe0c9f5
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Jul 6, 2005
1 parent eca04eb commit e9f3ef1
Show file tree
Hide file tree
Showing 52 changed files with 2,765 additions and 645 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fef43da4e4341697a682f5aae1d5d428e840bc61
refs/heads/master: fe0c9f58779988e769da544d54b660c76506e78f
145 changes: 145 additions & 0 deletions trunk/Documentation/networking/fib_trie.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
LC-trie implementation notes.

Node types
----------
leaf
An end node with data. This has a copy of the relevant key, along
with 'hlist' with routing table entries sorted by prefix length.
See struct leaf and struct leaf_info.

trie node or tnode
An internal node, holding an array of child (leaf or tnode) pointers,
indexed through a subset of the key. See Level Compression.

A few concepts explained
------------------------
Bits (tnode)
The number of bits in the key segment used for indexing into the
child array - the "child index". See Level Compression.

Pos (tnode)
The position (in the key) of the key segment used for indexing into
the child array. See Path Compression.

Path Compression / skipped bits
Any given tnode is linked to from the child array of its parent, using
a segment of the key specified by the parent's "pos" and "bits"
In certain cases, this tnode's own "pos" will not be immediately
adjacent to the parent (pos+bits), but there will be some bits
in the key skipped over because they represent a single path with no
deviations. These "skipped bits" constitute Path Compression.
Note that the search algorithm will simply skip over these bits when
searching, making it necessary to save the keys in the leaves to
verify that they actually do match the key we are searching for.

Level Compression / child arrays
the trie is kept level balanced moving, under certain conditions, the
children of a full child (see "full_children") up one level, so that
instead of a pure binary tree, each internal node ("tnode") may
contain an arbitrarily large array of links to several children.
Conversely, a tnode with a mostly empty child array (see empty_children)
may be "halved", having some of its children moved downwards one level,
in order to avoid ever-increasing child arrays.

empty_children
the number of positions in the child array of a given tnode that are
NULL.

full_children
the number of children of a given tnode that aren't path compressed.
(in other words, they aren't NULL or leaves and their "pos" is equal
to this tnode's "pos"+"bits").

(The word "full" here is used more in the sense of "complete" than
as the opposite of "empty", which might be a tad confusing.)

Comments
---------

We have tried to keep the structure of the code as close to fib_hash as
possible to allow verification and help up reviewing.

fib_find_node()
A good start for understanding this code. This function implements a
straightforward trie lookup.

fib_insert_node()
Inserts a new leaf node in the trie. This is bit more complicated than
fib_find_node(). Inserting a new node means we might have to run the
level compression algorithm on part of the trie.

trie_leaf_remove()
Looks up a key, deletes it and runs the level compression algorithm.

trie_rebalance()
The key function for the dynamic trie after any change in the trie
it is run to optimize and reorganize. Tt will walk the trie upwards
towards the root from a given tnode, doing a resize() at each step
to implement level compression.

resize()
Analyzes a tnode and optimizes the child array size by either inflating
or shrinking it repeatedly until it fullfills the criteria for optimal
level compression. This part follows the original paper pretty closely
and there may be some room for experimentation here.

inflate()
Doubles the size of the child array within a tnode. Used by resize().

halve()
Halves the size of the child array within a tnode - the inverse of
inflate(). Used by resize();

fn_trie_insert(), fn_trie_delete(), fn_trie_select_default()
The route manipulation functions. Should conform pretty closely to the
corresponding functions in fib_hash.

fn_trie_flush()
This walks the full trie (using nextleaf()) and searches for empty
leaves which have to be removed.

fn_trie_dump()
Dumps the routing table ordered by prefix length. This is somewhat
slower than the corresponding fib_hash function, as we have to walk the
entire trie for each prefix length. In comparison, fib_hash is organized
as one "zone"/hash per prefix length.

Locking
-------

fib_lock is used for an RW-lock in the same way that this is done in fib_hash.
However, the functions are somewhat separated for other possible locking
scenarios. It might conceivably be possible to run trie_rebalance via RCU
to avoid read_lock in the fn_trie_lookup() function.

Main lookup mechanism
---------------------
fn_trie_lookup() is the main lookup function.

The lookup is in its simplest form just like fib_find_node(). We descend the
trie, key segment by key segment, until we find a leaf. check_leaf() does
the fib_semantic_match in the leaf's sorted prefix hlist.

If we find a match, we are done.

If we don't find a match, we enter prefix matching mode. The prefix length,
starting out at the same as the key length, is reduced one step at a time,
and we backtrack upwards through the trie trying to find a longest matching
prefix. The goal is always to reach a leaf and get a positive result from the
fib_semantic_match mechanism.

Inside each tnode, the search for longest matching prefix consists of searching
through the child array, chopping off (zeroing) the least significant "1" of
the child index until we find a match or the child index consists of nothing but
zeros.

At this point we backtrack (t->stats.backtrack++) up the trie, continuing to
chop off part of the key in order to find the longest matching prefix.

At this point we will repeatedly descend subtries to look for a match, and there
are some optimizations available that can provide us with "shortcuts" to avoid
descending into dead ends. Look for "HL_OPTIMIZE" sections in the code.

To alleviate any doubts about the correctness of the route selection process,
a new netlink operation has been added. Look for NETLINK_FIB_LOOKUP, which
gives userland access to fib_lookup().
2 changes: 1 addition & 1 deletion trunk/arch/i386/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ static struct kprobe trampoline_p = {
.pre_handler = trampoline_probe_handler
};

int __init arch_init(void)
int __init arch_init_kprobes(void)
{
return register_kprobe(&trampoline_p);
}
2 changes: 1 addition & 1 deletion trunk/arch/ia64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ static struct kprobe trampoline_p = {
.pre_handler = trampoline_probe_handler
};

int __init arch_init(void)
int __init arch_init_kprobes(void)
{
trampoline_p.addr =
(kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip;
Expand Down
52 changes: 44 additions & 8 deletions trunk/arch/ppc/8xx_io/enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,16 +714,24 @@ static int __init scc_enet_init(void)
immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */
#endif /* PC_ENET_LBK */

/* Configure port C pins to enable CLSN and RENA.
#ifdef PE_ENET_TCLK
/* Configure port E for TCLK and RCLK.
*/
immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);

cp->cp_pepar |= (PE_ENET_TCLK | PE_ENET_RCLK);
cp->cp_pedir &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
cp->cp_peso &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
#else
/* Configure port A for TCLK and RCLK.
*/
immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
#endif

/* Configure port C pins to enable CLSN and RENA.
*/
immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);

/* Configure Serial Interface clock routing.
* First, clear all SCC bits to zero, then set the ones we want.
Expand Down Expand Up @@ -896,14 +904,18 @@ static int __init scc_enet_init(void)
/* It is now OK to enable the Ethernet transmitter.
* Unfortunately, there are board implementation differences here.
*/
#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA))
#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
immap->im_ioport.iop_pcpar |= PC_ENET_TENA;
immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA))
#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
cp->cp_pbpar |= PB_ENET_TENA;
cp->cp_pbdir |= PB_ENET_TENA;
#elif ( !defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && defined (PE_ENET_TENA))
cp->cp_pepar |= PE_ENET_TENA;
cp->cp_pedir &= ~PE_ENET_TENA;
cp->cp_peso |= PE_ENET_TENA;
#else
#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA
#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA, PE_ENET_TENA
#endif

#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
Expand Down Expand Up @@ -936,6 +948,29 @@ static int __init scc_enet_init(void)
*((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
#endif

#ifdef CONFIG_MPC885ADS

/* Deassert PHY reset and enable the PHY.
*/
{
volatile uint __iomem *bcsr = ioremap(BCSR_ADDR, BCSR_SIZE);
uint tmp;

tmp = in_be32(bcsr + 1 /* BCSR1 */);
tmp |= BCSR1_ETHEN;
out_be32(bcsr + 1, tmp);
tmp = in_be32(bcsr + 4 /* BCSR4 */);
tmp |= BCSR4_ETH10_RST;
out_be32(bcsr + 4, tmp);
iounmap(bcsr);
}

/* On MPC885ADS SCC ethernet PHY defaults to the full duplex mode
* upon reset. SCC is set to half duplex by default. So this
* inconsistency should be better fixed by the software.
*/
#endif

dev->base_addr = (unsigned long)ep;
#if 0
dev->name = "CPM_ENET";
Expand Down Expand Up @@ -969,3 +1004,4 @@ static int __init scc_enet_init(void)
}

module_init(scc_enet_init);

22 changes: 21 additions & 1 deletion trunk/arch/ppc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ endmenu

menu "Platform options"

config FADS
bool

choice
prompt "8xx Machine Type"
depends on 8xx
Expand Down Expand Up @@ -399,8 +402,25 @@ config BSEIP
26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video
controller, and two RS232 ports.

config FADS
config MPC8XXFADS
bool "FADS"
select FADS

config MPC86XADS
bool "MPC86XADS"
help
MPC86x Application Development System by Freescale Semiconductor.
The MPC86xADS is meant to serve as a platform for s/w and h/w
development around the MPC86X processor families.
select FADS

config MPC885ADS
bool "MPC885ADS"
help
Freescale Semiconductor MPC885 Application Development System (ADS).
Also known as DUET.
The MPC885ADS is meant to serve as a platform for s/w and h/w
development around the MPC885 processor family.

config TQM823L
bool "TQM823L"
Expand Down
Loading

0 comments on commit e9f3ef1

Please sign in to comment.