Skip to content

Commit 56ca2ad

Browse files
Alexander Duyckdavem330
authored andcommitted
fib_trie: Move rcu from key_vector to tnode, add accessors.
RCU is only needed once for the entire node, not once per key_vector so we can pull that out and move it to the tnode structure. In addition add accessors to be used inside the RCU functions so that we can more easily get from the key vector to either the tnode or the trie pointers. Signed-off-by: Alexander Duyck <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent dc35dbe commit 56ca2ad

File tree

1 file changed

+16
-18
lines changed

1 file changed

+16
-18
lines changed

net/ipv4/fib_trie.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,6 @@ typedef unsigned int t_key;
9393
#define IS_LEAF(n) (!(n)->bits)
9494

9595
struct key_vector {
96-
struct rcu_head rcu;
97-
9896
t_key empty_children; /* KEYLENGTH bits needed */
9997
t_key full_children; /* KEYLENGTH bits needed */
10098
struct key_vector __rcu *parent;
@@ -112,7 +110,9 @@ struct key_vector {
112110
};
113111

114112
struct tnode {
113+
struct rcu_head rcu;
115114
struct key_vector kv[1];
115+
#define tn_bits kv[0].bits
116116
};
117117

118118
#define TNODE_SIZE(n) offsetof(struct tnode, kv[0].tnode[n])
@@ -159,6 +159,11 @@ static const int sync_pages = 128;
159159
static struct kmem_cache *fn_alias_kmem __read_mostly;
160160
static struct kmem_cache *trie_leaf_kmem __read_mostly;
161161

162+
static inline struct tnode *tn_info(struct key_vector *kv)
163+
{
164+
return container_of(kv, struct tnode, kv[0]);
165+
}
166+
162167
/* caller must hold RTNL */
163168
#define node_parent(n) rtnl_dereference((n)->parent)
164169
#define get_child(tn, i) rtnl_dereference((tn)->tnode[i])
@@ -191,13 +196,6 @@ static inline unsigned long get_index(t_key key, struct key_vector *kv)
191196
return index >> kv->pos;
192197
}
193198

194-
static inline struct fib_table *trie_get_table(struct trie *t)
195-
{
196-
unsigned long *tb_data = (unsigned long *)t;
197-
198-
return container_of(tb_data, struct fib_table, tb_data[0]);
199-
}
200-
201199
/* To understand this stuff, an understanding of keys and all their bits is
202200
* necessary. Every node in the trie has a key associated with it, but not
203201
* all of the bits in that key are significant.
@@ -280,17 +278,17 @@ static inline void alias_free_mem_rcu(struct fib_alias *fa)
280278

281279
static void __node_free_rcu(struct rcu_head *head)
282280
{
283-
struct key_vector *n = container_of(head, struct key_vector, rcu);
281+
struct tnode *n = container_of(head, struct tnode, rcu);
284282

285-
if (IS_LEAF(n))
283+
if (!n->tn_bits)
286284
kmem_cache_free(trie_leaf_kmem, n);
287-
else if (n->bits <= TNODE_KMALLOC_MAX)
285+
else if (n->tn_bits <= TNODE_KMALLOC_MAX)
288286
kfree(n);
289287
else
290288
vfree(n);
291289
}
292290

293-
#define node_free(n) call_rcu(&n->rcu, __node_free_rcu)
291+
#define node_free(n) call_rcu(&tn_info(n)->rcu, __node_free_rcu)
294292

295293
static struct tnode *tnode_alloc(int bits)
296294
{
@@ -441,26 +439,26 @@ static inline void put_child_root(struct key_vector *tp, struct trie *t,
441439

442440
static inline void tnode_free_init(struct key_vector *tn)
443441
{
444-
tn->rcu.next = NULL;
442+
tn_info(tn)->rcu.next = NULL;
445443
}
446444

447445
static inline void tnode_free_append(struct key_vector *tn,
448446
struct key_vector *n)
449447
{
450-
n->rcu.next = tn->rcu.next;
451-
tn->rcu.next = &n->rcu;
448+
tn_info(n)->rcu.next = tn_info(tn)->rcu.next;
449+
tn_info(tn)->rcu.next = &tn_info(n)->rcu;
452450
}
453451

454452
static void tnode_free(struct key_vector *tn)
455453
{
456-
struct callback_head *head = &tn->rcu;
454+
struct callback_head *head = &tn_info(tn)->rcu;
457455

458456
while (head) {
459457
head = head->next;
460458
tnode_free_size += TNODE_SIZE(1ul << tn->bits);
461459
node_free(tn);
462460

463-
tn = container_of(head, struct key_vector, rcu);
461+
tn = container_of(head, struct tnode, rcu)->kv;
464462
}
465463

466464
if (tnode_free_size >= PAGE_SIZE * sync_pages) {

0 commit comments

Comments
 (0)