Commit 772cb712 authored by Robert Olsson's avatar Robert Olsson Committed by David S. Miller
Browse files

[IPV4]: fib_trie RCU refinements



* This patch is from Paul McKenney's RCU reviewing. 

Signed-off-by: default avatarRobert Olsson <robert.olsson@its.uu.se>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1d25cd6c
Loading
Loading
Loading
Loading
+10 −11
Original line number Original line Diff line number Diff line
@@ -43,7 +43,7 @@
 *		2 of the License, or (at your option) any later version.
 *		2 of the License, or (at your option) any later version.
 */
 */


#define VERSION "0.403"
#define VERSION "0.404"


#include <linux/config.h>
#include <linux/config.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
@@ -224,7 +224,7 @@ static inline int tkey_mismatch(t_key a, int offset, t_key b)
  Consider a node 'n' and its parent 'tp'.
  Consider a node 'n' and its parent 'tp'.


  If n is a leaf, every bit in its key is significant. Its presence is 
  If n is a leaf, every bit in its key is significant. Its presence is 
  necessitaded by path compression, since during a tree traversal (when 
  necessitated by path compression, since during a tree traversal (when 
  searching for a leaf - unless we are doing an insertion) we will completely 
  searching for a leaf - unless we are doing an insertion) we will completely 
  ignore all skipped bits we encounter. Thus we need to verify, at the end of 
  ignore all skipped bits we encounter. Thus we need to verify, at the end of 
  a potentially successful search, that we have indeed been walking the 
  a potentially successful search, that we have indeed been walking the 
@@ -836,11 +836,12 @@ static void trie_init(struct trie *t)
#endif
#endif
}
}


/* readside most use rcu_read_lock currently dump routines
/* readside must use rcu_read_lock currently dump routines
 via get_fa_head and dump */
 via get_fa_head and dump */


static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)
static struct leaf_info *find_leaf_info(struct leaf *l, int plen)
{
{
	struct hlist_head *head = &l->list;
	struct hlist_node *node;
	struct hlist_node *node;
	struct leaf_info *li;
	struct leaf_info *li;


@@ -853,7 +854,7 @@ static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)


static inline struct list_head * get_fa_head(struct leaf *l, int plen)
static inline struct list_head * get_fa_head(struct leaf *l, int plen)
{
{
	struct leaf_info *li = find_leaf_info(&l->list, plen);
	struct leaf_info *li = find_leaf_info(l, plen);


	if (!li)
	if (!li)
		return NULL;
		return NULL;
@@ -1248,7 +1249,7 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
}
}




/* should be clalled with rcu_read_lock */
/* should be called with rcu_read_lock */
static inline int check_leaf(struct trie *t, struct leaf *l,
static inline int check_leaf(struct trie *t, struct leaf *l,
			     t_key key, int *plen, const struct flowi *flp,
			     t_key key, int *plen, const struct flowi *flp,
			     struct fib_result *res)
			     struct fib_result *res)
@@ -1590,7 +1591,7 @@ fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
	rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req);
	rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req);


	l = fib_find_node(t, key);
	l = fib_find_node(t, key);
	li = find_leaf_info(&l->list, plen);
	li = find_leaf_info(l, plen);


	list_del_rcu(&fa->fa_list);
	list_del_rcu(&fa->fa_list);


@@ -1714,7 +1715,6 @@ static int fn_trie_flush(struct fib_table *tb)


	t->revision++;
	t->revision++;


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


@@ -1722,7 +1722,6 @@ static int fn_trie_flush(struct fib_table *tb)
			trie_leaf_remove(t, ll->key);
			trie_leaf_remove(t, ll->key);
		ll = l;
		ll = l;
	}
	}
	rcu_read_unlock();  


	if (ll && hlist_empty(&ll->list))
	if (ll && hlist_empty(&ll->list))
		trie_leaf_remove(t, ll->key);
		trie_leaf_remove(t, ll->key);
@@ -2288,7 +2287,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
		seq_indent(seq, iter->depth);
		seq_indent(seq, iter->depth);
		seq_printf(seq, "  |-- %d.%d.%d.%d\n", NIPQUAD(val));
		seq_printf(seq, "  |-- %d.%d.%d.%d\n", NIPQUAD(val));
		for (i = 32; i >= 0; i--) {
		for (i = 32; i >= 0; i--) {
			struct leaf_info *li = find_leaf_info(&l->list, i);
			struct leaf_info *li = find_leaf_info(l, i);
			if (li) {
			if (li) {
				struct fib_alias *fa;
				struct fib_alias *fa;
				list_for_each_entry_rcu(fa, &li->falh, fa_list) {
				list_for_each_entry_rcu(fa, &li->falh, fa_list) {
@@ -2384,7 +2383,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
		return 0;
		return 0;


	for (i=32; i>=0; i--) {
	for (i=32; i>=0; i--) {
		struct leaf_info *li = find_leaf_info(&l->list, i);
		struct leaf_info *li = find_leaf_info(l, i);
		struct fib_alias *fa;
		struct fib_alias *fa;
		u32 mask, prefix;
		u32 mask, prefix;