Commit b6c35976 authored by Simon Wunderlich's avatar Simon Wunderlich Committed by Greg Kroah-Hartman
Browse files

Staging: batman-adv: initialize static hash iterators



instead of dynamically registering hash iterators, calling functions are
changed to register the iterator objects statically. The two advantages are:

 * no memory leaks when aborting from hash_iterate()
 * no calls to kmalloc/kfree, therefore a little faster/safer

Tested with 9 QEMU instances, no obvious regression found.

Signed-off-by: default avatarSimon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 4ce21a7f
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -318,7 +318,7 @@ int hardif_add_interface(char *dev, int if_num)
	struct batman_if *batman_if;
	struct batman_packet *batman_packet;
	struct orig_node *orig_node;
	struct hash_it_t *hashit = NULL;
	HASHIT(hashit);

	batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL);

@@ -377,8 +377,8 @@ int hardif_add_interface(char *dev, int if_num)
	 * if_num */
	spin_lock(&orig_hash_lock);

	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
		orig_node = hashit->bucket->data;
	while (hash_iterate(orig_hash, &hashit)) {
		orig_node = hashit.bucket->data;
		if (resize_orig(orig_node, if_num) == -1) {
			spin_unlock(&orig_hash_lock);
			goto out;
+8 −15
Original line number Diff line number Diff line
@@ -64,24 +64,18 @@ void hash_destroy(struct hashtable_t *hash)
	kfree(hash);
}

/* iterate though the hash. first element is selected with iter_in NULL.  use
 * the returned iterator to access the elements until hash_it_t returns NULL. */
/* iterate though the hash. First element is selected if an iterator
 * initialized with HASHIT() is supplied as iter. Use the returned
 * (or supplied) iterator to access the elements until hash_iterate returns
 * NULL. */

struct hash_it_t *hash_iterate(struct hashtable_t *hash,
			       struct hash_it_t *iter_in)
			       struct hash_it_t *iter)
{
	struct hash_it_t *iter;

	if (!hash)
		return NULL;

	if (iter_in == NULL) {
		iter = kmalloc(sizeof(struct hash_it_t), GFP_ATOMIC);
		iter->index = -1;
		iter->bucket = NULL;
		iter->prev_bucket = NULL;
	} else {
		iter = iter_in;
	}
	if (!iter)
		return NULL;

	/* sanity checks first (if our bucket got deleted in the last
	 * iteration): */
@@ -139,7 +133,6 @@ struct hash_it_t *hash_iterate(struct hashtable_t *hash,
	}

	/* nothing to iterate over anymore */
	kfree(iter);
	return NULL;
}

+5 −0
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@

#ifndef _BATMAN_HASH_H
#define _BATMAN_HASH_H
#define HASHIT(name) struct hash_it_t name = { \
		.index = -1, .bucket = NULL, \
		.prev_bucket = NULL, \
		.first_bucket = NULL }


typedef int (*hashdata_compare_cb)(void *, void *);
typedef int (*hashdata_choose_cb)(void *, int);
+4 −4
Original line number Diff line number Diff line
@@ -221,16 +221,16 @@ static bool purge_orig_node(struct orig_node *orig_node)

void purge_orig(struct work_struct *work)
{
	struct hash_it_t *hashit = NULL;
	HASHIT(hashit);
	struct orig_node *orig_node;

	spin_lock(&orig_hash_lock);

	/* for all origins... */
	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
		orig_node = hashit->bucket->data;
	while (hash_iterate(orig_hash, &hashit)) {
		orig_node = hashit.bucket->data;
		if (purge_orig_node(orig_node)) {
			hash_remove_bucket(orig_hash, hashit);
			hash_remove_bucket(orig_hash, &hashit);
			free_orig_node(orig_node);
		}
	}
+6 −6
Original line number Diff line number Diff line
@@ -186,7 +186,7 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file)

static int proc_originators_read(struct seq_file *seq, void *offset)
{
	struct hash_it_t *hashit = NULL;
	HASHIT(hashit);
	struct orig_node *orig_node;
	struct neigh_node *neigh_node;
	int batman_count = 0;
@@ -215,9 +215,9 @@ static int proc_originators_read(struct seq_file *seq, void *offset)
	rcu_read_unlock();
	spin_lock(&orig_hash_lock);

	while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
	while (hash_iterate(orig_hash, &hashit)) {

		orig_node = hashit->bucket->data;
		orig_node = hashit.bucket->data;

		if (!orig_node->router)
			continue;
@@ -413,7 +413,7 @@ static void proc_vis_read_entry(struct seq_file *seq,

static int proc_vis_read(struct seq_file *seq, void *offset)
{
	struct hash_it_t *hashit = NULL;
	HASHIT(hashit);
	struct vis_info *info;
	struct vis_info_entry *entries;
	struct vis_if_list *if_entries = NULL;
@@ -440,8 +440,8 @@ static int proc_vis_read(struct seq_file *seq, void *offset)
		seq_printf(seq, "digraph {\n");

	spin_lock(&vis_hash_lock);
	while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
		info = hashit->bucket->data;
	while (hash_iterate(vis_hash, &hashit)) {
		info = hashit.bucket->data;
		entries = (struct vis_info_entry *)
			((char *)info + sizeof(struct vis_info));

Loading