Since forwarding database gets a lot of memory alloc/free on a busy
bridge, use kmem_cache_alloc to provide cache and better stats.
diff -Nru a/net/bridge/br.c b/net/bridge/br.c
--- a/net/bridge/br.c Tue Apr 13 13:17:16 2004
+++ b/net/bridge/br.c Tue Apr 13 13:17:16 2004
@@ -31,6 +31,8 @@
static int __init br_init(void)
{
+ br_fdb_init();
+
#ifdef CONFIG_BRIDGE_NETFILTER
if (br_netfilter_init())
return 1;
@@ -65,6 +67,7 @@
#endif
br_handle_frame_hook = NULL;
+ br_fdb_fini();
}
EXPORT_SYMBOL(br_should_route_hook);
diff -Nru a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
--- a/net/bridge/br_fdb.c Tue Apr 13 13:17:16 2004
+++ b/net/bridge/br_fdb.c Tue Apr 13 13:17:16 2004
@@ -22,6 +22,22 @@
#include <asm/uaccess.h>
#include "br_private.h"
+static kmem_cache_t *br_fdb_cache;
+
+void __init br_fdb_init(void)
+{
+ br_fdb_cache = kmem_cache_create("bridge_fdb_cache",
+ sizeof(struct net_bridge_fdb_entry),
+ 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+}
+
+void __exit br_fdb_fini(void)
+{
+ kmem_cache_destroy(br_fdb_cache);
+}
+
+
/* if topology_changing then use forward_delay (default 15 sec)
* otherwise keep longer (default 5 minutes)
*/
@@ -37,7 +53,7 @@
&& time_before_eq(fdb->ageing_timer + hold_time(br), jiffies);
}
-static __inline__ void copy_fdb(struct __fdb_entry *ent,
+static inline void copy_fdb(struct __fdb_entry *ent,
const struct net_bridge_fdb_entry *f)
{
memset(ent, 0, sizeof(struct __fdb_entry));
@@ -180,7 +196,7 @@
void br_fdb_put(struct net_bridge_fdb_entry *ent)
{
if (atomic_dec_and_test(&ent->use_count))
- kfree(ent);
+ kmem_cache_free(br_fdb_cache, ent);
}
int br_fdb_get_entries(struct net_bridge *br, void __user *buf,
@@ -224,7 +240,7 @@
/* entry was deleted during copy_to_user */
if (atomic_dec_and_test(&f->use_count)) {
- kfree(f);
+ kmem_cache_free(br_fdb_cache, f);
num = -EAGAIN;
goto out;
}
@@ -283,7 +299,7 @@
}
}
- fdb = kmalloc(sizeof(*fdb), GFP_ATOMIC);
+ fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC);
if (unlikely(fdb == NULL)) {
ret = -ENOMEM;
goto out;
diff -Nru a/net/bridge/br_private.h b/net/bridge/br_private.h
--- a/net/bridge/br_private.h Tue Apr 13 13:17:16 2004
+++ b/net/bridge/br_private.h Tue Apr 13 13:17:16 2004
@@ -127,6 +127,8 @@
extern int br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
/* br_fdb.c */
+extern void br_fdb_init(void);
+extern void br_fdb_fini(void);
extern void br_fdb_changeaddr(struct net_bridge_port *p,
const unsigned char *newaddr);
extern void br_fdb_cleanup(unsigned long arg);
|