Loading net/batman-adv/hash.c +0 −8 Original line number Diff line number Diff line Loading @@ -68,11 +68,3 @@ struct hashtable_t *hash_new(int size) kfree(hash); return NULL; } void bucket_free_rcu(struct rcu_head *rcu) { struct element_t *bucket; bucket = container_of(rcu, struct element_t, rcu); kfree(bucket); } net/batman-adv/hash.h +24 −71 Original line number Diff line number Diff line Loading @@ -28,19 +28,13 @@ * compare 2 element datas for their keys, * return 0 if same and not 0 if not * same */ typedef int (*hashdata_compare_cb)(void *, void *); typedef int (*hashdata_compare_cb)(struct hlist_node *, void *); /* the hashfunction, should return an index * based on the key in the data of the first * argument and the size the second */ typedef int (*hashdata_choose_cb)(void *, int); typedef void (*hashdata_free_cb)(void *, void *); struct element_t { void *data; /* pointer to the data */ struct hlist_node hlist; /* bucket list pointer */ struct rcu_head rcu; }; typedef void (*hashdata_free_cb)(struct hlist_node *, void *); struct hashtable_t { struct hlist_head *table; /* the hashtable itself with the buckets */ Loading @@ -54,8 +48,6 @@ struct hashtable_t *hash_new(int size); /* free only the hashtable and the hash itself. */ void hash_destroy(struct hashtable_t *hash); void bucket_free_rcu(struct rcu_head *rcu); /* remove the hash structure. if hashdata_free_cb != NULL, this function will be * called to remove the elements inside of the hash. if you don't remove the * elements, memory might be leaked. */ Loading @@ -63,8 +55,7 @@ static inline void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg) { struct hlist_head *head; struct hlist_node *walk, *safe; struct element_t *bucket; struct hlist_node *node, *node_tmp; spinlock_t *list_lock; /* spinlock to protect write access */ int i; Loading @@ -73,12 +64,11 @@ static inline void hash_delete(struct hashtable_t *hash, list_lock = &hash->list_locks[i]; spin_lock_bh(list_lock); hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { if (free_cb) free_cb(bucket->data, arg); hlist_for_each_safe(node, node_tmp, head) { hlist_del_rcu(node); hlist_del_rcu(walk); call_rcu(&bucket->rcu, bucket_free_rcu); if (free_cb) free_cb(node, arg); } spin_unlock_bh(list_lock); } Loading @@ -89,12 +79,12 @@ static inline void hash_delete(struct hashtable_t *hash, /* adds data to the hashtable. returns 0 on success, -1 on error */ static inline int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, hashdata_choose_cb choose, void *data) hashdata_choose_cb choose, void *data, struct hlist_node *data_node) { int index; struct hlist_head *head; struct hlist_node *walk, *safe; struct element_t *bucket; struct hlist_node *node; spinlock_t *list_lock; /* spinlock to protect write access */ if (!hash) Loading @@ -105,21 +95,17 @@ static inline int hash_add(struct hashtable_t *hash, list_lock = &hash->list_locks[index]; rcu_read_lock(); hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { if (compare(bucket->data, data)) __hlist_for_each_rcu(node, head) { if (!compare(node, data)) continue; goto err_unlock; } rcu_read_unlock(); /* no duplicate found in list, add new element */ bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC); if (!bucket) goto err; bucket->data = data; spin_lock_bh(list_lock); hlist_add_head_rcu(&bucket->hlist, head); hlist_add_head_rcu(data_node, head); spin_unlock_bh(list_lock); return 0; Loading @@ -139,8 +125,7 @@ static inline void *hash_remove(struct hashtable_t *hash, hashdata_choose_cb choose, void *data) { size_t index; struct hlist_node *walk; struct element_t *bucket; struct hlist_node *node; struct hlist_head *head; void *data_save = NULL; Loading @@ -148,49 +133,17 @@ static inline void *hash_remove(struct hashtable_t *hash, head = &hash->table[index]; spin_lock_bh(&hash->list_locks[index]); hlist_for_each_entry(bucket, walk, head, hlist) { if (compare(bucket->data, data)) { data_save = bucket->data; hlist_del_rcu(walk); call_rcu(&bucket->rcu, bucket_free_rcu); hlist_for_each(node, head) { if (!compare(node, data)) continue; data_save = node; hlist_del_rcu(node); break; } } spin_unlock_bh(&hash->list_locks[index]); return data_save; } /** * finds data, based on the key in keydata. returns the found data on success, * or NULL on error * * caller must lock with rcu_read_lock() / rcu_read_unlock() **/ static inline void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare, hashdata_choose_cb choose, void *keydata) { int index; struct hlist_head *head; struct hlist_node *walk; struct element_t *bucket; void *bucket_data = NULL; if (!hash) return NULL; index = choose(keydata , hash->size); head = &hash->table[index]; hlist_for_each_entry(bucket, walk, head, hlist) { if (compare(bucket->data, keydata)) { bucket_data = bucket->data; break; } } return bucket_data; } #endif /* _NET_BATMAN_ADV_HASH_H_ */ net/batman-adv/icmp_socket.c +1 −4 Original line number Diff line number Diff line Loading @@ -222,14 +222,11 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, spin_lock_bh(&bat_priv->orig_hash_lock); rcu_read_lock(); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, compare_orig, choose_orig, icmp_packet->dst)); orig_node = orig_hash_find(bat_priv, icmp_packet->dst); if (!orig_node) goto unlock; kref_get(&orig_node->refcount); neigh_node = orig_node->router; if (!neigh_node) Loading net/batman-adv/originator.c +21 −52 Original line number Diff line number Diff line Loading @@ -140,9 +140,8 @@ void orig_node_free_ref(struct kref *refcount) void originator_free(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk, *safe; struct hlist_node *node, *node_tmp; struct hlist_head *head; struct element_t *bucket; spinlock_t *list_lock; /* spinlock to protect write access */ struct orig_node *orig_node; int i; Loading @@ -160,11 +159,10 @@ void originator_free(struct bat_priv *bat_priv) list_lock = &hash->list_locks[i]; spin_lock_bh(list_lock); hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_safe(orig_node, node, node_tmp, head, hash_entry) { hlist_del_rcu(walk); call_rcu(&bucket->rcu, bucket_free_rcu); hlist_del_rcu(node); kref_put(&orig_node->refcount, orig_node_free_ref); } spin_unlock_bh(list_lock); Loading @@ -174,18 +172,6 @@ void originator_free(struct bat_priv *bat_priv) spin_unlock_bh(&bat_priv->orig_hash_lock); } static void bucket_free_orig_rcu(struct rcu_head *rcu) { struct element_t *bucket; struct orig_node *orig_node; bucket = container_of(rcu, struct element_t, rcu); orig_node = bucket->data; kref_put(&orig_node->refcount, orig_node_free_ref); kfree(bucket); } /* this function finds or creates an originator entry for the given * address if it does not exits */ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) Loading @@ -194,16 +180,9 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) int size; int hash_added; rcu_read_lock(); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, compare_orig, choose_orig, addr)); rcu_read_unlock(); if (orig_node) { kref_get(&orig_node->refcount); orig_node = orig_hash_find(bat_priv, addr); if (orig_node) return orig_node; } bat_dbg(DBG_BATMAN, bat_priv, "Creating new originator: %pM\n", addr); Loading Loading @@ -245,8 +224,8 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) if (!orig_node->bcast_own_sum) goto free_bcast_own; hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig, orig_node); hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig, orig_node, &orig_node->hash_entry); if (hash_added < 0) goto free_bcast_own_sum; Loading Loading @@ -346,9 +325,8 @@ static bool purge_orig_node(struct bat_priv *bat_priv, static void _purge_orig(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk, *safe; struct hlist_node *node, *node_tmp; struct hlist_head *head; struct element_t *bucket; spinlock_t *list_lock; /* spinlock to protect write access */ struct orig_node *orig_node; int i; Loading @@ -364,14 +342,14 @@ static void _purge_orig(struct bat_priv *bat_priv) list_lock = &hash->list_locks[i]; spin_lock_bh(list_lock); hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_safe(orig_node, node, node_tmp, head, hash_entry) { if (purge_orig_node(bat_priv, orig_node)) { if (orig_node->gw_flags) gw_node_delete(bat_priv, orig_node); hlist_del_rcu(walk); call_rcu(&bucket->rcu, bucket_free_orig_rcu); hlist_del_rcu(node); kref_put(&orig_node->refcount, orig_node_free_ref); continue; } Loading Loading @@ -411,9 +389,8 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) struct net_device *net_dev = (struct net_device *)seq->private; struct bat_priv *bat_priv = netdev_priv(net_dev); struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk, *node; struct hlist_node *node, *node_tmp; struct hlist_head *head; struct element_t *bucket; struct orig_node *orig_node; struct neigh_node *neigh_node; int batman_count = 0; Loading Loading @@ -447,9 +424,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) head = &hash->table[i]; rcu_read_lock(); hlist_for_each_entry_rcu(bucket, walk, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { if (!orig_node->router) continue; Loading @@ -468,7 +443,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) neigh_node->addr, neigh_node->if_incoming->net_dev->name); hlist_for_each_entry_rcu(neigh_node, node, hlist_for_each_entry_rcu(neigh_node, node_tmp, &orig_node->neigh_list, list) { seq_printf(seq, " %pM (%3i)", neigh_node->addr, neigh_node->tq_avg); Loading Loading @@ -522,9 +497,8 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) { struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk; struct hlist_node *node; struct hlist_head *head; struct element_t *bucket; struct orig_node *orig_node; int i, ret; Loading @@ -536,9 +510,7 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) head = &hash->table[i]; rcu_read_lock(); hlist_for_each_entry_rcu(bucket, walk, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { spin_lock_bh(&orig_node->ogm_cnt_lock); ret = orig_node_add_if(orig_node, max_if_num); spin_unlock_bh(&orig_node->ogm_cnt_lock); Loading Loading @@ -614,9 +586,8 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) { struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk; struct hlist_node *node; struct hlist_head *head; struct element_t *bucket; struct batman_if *batman_if_tmp; struct orig_node *orig_node; int i, ret; Loading @@ -629,9 +600,7 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) head = &hash->table[i]; rcu_read_lock(); hlist_for_each_entry_rcu(bucket, walk, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { spin_lock_bh(&orig_node->ogm_cnt_lock); ret = orig_node_del_if(orig_node, max_if_num, batman_if->if_num); Loading net/batman-adv/originator.h +34 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #ifndef _NET_BATMAN_ADV_ORIGINATOR_H_ #define _NET_BATMAN_ADV_ORIGINATOR_H_ #include "hash.h" int originator_init(struct bat_priv *bat_priv); void originator_free(struct bat_priv *bat_priv); void purge_orig_ref(struct bat_priv *bat_priv); Loading @@ -38,8 +40,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num); /* returns 1 if they are the same originator */ static inline int compare_orig(void *data1, void *data2) static inline int compare_orig(struct hlist_node *node, void *data2) { void *data1 = container_of(node, struct orig_node, hash_entry); return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); } Loading @@ -64,4 +68,33 @@ static inline int choose_orig(void *data, int32_t size) return hash % size; } static inline struct orig_node *orig_hash_find(struct bat_priv *bat_priv, void *data) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_head *head; struct hlist_node *node; struct orig_node *orig_node, *orig_node_tmp = NULL; int index; if (!hash) return NULL; index = choose_orig(data, hash->size); head = &hash->table[index]; rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { if (!compare_eth(orig_node, data)) continue; orig_node_tmp = orig_node; kref_get(&orig_node_tmp->refcount); break; } rcu_read_unlock(); return orig_node_tmp; } #endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */ Loading
net/batman-adv/hash.c +0 −8 Original line number Diff line number Diff line Loading @@ -68,11 +68,3 @@ struct hashtable_t *hash_new(int size) kfree(hash); return NULL; } void bucket_free_rcu(struct rcu_head *rcu) { struct element_t *bucket; bucket = container_of(rcu, struct element_t, rcu); kfree(bucket); }
net/batman-adv/hash.h +24 −71 Original line number Diff line number Diff line Loading @@ -28,19 +28,13 @@ * compare 2 element datas for their keys, * return 0 if same and not 0 if not * same */ typedef int (*hashdata_compare_cb)(void *, void *); typedef int (*hashdata_compare_cb)(struct hlist_node *, void *); /* the hashfunction, should return an index * based on the key in the data of the first * argument and the size the second */ typedef int (*hashdata_choose_cb)(void *, int); typedef void (*hashdata_free_cb)(void *, void *); struct element_t { void *data; /* pointer to the data */ struct hlist_node hlist; /* bucket list pointer */ struct rcu_head rcu; }; typedef void (*hashdata_free_cb)(struct hlist_node *, void *); struct hashtable_t { struct hlist_head *table; /* the hashtable itself with the buckets */ Loading @@ -54,8 +48,6 @@ struct hashtable_t *hash_new(int size); /* free only the hashtable and the hash itself. */ void hash_destroy(struct hashtable_t *hash); void bucket_free_rcu(struct rcu_head *rcu); /* remove the hash structure. if hashdata_free_cb != NULL, this function will be * called to remove the elements inside of the hash. if you don't remove the * elements, memory might be leaked. */ Loading @@ -63,8 +55,7 @@ static inline void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg) { struct hlist_head *head; struct hlist_node *walk, *safe; struct element_t *bucket; struct hlist_node *node, *node_tmp; spinlock_t *list_lock; /* spinlock to protect write access */ int i; Loading @@ -73,12 +64,11 @@ static inline void hash_delete(struct hashtable_t *hash, list_lock = &hash->list_locks[i]; spin_lock_bh(list_lock); hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { if (free_cb) free_cb(bucket->data, arg); hlist_for_each_safe(node, node_tmp, head) { hlist_del_rcu(node); hlist_del_rcu(walk); call_rcu(&bucket->rcu, bucket_free_rcu); if (free_cb) free_cb(node, arg); } spin_unlock_bh(list_lock); } Loading @@ -89,12 +79,12 @@ static inline void hash_delete(struct hashtable_t *hash, /* adds data to the hashtable. returns 0 on success, -1 on error */ static inline int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, hashdata_choose_cb choose, void *data) hashdata_choose_cb choose, void *data, struct hlist_node *data_node) { int index; struct hlist_head *head; struct hlist_node *walk, *safe; struct element_t *bucket; struct hlist_node *node; spinlock_t *list_lock; /* spinlock to protect write access */ if (!hash) Loading @@ -105,21 +95,17 @@ static inline int hash_add(struct hashtable_t *hash, list_lock = &hash->list_locks[index]; rcu_read_lock(); hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { if (compare(bucket->data, data)) __hlist_for_each_rcu(node, head) { if (!compare(node, data)) continue; goto err_unlock; } rcu_read_unlock(); /* no duplicate found in list, add new element */ bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC); if (!bucket) goto err; bucket->data = data; spin_lock_bh(list_lock); hlist_add_head_rcu(&bucket->hlist, head); hlist_add_head_rcu(data_node, head); spin_unlock_bh(list_lock); return 0; Loading @@ -139,8 +125,7 @@ static inline void *hash_remove(struct hashtable_t *hash, hashdata_choose_cb choose, void *data) { size_t index; struct hlist_node *walk; struct element_t *bucket; struct hlist_node *node; struct hlist_head *head; void *data_save = NULL; Loading @@ -148,49 +133,17 @@ static inline void *hash_remove(struct hashtable_t *hash, head = &hash->table[index]; spin_lock_bh(&hash->list_locks[index]); hlist_for_each_entry(bucket, walk, head, hlist) { if (compare(bucket->data, data)) { data_save = bucket->data; hlist_del_rcu(walk); call_rcu(&bucket->rcu, bucket_free_rcu); hlist_for_each(node, head) { if (!compare(node, data)) continue; data_save = node; hlist_del_rcu(node); break; } } spin_unlock_bh(&hash->list_locks[index]); return data_save; } /** * finds data, based on the key in keydata. returns the found data on success, * or NULL on error * * caller must lock with rcu_read_lock() / rcu_read_unlock() **/ static inline void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare, hashdata_choose_cb choose, void *keydata) { int index; struct hlist_head *head; struct hlist_node *walk; struct element_t *bucket; void *bucket_data = NULL; if (!hash) return NULL; index = choose(keydata , hash->size); head = &hash->table[index]; hlist_for_each_entry(bucket, walk, head, hlist) { if (compare(bucket->data, keydata)) { bucket_data = bucket->data; break; } } return bucket_data; } #endif /* _NET_BATMAN_ADV_HASH_H_ */
net/batman-adv/icmp_socket.c +1 −4 Original line number Diff line number Diff line Loading @@ -222,14 +222,11 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, spin_lock_bh(&bat_priv->orig_hash_lock); rcu_read_lock(); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, compare_orig, choose_orig, icmp_packet->dst)); orig_node = orig_hash_find(bat_priv, icmp_packet->dst); if (!orig_node) goto unlock; kref_get(&orig_node->refcount); neigh_node = orig_node->router; if (!neigh_node) Loading
net/batman-adv/originator.c +21 −52 Original line number Diff line number Diff line Loading @@ -140,9 +140,8 @@ void orig_node_free_ref(struct kref *refcount) void originator_free(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk, *safe; struct hlist_node *node, *node_tmp; struct hlist_head *head; struct element_t *bucket; spinlock_t *list_lock; /* spinlock to protect write access */ struct orig_node *orig_node; int i; Loading @@ -160,11 +159,10 @@ void originator_free(struct bat_priv *bat_priv) list_lock = &hash->list_locks[i]; spin_lock_bh(list_lock); hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_safe(orig_node, node, node_tmp, head, hash_entry) { hlist_del_rcu(walk); call_rcu(&bucket->rcu, bucket_free_rcu); hlist_del_rcu(node); kref_put(&orig_node->refcount, orig_node_free_ref); } spin_unlock_bh(list_lock); Loading @@ -174,18 +172,6 @@ void originator_free(struct bat_priv *bat_priv) spin_unlock_bh(&bat_priv->orig_hash_lock); } static void bucket_free_orig_rcu(struct rcu_head *rcu) { struct element_t *bucket; struct orig_node *orig_node; bucket = container_of(rcu, struct element_t, rcu); orig_node = bucket->data; kref_put(&orig_node->refcount, orig_node_free_ref); kfree(bucket); } /* this function finds or creates an originator entry for the given * address if it does not exits */ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) Loading @@ -194,16 +180,9 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) int size; int hash_added; rcu_read_lock(); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, compare_orig, choose_orig, addr)); rcu_read_unlock(); if (orig_node) { kref_get(&orig_node->refcount); orig_node = orig_hash_find(bat_priv, addr); if (orig_node) return orig_node; } bat_dbg(DBG_BATMAN, bat_priv, "Creating new originator: %pM\n", addr); Loading Loading @@ -245,8 +224,8 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) if (!orig_node->bcast_own_sum) goto free_bcast_own; hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig, orig_node); hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig, orig_node, &orig_node->hash_entry); if (hash_added < 0) goto free_bcast_own_sum; Loading Loading @@ -346,9 +325,8 @@ static bool purge_orig_node(struct bat_priv *bat_priv, static void _purge_orig(struct bat_priv *bat_priv) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk, *safe; struct hlist_node *node, *node_tmp; struct hlist_head *head; struct element_t *bucket; spinlock_t *list_lock; /* spinlock to protect write access */ struct orig_node *orig_node; int i; Loading @@ -364,14 +342,14 @@ static void _purge_orig(struct bat_priv *bat_priv) list_lock = &hash->list_locks[i]; spin_lock_bh(list_lock); hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_safe(orig_node, node, node_tmp, head, hash_entry) { if (purge_orig_node(bat_priv, orig_node)) { if (orig_node->gw_flags) gw_node_delete(bat_priv, orig_node); hlist_del_rcu(walk); call_rcu(&bucket->rcu, bucket_free_orig_rcu); hlist_del_rcu(node); kref_put(&orig_node->refcount, orig_node_free_ref); continue; } Loading Loading @@ -411,9 +389,8 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) struct net_device *net_dev = (struct net_device *)seq->private; struct bat_priv *bat_priv = netdev_priv(net_dev); struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk, *node; struct hlist_node *node, *node_tmp; struct hlist_head *head; struct element_t *bucket; struct orig_node *orig_node; struct neigh_node *neigh_node; int batman_count = 0; Loading Loading @@ -447,9 +424,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) head = &hash->table[i]; rcu_read_lock(); hlist_for_each_entry_rcu(bucket, walk, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { if (!orig_node->router) continue; Loading @@ -468,7 +443,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) neigh_node->addr, neigh_node->if_incoming->net_dev->name); hlist_for_each_entry_rcu(neigh_node, node, hlist_for_each_entry_rcu(neigh_node, node_tmp, &orig_node->neigh_list, list) { seq_printf(seq, " %pM (%3i)", neigh_node->addr, neigh_node->tq_avg); Loading Loading @@ -522,9 +497,8 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) { struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk; struct hlist_node *node; struct hlist_head *head; struct element_t *bucket; struct orig_node *orig_node; int i, ret; Loading @@ -536,9 +510,7 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) head = &hash->table[i]; rcu_read_lock(); hlist_for_each_entry_rcu(bucket, walk, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { spin_lock_bh(&orig_node->ogm_cnt_lock); ret = orig_node_add_if(orig_node, max_if_num); spin_unlock_bh(&orig_node->ogm_cnt_lock); Loading Loading @@ -614,9 +586,8 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) { struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *walk; struct hlist_node *node; struct hlist_head *head; struct element_t *bucket; struct batman_if *batman_if_tmp; struct orig_node *orig_node; int i, ret; Loading @@ -629,9 +600,7 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) head = &hash->table[i]; rcu_read_lock(); hlist_for_each_entry_rcu(bucket, walk, head, hlist) { orig_node = bucket->data; hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { spin_lock_bh(&orig_node->ogm_cnt_lock); ret = orig_node_del_if(orig_node, max_if_num, batman_if->if_num); Loading
net/batman-adv/originator.h +34 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #ifndef _NET_BATMAN_ADV_ORIGINATOR_H_ #define _NET_BATMAN_ADV_ORIGINATOR_H_ #include "hash.h" int originator_init(struct bat_priv *bat_priv); void originator_free(struct bat_priv *bat_priv); void purge_orig_ref(struct bat_priv *bat_priv); Loading @@ -38,8 +40,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num); /* returns 1 if they are the same originator */ static inline int compare_orig(void *data1, void *data2) static inline int compare_orig(struct hlist_node *node, void *data2) { void *data1 = container_of(node, struct orig_node, hash_entry); return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); } Loading @@ -64,4 +68,33 @@ static inline int choose_orig(void *data, int32_t size) return hash % size; } static inline struct orig_node *orig_hash_find(struct bat_priv *bat_priv, void *data) { struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_head *head; struct hlist_node *node; struct orig_node *orig_node, *orig_node_tmp = NULL; int index; if (!hash) return NULL; index = choose_orig(data, hash->size); head = &hash->table[index]; rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { if (!compare_eth(orig_node, data)) continue; orig_node_tmp = orig_node; kref_get(&orig_node_tmp->refcount); break; } rcu_read_unlock(); return orig_node_tmp; } #endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */