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_ */
|
||