diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 24 |
1 files changed, 3 insertions, 21 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 504f7f1cad94..fbd106edbe59 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -180,7 +180,6 @@ struct tun_struct { | |||
180 | int debug; | 180 | int debug; |
181 | #endif | 181 | #endif |
182 | spinlock_t lock; | 182 | spinlock_t lock; |
183 | struct kmem_cache *flow_cache; | ||
184 | struct hlist_head flows[TUN_NUM_FLOW_ENTRIES]; | 183 | struct hlist_head flows[TUN_NUM_FLOW_ENTRIES]; |
185 | struct timer_list flow_gc_timer; | 184 | struct timer_list flow_gc_timer; |
186 | unsigned long ageing_time; | 185 | unsigned long ageing_time; |
@@ -209,8 +208,8 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun, | |||
209 | struct hlist_head *head, | 208 | struct hlist_head *head, |
210 | u32 rxhash, u16 queue_index) | 209 | u32 rxhash, u16 queue_index) |
211 | { | 210 | { |
212 | struct tun_flow_entry *e = kmem_cache_alloc(tun->flow_cache, | 211 | struct tun_flow_entry *e = kmalloc(sizeof(*e), GFP_ATOMIC); |
213 | GFP_ATOMIC); | 212 | |
214 | if (e) { | 213 | if (e) { |
215 | tun_debug(KERN_INFO, tun, "create flow: hash %u index %u\n", | 214 | tun_debug(KERN_INFO, tun, "create flow: hash %u index %u\n", |
216 | rxhash, queue_index); | 215 | rxhash, queue_index); |
@@ -223,19 +222,12 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun, | |||
223 | return e; | 222 | return e; |
224 | } | 223 | } |
225 | 224 | ||
226 | static void tun_flow_free(struct rcu_head *head) | ||
227 | { | ||
228 | struct tun_flow_entry *e | ||
229 | = container_of(head, struct tun_flow_entry, rcu); | ||
230 | kmem_cache_free(e->tun->flow_cache, e); | ||
231 | } | ||
232 | |||
233 | static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e) | 225 | static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e) |
234 | { | 226 | { |
235 | tun_debug(KERN_INFO, tun, "delete flow: hash %u index %u\n", | 227 | tun_debug(KERN_INFO, tun, "delete flow: hash %u index %u\n", |
236 | e->rxhash, e->queue_index); | 228 | e->rxhash, e->queue_index); |
237 | hlist_del_rcu(&e->hash_link); | 229 | hlist_del_rcu(&e->hash_link); |
238 | call_rcu(&e->rcu, tun_flow_free); | 230 | kfree_rcu(e, rcu); |
239 | } | 231 | } |
240 | 232 | ||
241 | static void tun_flow_flush(struct tun_struct *tun) | 233 | static void tun_flow_flush(struct tun_struct *tun) |
@@ -833,12 +825,6 @@ static int tun_flow_init(struct tun_struct *tun) | |||
833 | { | 825 | { |
834 | int i; | 826 | int i; |
835 | 827 | ||
836 | tun->flow_cache = kmem_cache_create("tun_flow_cache", | ||
837 | sizeof(struct tun_flow_entry), 0, 0, | ||
838 | NULL); | ||
839 | if (!tun->flow_cache) | ||
840 | return -ENOMEM; | ||
841 | |||
842 | for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) | 828 | for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) |
843 | INIT_HLIST_HEAD(&tun->flows[i]); | 829 | INIT_HLIST_HEAD(&tun->flows[i]); |
844 | 830 | ||
@@ -854,10 +840,6 @@ static void tun_flow_uninit(struct tun_struct *tun) | |||
854 | { | 840 | { |
855 | del_timer_sync(&tun->flow_gc_timer); | 841 | del_timer_sync(&tun->flow_gc_timer); |
856 | tun_flow_flush(tun); | 842 | tun_flow_flush(tun); |
857 | |||
858 | /* Wait for completion of call_rcu()'s */ | ||
859 | rcu_barrier(); | ||
860 | kmem_cache_destroy(tun->flow_cache); | ||
861 | } | 843 | } |
862 | 844 | ||
863 | /* Initialize net device. */ | 845 | /* Initialize net device. */ |