Kmalloc-kmem-cache-tests » 0002-batman-adv-use-kmem_cache-for-translation-table.patch
net/batman-adv/main.c | ||
---|---|---|
static int __init batadv_init(void)
|
||
{
|
||
int ret;
|
||
ret = batadv_tt_cache_init();
|
||
if (ret < 0)
|
||
return ret;
|
||
INIT_LIST_HEAD(&batadv_hardif_list);
|
||
INIT_HLIST_HEAD(&batadv_algo_list);
|
||
... | ... | |
batadv_nc_init();
|
||
batadv_event_workqueue = create_singlethread_workqueue("bat_events");
|
||
if (!batadv_event_workqueue)
|
||
return -ENOMEM;
|
||
goto err_create_wq;
|
||
batadv_socket_init();
|
||
batadv_debugfs_init();
|
||
... | ... | |
BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION);
|
||
return 0;
|
||
err_create_wq:
|
||
batadv_tt_cache_destroy();
|
||
return -ENOMEM;
|
||
}
|
||
static void __exit batadv_exit(void)
|
||
... | ... | |
batadv_event_workqueue = NULL;
|
||
rcu_barrier();
|
||
batadv_tt_cache_destroy();
|
||
}
|
||
int batadv_mesh_init(struct net_device *soft_iface)
|
net/batman-adv/translation-table.c | ||
---|---|---|
#include <linux/bitops.h>
|
||
#include <linux/bug.h>
|
||
#include <linux/byteorder/generic.h>
|
||
#include <linux/cache.h>
|
||
#include <linux/compiler.h>
|
||
#include <linux/crc32c.h>
|
||
#include <linux/errno.h>
|
||
#include <linux/etherdevice.h>
|
||
#include <linux/fs.h>
|
||
#include <linux/if_ether.h>
|
||
#include <linux/init.h>
|
||
#include <linux/jhash.h>
|
||
#include <linux/jiffies.h>
|
||
#include <linux/kernel.h>
|
||
... | ... | |
#include "packet.h"
|
||
#include "soft-interface.h"
|
||
static struct kmem_cache *batadv_tl_cache __read_mostly;
|
||
static struct kmem_cache *batadv_tg_cache __read_mostly;
|
||
static struct kmem_cache *batadv_tt_orig_cache __read_mostly;
|
||
/* hash class keys */
|
||
static struct lock_class_key batadv_tt_local_hash_lock_class_key;
|
||
static struct lock_class_key batadv_tt_global_hash_lock_class_key;
|
||
... | ... | |
}
|
||
/**
|
||
* batadv_tt_local_entry_free_rcu - free the tt_local_entry
|
||
* @rcu: rcu pointer of the tt_local_entry
|
||
*/
|
||
static void batadv_tt_local_entry_free_rcu(struct rcu_head *rcu)
|
||
{
|
||
struct batadv_tt_local_entry *tt_local_entry;
|
||
tt_local_entry = container_of(rcu, struct batadv_tt_local_entry,
|
||
common.rcu);
|
||
kmem_cache_free(batadv_tl_cache, tt_local_entry);
|
||
}
|
||
/**
|
||
* batadv_tt_local_entry_release - release tt_local_entry from lists and queue
|
||
* for free after rcu grace period
|
||
* @ref: kref pointer of the nc_node
|
||
... | ... | |
batadv_softif_vlan_put(tt_local_entry->vlan);
|
||
kfree_rcu(tt_local_entry, common.rcu);
|
||
call_rcu(&tt_local_entry->common.rcu, batadv_tt_local_entry_free_rcu);
|
||
}
|
||
/**
|
||
... | ... | |
}
|
||
/**
|
||
* batadv_tt_global_entry_free_rcu - free the tt_global_entry
|
||
* @rcu: rcu pointer of the tt_global_entry
|
||
*/
|
||
static void batadv_tt_global_entry_free_rcu(struct rcu_head *rcu)
|
||
{
|
||
struct batadv_tt_global_entry *tt_global_entry;
|
||
tt_global_entry = container_of(rcu, struct batadv_tt_global_entry,
|
||
common.rcu);
|
||
kmem_cache_free(batadv_tg_cache, tt_global_entry);
|
||
}
|
||
/**
|
||
* batadv_tt_global_entry_release - release tt_global_entry from lists and queue
|
||
* for free after rcu grace period
|
||
* @ref: kref pointer of the nc_node
|
||
... | ... | |
common.refcount);
|
||
batadv_tt_global_del_orig_list(tt_global_entry);
|
||
kfree_rcu(tt_global_entry, common.rcu);
|
||
call_rcu(&tt_global_entry->common.rcu, batadv_tt_global_entry_free_rcu);
|
||
}
|
||
/**
|
||
... | ... | |
}
|
||
/**
|
||
* batadv_tt_orig_list_entry_free_rcu - free the orig_entry
|
||
* @rcu: rcu pointer of the orig_entry
|
||
*/
|
||
static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
|
||
{
|
||
struct batadv_tt_orig_list_entry *orig_entry;
|
||
orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
|
||
kmem_cache_free(batadv_tt_orig_cache, orig_entry);
|
||
}
|
||
/**
|
||
* batadv_tt_orig_list_entry_release - release tt orig entry from lists and
|
||
* queue for free after rcu grace period
|
||
* @ref: kref pointer of the tt orig entry
|
||
... | ... | |
refcount);
|
||
batadv_orig_node_put(orig_entry->orig_node);
|
||
kfree_rcu(orig_entry, rcu);
|
||
call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
|
||
}
|
||
/**
|
||
... | ... | |
goto out;
|
||
}
|
||
tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
|
||
tt_local = kmem_cache_alloc(batadv_tl_cache, GFP_ATOMIC);
|
||
if (!tt_local)
|
||
goto out;
|
||
... | ... | |
vlan = batadv_softif_vlan_get(bat_priv, vid);
|
||
if (WARN(!vlan, "adding TT local entry %pM to non-existent VLAN %d",
|
||
addr, BATADV_PRINT_VID(vid))) {
|
||
kfree(tt_local);
|
||
kmem_cache_free(batadv_tl_cache, tt_local);
|
||
tt_local = NULL;
|
||
goto out;
|
||
}
|
||
... | ... | |
goto out;
|
||
}
|
||
orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
|
||
orig_entry = kmem_cache_zalloc(batadv_tt_orig_cache, GFP_ATOMIC);
|
||
if (!orig_entry)
|
||
goto out;
|
||
... | ... | |
goto out;
|
||
if (!tt_global_entry) {
|
||
tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC);
|
||
tt_global_entry = kmem_cache_zalloc(batadv_tg_cache,
|
||
GFP_ATOMIC);
|
||
if (!tt_global_entry)
|
||
goto out;
|
||
... | ... | |
return ret;
|
||
}
|
||
/**
|
||
* batadv_tt_cache_init - Initialize tt memory object cache
|
||
*
|
||
* Return: 0 on success or negative error number in case of failure.
|
||
*/
|
||
int __init batadv_tt_cache_init(void)
|
||
{
|
||
size_t tl_size = sizeof(struct batadv_tt_local_entry);
|
||
size_t tg_size = sizeof(struct batadv_tt_global_entry);
|
||
size_t tt_orig_size = sizeof(struct batadv_tt_orig_list_entry);
|
||
batadv_tl_cache = kmem_cache_create("batadv_tl_cache", tl_size, 0,
|
||
SLAB_HWCACHE_ALIGN, NULL);
|
||
if (!batadv_tl_cache)
|
||
return -ENOMEM;
|
||
batadv_tg_cache = kmem_cache_create("batadv_tg_cache", tg_size, 0,
|
||
SLAB_HWCACHE_ALIGN, NULL);
|
||
if (!batadv_tg_cache)
|
||
goto err_tg_alloc;
|
||
batadv_tt_orig_cache = kmem_cache_create("batadv_tt_orig_cache",
|
||
tt_orig_size, 0,
|
||
SLAB_HWCACHE_ALIGN, NULL);
|
||
if (!batadv_tt_orig_cache)
|
||
goto err_tt_orig_alloc;
|
||
return 0;
|
||
err_tt_orig_alloc:
|
||
kmem_cache_destroy(batadv_tg_cache);
|
||
batadv_tg_cache = NULL;
|
||
err_tg_alloc:
|
||
kmem_cache_destroy(batadv_tl_cache);
|
||
batadv_tl_cache = NULL;
|
||
return -ENOMEM;
|
||
}
|
||
/**
|
||
* batadv_tt_cache_destroy - Destroy tt memory object cache
|
||
*/
|
||
void batadv_tt_cache_destroy(void)
|
||
{
|
||
kmem_cache_destroy(batadv_tl_cache);
|
||
kmem_cache_destroy(batadv_tg_cache);
|
||
kmem_cache_destroy(batadv_tt_orig_cache);
|
||
}
|
net/batman-adv/translation-table.h | ||
---|---|---|
bool batadv_tt_global_is_isolated(struct batadv_priv *bat_priv,
|
||
const u8 *addr, unsigned short vid);
|
||
int batadv_tt_cache_init(void);
|
||
void batadv_tt_cache_destroy(void);
|
||
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
|