mac80211: mesh: convert path table to rhashtable

In the time since the mesh path table was implemented as an
RCU-traversable, dynamically growing hash table, a generic RCU
hashtable implementation was added to the kernel.

Switch the mesh path table over to rhashtable to remove some code
and also gain some features like automatic shrinking.

Cc: Thomas Graf <tgraf@suug.ch>
Cc: netdev@vger.kernel.org
Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Bob Copeland 2016-03-02 10:09:20 -05:00 committed by Johannes Berg
parent 8f6fd83c6c
commit 60854fd945
4 changed files with 265 additions and 581 deletions

View File

@ -697,17 +697,10 @@ struct ieee80211_if_mesh {
/* offset from skb->data while building IE */ /* offset from skb->data while building IE */
int meshconf_offset; int meshconf_offset;
struct mesh_table __rcu *mesh_paths; struct mesh_table *mesh_paths;
struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */
int mesh_paths_generation; int mesh_paths_generation;
int mpp_paths_generation; int mpp_paths_generation;
/* Protects assignment of the mesh_paths/mpp_paths table
* pointer for resize against reading it for add/delete
* of individual paths. Pure readers (lookups) just use
* RCU.
*/
rwlock_t pathtbl_resize_lock;
}; };
#ifdef CONFIG_MAC80211_MESH #ifdef CONFIG_MAC80211_MESH

View File

@ -1347,12 +1347,6 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval)))
mesh_path_start_discovery(sdata); mesh_path_start_discovery(sdata);
if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags))
mesh_mpath_table_grow(sdata);
if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags))
mesh_mpp_table_grow(sdata);
if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
ieee80211_mesh_housekeeping(sdata); ieee80211_mesh_housekeeping(sdata);

View File

@ -51,10 +51,6 @@ enum mesh_path_flags {
* *
* *
* @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks * @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks
* @MESH_WORK_GROW_MPATH_TABLE: the mesh path table is full and needs
* to grow.
* @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
* grow
* @MESH_WORK_ROOT: the mesh root station needs to send a frame * @MESH_WORK_ROOT: the mesh root station needs to send a frame
* @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other
* mesh nodes * mesh nodes
@ -62,8 +58,6 @@ enum mesh_path_flags {
*/ */
enum mesh_deferred_task_flags { enum mesh_deferred_task_flags {
MESH_WORK_HOUSEKEEPING, MESH_WORK_HOUSEKEEPING,
MESH_WORK_GROW_MPATH_TABLE,
MESH_WORK_GROW_MPP_TABLE,
MESH_WORK_ROOT, MESH_WORK_ROOT,
MESH_WORK_DRIFT_ADJUST, MESH_WORK_DRIFT_ADJUST,
MESH_WORK_MBSS_CHANGED, MESH_WORK_MBSS_CHANGED,
@ -105,6 +99,7 @@ enum mesh_deferred_task_flags {
struct mesh_path { struct mesh_path {
u8 dst[ETH_ALEN]; u8 dst[ETH_ALEN];
u8 mpp[ETH_ALEN]; /* used for MPP or MAP */ u8 mpp[ETH_ALEN]; /* used for MPP or MAP */
struct rhash_head rhash;
struct hlist_node gate_list; struct hlist_node gate_list;
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
struct sta_info __rcu *next_hop; struct sta_info __rcu *next_hop;
@ -129,34 +124,17 @@ struct mesh_path {
/** /**
* struct mesh_table * struct mesh_table
* *
* @hash_buckets: array of hash buckets of the table
* @hashwlock: array of locks to protect write operations, one per bucket
* @hash_mask: 2^size_order - 1, used to compute hash idx
* @hash_rnd: random value used for hash computations
* @entries: number of entries in the table * @entries: number of entries in the table
* @free_node: function to free nodes of the table
* @copy_node: function to copy nodes of the table
* @size_order: determines size of the table, there will be 2^size_order hash
* buckets
* @known_gates: list of known mesh gates and their mpaths by the station. The * @known_gates: list of known mesh gates and their mpaths by the station. The
* gate's mpath may or may not be resolved and active. * gate's mpath may or may not be resolved and active.
* * @rhash: the rhashtable containing struct mesh_paths, keyed by dest addr
* rcu_head: RCU head to free the table
*/ */
struct mesh_table { struct mesh_table {
/* Number of buckets will be 2^N */
struct hlist_head *hash_buckets;
spinlock_t *hashwlock; /* One per bucket, for add/del */
unsigned int hash_mask; /* (2^size_order) - 1 */
__u32 hash_rnd; /* Used for hash generation */
atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */
void (*free_node) (struct hlist_node *p, bool free_leafs);
int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
int size_order;
struct hlist_head *known_gates; struct hlist_head *known_gates;
spinlock_t gates_lock; spinlock_t gates_lock;
struct rcu_head rcu_head; struct rhashtable rhead;
}; };
/* Recent multicast cache */ /* Recent multicast cache */
@ -300,9 +278,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
void mesh_sta_cleanup(struct sta_info *sta); void mesh_sta_cleanup(struct sta_info *sta);
/* Private interfaces */ /* Private interfaces */
/* Mesh tables */
void mesh_mpath_table_grow(struct ieee80211_sub_if_data *sdata);
void mesh_mpp_table_grow(struct ieee80211_sub_if_data *sdata);
/* Mesh paths */ /* Mesh paths */
int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
u8 ttl, const u8 *target, u32 target_sn, u8 ttl, const u8 *target, u32 target_sn,

File diff suppressed because it is too large Load Diff