Commit 7683fdc1 authored by Antonio Quartulli's avatar Antonio Quartulli Committed by Sven Eckelmann

batman-adv: protect the local and the global trans-tables with rcu

The local and the global translation-tables are now lock free and rcu
protected.
Signed-off-by: default avatarAntonio Quartulli <ordex@autistici.org>
Acked-by: default avatarSimon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: default avatarSven Eckelmann <sven@narfation.org>
parent cc47f66e
...@@ -84,8 +84,6 @@ int mesh_init(struct net_device *soft_iface) ...@@ -84,8 +84,6 @@ int mesh_init(struct net_device *soft_iface)
spin_lock_init(&bat_priv->forw_bat_list_lock); spin_lock_init(&bat_priv->forw_bat_list_lock);
spin_lock_init(&bat_priv->forw_bcast_list_lock); spin_lock_init(&bat_priv->forw_bcast_list_lock);
spin_lock_init(&bat_priv->tt_lhash_lock);
spin_lock_init(&bat_priv->tt_ghash_lock);
spin_lock_init(&bat_priv->tt_changes_list_lock); spin_lock_init(&bat_priv->tt_changes_list_lock);
spin_lock_init(&bat_priv->tt_req_list_lock); spin_lock_init(&bat_priv->tt_req_list_lock);
spin_lock_init(&bat_priv->tt_roam_list_lock); spin_lock_init(&bat_priv->tt_roam_list_lock);
......
...@@ -90,9 +90,7 @@ static void update_transtable(struct bat_priv *bat_priv, ...@@ -90,9 +90,7 @@ static void update_transtable(struct bat_priv *bat_priv,
/* Even if we received the crc into the OGM, we prefer /* Even if we received the crc into the OGM, we prefer
* to recompute it to spot any possible inconsistency * to recompute it to spot any possible inconsistency
* in the global table */ * in the global table */
spin_lock_bh(&bat_priv->tt_ghash_lock);
orig_node->tt_crc = tt_global_crc(bat_priv, orig_node); orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
spin_unlock_bh(&bat_priv->tt_ghash_lock);
/* Roaming phase is over: tables are in sync again. I can /* Roaming phase is over: tables are in sync again. I can
* unset the flag */ * unset the flag */
orig_node->tt_poss_change = false; orig_node->tt_poss_change = false;
......
This diff is collapsed.
...@@ -184,8 +184,6 @@ struct bat_priv { ...@@ -184,8 +184,6 @@ struct bat_priv {
spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
spinlock_t forw_bcast_list_lock; /* protects */ spinlock_t forw_bcast_list_lock; /* protects */
spinlock_t tt_changes_list_lock; /* protects tt_changes */ spinlock_t tt_changes_list_lock; /* protects tt_changes */
spinlock_t tt_lhash_lock; /* protects tt_local_hash */
spinlock_t tt_ghash_lock; /* protects tt_global_hash */
spinlock_t tt_req_list_lock; /* protects tt_req_list */ spinlock_t tt_req_list_lock; /* protects tt_req_list */
spinlock_t tt_roam_list_lock; /* protects tt_roam_list */ spinlock_t tt_roam_list_lock; /* protects tt_roam_list */
spinlock_t gw_list_lock; /* protects gw_list and curr_gw */ spinlock_t gw_list_lock; /* protects gw_list and curr_gw */
...@@ -226,6 +224,8 @@ struct tt_local_entry { ...@@ -226,6 +224,8 @@ struct tt_local_entry {
uint8_t addr[ETH_ALEN]; uint8_t addr[ETH_ALEN];
unsigned long last_seen; unsigned long last_seen;
char never_purge; char never_purge;
atomic_t refcount;
struct rcu_head rcu;
struct hlist_node hash_entry; struct hlist_node hash_entry;
}; };
...@@ -235,6 +235,8 @@ struct tt_global_entry { ...@@ -235,6 +235,8 @@ struct tt_global_entry {
uint8_t ttvn; uint8_t ttvn;
uint8_t flags; /* only TT_GLOBAL_ROAM is used */ uint8_t flags; /* only TT_GLOBAL_ROAM is used */
unsigned long roam_at; /* time at which TT_GLOBAL_ROAM was set */ unsigned long roam_at; /* time at which TT_GLOBAL_ROAM was set */
atomic_t refcount;
struct rcu_head rcu;
struct hlist_node hash_entry; /* entry in the global table */ struct hlist_node hash_entry; /* entry in the global table */
}; };
......
...@@ -665,11 +665,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv) ...@@ -665,11 +665,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
hash = bat_priv->tt_local_hash; hash = bat_priv->tt_local_hash;
spin_lock_bh(&bat_priv->tt_lhash_lock);
for (i = 0; i < hash->size; i++) { for (i = 0; i < hash->size; i++) {
head = &hash->table[i]; head = &hash->table[i];
hlist_for_each_entry(tt_local_entry, node, head, hash_entry) { rcu_read_lock();
hlist_for_each_entry_rcu(tt_local_entry, node, head,
hash_entry) {
entry = (struct vis_info_entry *) entry = (struct vis_info_entry *)
skb_put(info->skb_packet, skb_put(info->skb_packet,
sizeof(*entry)); sizeof(*entry));
...@@ -678,14 +679,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv) ...@@ -678,14 +679,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
entry->quality = 0; /* 0 means TT */ entry->quality = 0; /* 0 means TT */
packet->entries++; packet->entries++;
if (vis_packet_full(info)) { if (vis_packet_full(info))
spin_unlock_bh(&bat_priv->tt_lhash_lock); goto unlock;
return 0;
}
} }
rcu_read_unlock();
} }
spin_unlock_bh(&bat_priv->tt_lhash_lock);
return 0; return 0;
unlock: unlock:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment