diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-31 18:02:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-31 18:02:02 -0400 |
commit | c5038a8327b980a5b279fa193163c468011de009 (patch) | |
tree | 6d24fd005340e73360f9c1aa20dd3a1d21fd1625 /net/ipv4/fib_semantics.c | |
parent | d26b3a7c4b3b26319f18bb645de93eba8f4bdcd5 (diff) |
ipv4: Cache routes in nexthop exception entries.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r-- | net/ipv4/fib_semantics.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index fe2ca02a1979..da80dc14cc76 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -140,6 +140,21 @@ const struct fib_prop fib_props[RTN_MAX + 1] = { | |||
140 | }, | 140 | }, |
141 | }; | 141 | }; |
142 | 142 | ||
143 | static void rt_fibinfo_free(struct rtable __rcu **rtp) | ||
144 | { | ||
145 | struct rtable *rt = rcu_dereference_protected(*rtp, 1); | ||
146 | |||
147 | if (!rt) | ||
148 | return; | ||
149 | |||
150 | /* Not even needed : RCU_INIT_POINTER(*rtp, NULL); | ||
151 | * because we waited an RCU grace period before calling | ||
152 | * free_fib_info_rcu() | ||
153 | */ | ||
154 | |||
155 | dst_free(&rt->dst); | ||
156 | } | ||
157 | |||
143 | static void free_nh_exceptions(struct fib_nh *nh) | 158 | static void free_nh_exceptions(struct fib_nh *nh) |
144 | { | 159 | { |
145 | struct fnhe_hash_bucket *hash = nh->nh_exceptions; | 160 | struct fnhe_hash_bucket *hash = nh->nh_exceptions; |
@@ -153,6 +168,9 @@ static void free_nh_exceptions(struct fib_nh *nh) | |||
153 | struct fib_nh_exception *next; | 168 | struct fib_nh_exception *next; |
154 | 169 | ||
155 | next = rcu_dereference_protected(fnhe->fnhe_next, 1); | 170 | next = rcu_dereference_protected(fnhe->fnhe_next, 1); |
171 | |||
172 | rt_fibinfo_free(&fnhe->fnhe_rth); | ||
173 | |||
156 | kfree(fnhe); | 174 | kfree(fnhe); |
157 | 175 | ||
158 | fnhe = next; | 176 | fnhe = next; |
@@ -161,22 +179,7 @@ static void free_nh_exceptions(struct fib_nh *nh) | |||
161 | kfree(hash); | 179 | kfree(hash); |
162 | } | 180 | } |
163 | 181 | ||
164 | static void rt_nexthop_free(struct rtable __rcu **rtp) | 182 | static void rt_fibinfo_free_cpus(struct rtable __rcu * __percpu *rtp) |
165 | { | ||
166 | struct rtable *rt = rcu_dereference_protected(*rtp, 1); | ||
167 | |||
168 | if (!rt) | ||
169 | return; | ||
170 | |||
171 | /* Not even needed : RCU_INIT_POINTER(*rtp, NULL); | ||
172 | * because we waited an RCU grace period before calling | ||
173 | * free_fib_info_rcu() | ||
174 | */ | ||
175 | |||
176 | dst_free(&rt->dst); | ||
177 | } | ||
178 | |||
179 | static void rt_nexthop_free_cpus(struct rtable __rcu * __percpu *rtp) | ||
180 | { | 183 | { |
181 | int cpu; | 184 | int cpu; |
182 | 185 | ||
@@ -203,8 +206,8 @@ static void free_fib_info_rcu(struct rcu_head *head) | |||
203 | dev_put(nexthop_nh->nh_dev); | 206 | dev_put(nexthop_nh->nh_dev); |
204 | if (nexthop_nh->nh_exceptions) | 207 | if (nexthop_nh->nh_exceptions) |
205 | free_nh_exceptions(nexthop_nh); | 208 | free_nh_exceptions(nexthop_nh); |
206 | rt_nexthop_free_cpus(nexthop_nh->nh_pcpu_rth_output); | 209 | rt_fibinfo_free_cpus(nexthop_nh->nh_pcpu_rth_output); |
207 | rt_nexthop_free(&nexthop_nh->nh_rth_input); | 210 | rt_fibinfo_free(&nexthop_nh->nh_rth_input); |
208 | } endfor_nexthops(fi); | 211 | } endfor_nexthops(fi); |
209 | 212 | ||
210 | release_net(fi->fib_net); | 213 | release_net(fi->fib_net); |