Author: simon
Date: 2009-12-13 21:58:12 +0000 (Sun, 13 Dec 2009)
New Revision: 1499
Modified:
trunk/batman-adv-kernelland/hard-interface.c
trunk/batman-adv-kernelland/hash.c
trunk/batman-adv-kernelland/hash.h
trunk/batman-adv-kernelland/originator.c
trunk/batman-adv-kernelland/proc.c
trunk/batman-adv-kernelland/routing.c
trunk/batman-adv-kernelland/translation-table.c
trunk/batman-adv-kernelland/vis.c
Log:
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: Simon Wunderlich <siwu(a)hrz.tu-chemnitz.de>
Modified: trunk/batman-adv-kernelland/hard-interface.c
===================================================================
--- trunk/batman-adv-kernelland/hard-interface.c 2009-12-13 20:33:45 UTC (rev 1498)
+++ trunk/batman-adv-kernelland/hard-interface.c 2009-12-13 21:58:12 UTC (rev 1499)
@@ -318,7 +318,7 @@
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 @@
* 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;
Modified: trunk/batman-adv-kernelland/hash.c
===================================================================
--- trunk/batman-adv-kernelland/hash.c 2009-12-13 20:33:45 UTC (rev 1498)
+++ trunk/batman-adv-kernelland/hash.c 2009-12-13 21:58:12 UTC (rev 1499)
@@ -64,25 +64,19 @@
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)
+ 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;
- }
-
/* sanity checks first (if our bucket got deleted in the last
* iteration): */
if (iter->bucket != NULL) {
@@ -139,7 +133,6 @@
}
/* nothing to iterate over anymore */
- kfree(iter);
return NULL;
}
Modified: trunk/batman-adv-kernelland/hash.h
===================================================================
--- trunk/batman-adv-kernelland/hash.h 2009-12-13 20:33:45 UTC (rev 1498)
+++ trunk/batman-adv-kernelland/hash.h 2009-12-13 21:58:12 UTC (rev 1499)
@@ -21,7 +21,12 @@
#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);
typedef void (*hashdata_free_cb)(void *);
Modified: trunk/batman-adv-kernelland/originator.c
===================================================================
--- trunk/batman-adv-kernelland/originator.c 2009-12-13 20:33:45 UTC (rev 1498)
+++ trunk/batman-adv-kernelland/originator.c 2009-12-13 21:58:12 UTC (rev 1499)
@@ -221,16 +221,16 @@
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);
}
}
Modified: trunk/batman-adv-kernelland/proc.c
===================================================================
--- trunk/batman-adv-kernelland/proc.c 2009-12-13 20:33:45 UTC (rev 1498)
+++ trunk/batman-adv-kernelland/proc.c 2009-12-13 21:58:12 UTC (rev 1499)
@@ -186,7 +186,7 @@
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 @@
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 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 @@
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));
Modified: trunk/batman-adv-kernelland/routing.c
===================================================================
--- trunk/batman-adv-kernelland/routing.c 2009-12-13 20:33:45 UTC (rev 1498)
+++ trunk/batman-adv-kernelland/routing.c 2009-12-13 21:58:12 UTC (rev 1499)
@@ -40,14 +40,14 @@
atomic_t exit_cond;
void slide_own_bcast_window(struct batman_if *batman_if)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
struct orig_node *orig_node;
TYPE_OF_WORD *word;
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;
word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]);
bit_get_packet(word, 1, 0);
Modified: trunk/batman-adv-kernelland/translation-table.c
===================================================================
--- trunk/batman-adv-kernelland/translation-table.c 2009-12-13 20:33:45 UTC (rev 1498)
+++ trunk/batman-adv-kernelland/translation-table.c 2009-12-13 21:58:12 UTC (rev 1499)
@@ -134,18 +134,18 @@
int hna_local_fill_buffer(unsigned char *buff, int buff_len)
{
struct hna_local_entry *hna_local_entry;
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
int i = 0;
unsigned long flags;
spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+ while (hash_iterate(hna_local_hash, &hashit)) {
if (buff_len < (i + 1) * ETH_ALEN)
break;
- hna_local_entry = hashit->bucket->data;
+ hna_local_entry = hashit.bucket->data;
memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN);
i++;
@@ -163,18 +163,18 @@
int hna_local_fill_buffer_text(unsigned char *buff, int buff_len)
{
struct hna_local_entry *hna_local_entry;
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
int bytes_written = 0;
unsigned long flags;
spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
+ while (hash_iterate(hna_local_hash, &hashit)) {
if (buff_len < bytes_written + ETH_STR_LEN + 4)
break;
- hna_local_entry = hashit->bucket->data;
+ hna_local_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4,
" * %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -214,14 +214,14 @@
void hna_local_purge(struct work_struct *work)
{
struct hna_local_entry *hna_local_entry;
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
unsigned long flags;
unsigned long timeout;
spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
- hna_local_entry = hashit->bucket->data;
+ while (hash_iterate(hna_local_hash, &hashit)) {
+ hna_local_entry = hashit.bucket->data;
timeout = hna_local_entry->last_seen +
((LOCAL_HNA_TIMEOUT / 1000) * HZ);
@@ -345,17 +345,17 @@
int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
{
struct hna_global_entry *hna_global_entry;
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
int bytes_written = 0;
unsigned long flags;
spin_lock_irqsave(&hna_global_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_global_hash, hashit))) {
+ while (hash_iterate(hna_global_hash, &hashit)) {
if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10)
break;
- hna_global_entry = hashit->bucket->data;
+ hna_global_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written,
(2 * ETH_STR_LEN) + 10,
Modified: trunk/batman-adv-kernelland/vis.c
===================================================================
--- trunk/batman-adv-kernelland/vis.c 2009-12-13 20:33:45 UTC (rev 1498)
+++ trunk/batman-adv-kernelland/vis.c 2009-12-13 21:58:12 UTC (rev 1499)
@@ -266,12 +266,12 @@
* Must be called with the originator hash locked */
static int find_best_vis_server(struct vis_info *info)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
struct orig_node *orig_node;
int best_tq = -1;
- 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 ((orig_node != NULL) &&
(orig_node->router != NULL) &&
(orig_node->flags & VIS_SERVER) &&
@@ -297,7 +297,8 @@
* returns 0 on success, -1 if no packet could be generated */
static int generate_vis_packet(void)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit_local);
+ HASHIT(hashit_global);
struct orig_node *orig_node;
struct vis_info *info = (struct vis_info *)my_vis_info;
struct vis_info_entry *entry, *entry_array;
@@ -320,13 +321,12 @@
return -1;
}
}
- hashit = NULL;
entry_array = (struct vis_info_entry *)
((char *)info + sizeof(struct vis_info));
- while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
- orig_node = hashit->bucket->data;
+ while (hash_iterate(orig_hash, &hashit_global)) {
+ orig_node = hashit_global.bucket->data;
if (orig_node->router != NULL
&& compare_orig(orig_node->router->addr, orig_node->orig)
&& orig_node->batman_if
@@ -349,10 +349,9 @@
spin_unlock(&orig_hash_lock);
- hashit = NULL;
spin_lock_irqsave(&hna_local_hash_lock, flags);
- while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
- hna_local_entry = hashit->bucket->data;
+ while (hash_iterate(hna_local_hash, &hashit_local)) {
+ hna_local_entry = hashit_local.bucket->data;
entry = &entry_array[info->packet.entries];
memset(entry->src, 0, ETH_ALEN);
memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
@@ -370,16 +369,16 @@
static void purge_vis_packets(void)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
struct vis_info *info;
- while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
- info = hashit->bucket->data;
+ while (hash_iterate(vis_hash, &hashit)) {
+ info = hashit.bucket->data;
if (info == my_vis_info) /* never purge own data. */
continue;
if (time_after(jiffies,
info->first_seen + (VIS_TIMEOUT/1000)*HZ)) {
- hash_remove_bucket(vis_hash, hashit);
+ hash_remove_bucket(vis_hash, &hashit);
free_info(info);
}
}
@@ -387,14 +386,14 @@
static void broadcast_vis_packet(struct vis_info *info, int packet_length)
{
- struct hash_it_t *hashit = NULL;
+ HASHIT(hashit);
struct orig_node *orig_node;
spin_lock(&orig_hash_lock);
/* send to all routers in range. */
- 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 it's a vis server and reachable, send it. */
if (orig_node &&