From: Alexander Duyck <alexander.h.duyck@redhat.com>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net
Subject: [next-next PATCH 7/7] fib_trie: Various clean-ups for handling slen
Date: Thu, 22 Jan 2015 15:51:45 -0800 [thread overview]
Message-ID: <20150122235145.5779.73547.stgit@ahduyck-vm-fedora20> (raw)
In-Reply-To: <20150122234652.5779.44251.stgit@ahduyck-vm-fedora20>
While doing further work on the fib_trie I noted a few items.
First I was using calls that were far more complicated than they needed to
be for determining when to push/pull the suffix length. I have updated the
code to reflect the simplier logic.
The second issue is that I realised we weren't necessarily handling the
case of a leaf_info struct surviving a flush. I have updated the logic so
that now we will call pull_suffix in the event of having a leaf info value
left in the leaf after flushing it.
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
net/ipv4/fib_trie.c | 49 +++++++++++++++++++++++++++++--------------------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 7f34226..3daf022 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -917,27 +917,20 @@ static void leaf_push_suffix(struct tnode *l)
static void remove_leaf_info(struct tnode *l, struct leaf_info *old)
{
- struct hlist_node *prev;
-
- /* record the location of the pointer to this object */
- prev = rtnl_dereference(hlist_pprev_rcu(&old->hlist));
+ /* record the location of the previous list_info entry */
+ struct hlist_node **pprev = old->hlist.pprev;
+ struct leaf_info *li = hlist_entry(pprev, typeof(*li), hlist.next);
/* remove the leaf info from the list */
hlist_del_rcu(&old->hlist);
- /* if we emptied the list this leaf will be freed and we can sort
- * out parent suffix lengths as a part of trie_rebalance
- */
- if (hlist_empty(&l->list))
+ /* only access li if it is pointing at the last valid hlist_node */
+ if (hlist_empty(&l->list) || (*pprev))
return;
- /* if we removed the tail then we need to update slen */
- if (!rcu_access_pointer(hlist_next_rcu(prev))) {
- struct leaf_info *li = hlist_entry(prev, typeof(*li), hlist);
-
- l->slen = KEYLENGTH - li->plen;
- leaf_pull_suffix(l);
- }
+ /* update the trie with the latest suffix length */
+ l->slen = KEYLENGTH - li->plen;
+ leaf_pull_suffix(l);
}
static void insert_leaf_info(struct tnode *l, struct leaf_info *new)
@@ -961,7 +954,7 @@ static void insert_leaf_info(struct tnode *l, struct leaf_info *new)
}
/* if we added to the tail node then we need to update slen */
- if (!rcu_access_pointer(hlist_next_rcu(&new->hlist))) {
+ if (l->slen < (KEYLENGTH - new->plen)) {
l->slen = KEYLENGTH - new->plen;
leaf_push_suffix(l);
}
@@ -1613,6 +1606,7 @@ static int trie_flush_leaf(struct tnode *l)
struct hlist_head *lih = &l->list;
struct hlist_node *tmp;
struct leaf_info *li = NULL;
+ unsigned char plen = KEYLENGTH;
hlist_for_each_entry_safe(li, tmp, lih, hlist) {
found += trie_flush_list(&li->falh);
@@ -1620,8 +1614,14 @@ static int trie_flush_leaf(struct tnode *l)
if (list_empty(&li->falh)) {
hlist_del_rcu(&li->hlist);
free_leaf_info(li);
+ continue;
}
+
+ plen = li->plen;
}
+
+ l->slen = KEYLENGTH - plen;
+
return found;
}
@@ -1700,13 +1700,22 @@ int fib_table_flush(struct fib_table *tb)
for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) {
found += trie_flush_leaf(l);
- if (ll && hlist_empty(&ll->list))
- trie_leaf_remove(t, ll);
+ if (ll) {
+ if (hlist_empty(&ll->list))
+ trie_leaf_remove(t, ll);
+ else
+ leaf_pull_suffix(ll);
+ }
+
ll = l;
}
- if (ll && hlist_empty(&ll->list))
- trie_leaf_remove(t, ll);
+ if (ll) {
+ if (hlist_empty(&ll->list))
+ trie_leaf_remove(t, ll);
+ else
+ leaf_pull_suffix(ll);
+ }
pr_debug("trie_flush found=%d\n", found);
return found;
next prev parent reply other threads:[~2015-01-22 23:51 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-22 23:51 [next-next PATCH 0/7] Fixes and improvements for recent fib_trie updates Alexander Duyck
2015-01-22 23:51 ` [next-next PATCH 1/7] fib_trie: Use index & (~0ul << n->bits) instead of index >> n->bits Alexander Duyck
2015-01-22 23:51 ` [next-next PATCH 2/7] fib_trie: Fix RCU bug and merge similar bits of inflate/halve Alexander Duyck
2015-01-22 23:51 ` [next-next PATCH 3/7] fib_trie: Fall back to slen update on inflate/halve failure Alexander Duyck
2015-01-22 23:51 ` [next-next PATCH 4/7] fib_trie: Add collapse() and should_collapse() to resize Alexander Duyck
2015-01-22 23:51 ` [next-next PATCH 5/7] fib_trie: Use empty_children instead of counting empty nodes in stats collection Alexander Duyck
2015-01-22 23:51 ` [next-next PATCH 6/7] fib_trie: Move fib_find_alias to file where it is used Alexander Duyck
2015-01-22 23:51 ` Alexander Duyck [this message]
2015-01-25 22:47 ` [next-next PATCH 0/7] Fixes and improvements for recent fib_trie updates David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150122235145.5779.73547.stgit@ahduyck-vm-fedora20 \
--to=alexander.h.duyck@redhat.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).