Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 79509
b: refs/heads/master
c: 82cfbb0
h: refs/heads/master
i:
  79507: 3c7b57b
v: v3
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Jan 28, 2008
1 parent 552abca commit 718d2fe
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 52 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: 64347f786d13349d6a6f812f3a83c269e26c0136
refs/heads/master: 82cfbb008572b1a953091ef78f767aa3ca213092
103 changes: 52 additions & 51 deletions trunk/net/ipv4/fib_trie.c
Original file line number Diff line number Diff line change
Expand Up @@ -1711,64 +1711,65 @@ static int trie_flush_leaf(struct trie *t, struct leaf *l)
return found;
}

/* rcu_read_lock needs to be hold by caller from readside */

static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf)
/*
* Scan for the next right leaf starting at node p->child[idx]
* Since we have back pointer, no recursion necessary.
*/
static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c)
{
struct node *c = (struct node *) thisleaf;
struct tnode *p;
int idx;
struct node *trie = rcu_dereference(t->trie);
do {
t_key idx;

if (c == NULL) {
if (trie == NULL)
return NULL;

if (IS_LEAF(trie)) /* trie w. just a leaf */
return (struct leaf *) trie;

p = (struct tnode *)trie; /* Start */
} else
p = node_parent_rcu(c);

while (p) {
int pos, last;

/* Find the next child of the parent */
if (c)
pos = 1 + tkey_extract_bits(c->key, p->pos, p->bits);
idx = tkey_extract_bits(c->key, p->pos, p->bits) + 1;
else
pos = 0;

last = 1 << p->bits;
for (idx = pos; idx < last ; idx++) {
c = rcu_dereference(p->child[idx]);
idx = 0;

while (idx < 1u << p->bits) {
c = tnode_get_child_rcu(p, idx++);
if (!c)
continue;

/* Decend if tnode */
while (IS_TNODE(c)) {
p = (struct tnode *) c;
idx = 0;

/* Rightmost non-NULL branch */
if (p && IS_TNODE(p))
while (!(c = rcu_dereference(p->child[idx]))
&& idx < (1<<p->bits)) idx++;

/* Done with this tnode? */
if (idx >= (1 << p->bits) || !c)
goto up;
if (IS_LEAF(c)) {
prefetch(p->child[idx]);
return (struct leaf *) c;
}
return (struct leaf *) c;

/* Rescan start scanning in new node */
p = (struct tnode *) c;
idx = 0;
}
up:
/* No more children go up one step */

/* Node empty, walk back up to parent */
c = (struct node *) p;
p = node_parent_rcu(c);
}
return NULL; /* Ready. Root of trie */
} while ( (p = node_parent_rcu(c)) != NULL);

return NULL; /* Root of trie */
}


static struct leaf *trie_firstleaf(struct trie *t)
{
struct tnode *n = (struct tnode *) rcu_dereference(t->trie);

if (!n)
return NULL;

if (IS_LEAF(n)) /* trie is just a leaf */
return (struct leaf *) n;

return leaf_walk_rcu(n, NULL);
}

static struct leaf *trie_nextleaf(struct leaf *l)
{
struct node *c = (struct node *) l;
struct tnode *p = node_parent(c);

if (!p)
return NULL; /* trie with just one leaf */

return leaf_walk_rcu(p, c);
}

/*
Expand All @@ -1778,9 +1779,9 @@ static int fn_trie_flush(struct fib_table *tb)
{
struct trie *t = (struct trie *) tb->tb_data;
struct leaf *ll = NULL, *l = NULL;
int found = 0, h;
int found = 0;

for (h = 0; (l = nextleaf(t, l)) != NULL; h++) {
for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) {
found += trie_flush_leaf(t, l);

if (ll && hlist_empty(&ll->list))
Expand Down Expand Up @@ -1887,7 +1888,6 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
i++;
continue;
}
BUG_ON(!fa->fa_info);

if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
Expand Down Expand Up @@ -1916,8 +1916,9 @@ static int fn_trie_dump_plen(struct trie *t, int plen, struct fib_table *tb,
struct leaf *l = NULL;

s_h = cb->args[3];
h = 0;

for (h = 0; (l = nextleaf(t, l)) != NULL; h++) {
for (l = trie_firstleaf(t); l != NULL; h++, l = trie_nextleaf(l)) {
if (h < s_h)
continue;
if (h > s_h)
Expand Down

0 comments on commit 718d2fe

Please sign in to comment.