Commit 2bdaf386 authored by Bob Copeland's avatar Bob Copeland Committed by Johannes Berg

mac80211: mesh: move path tables into if_mesh

The mesh path and mesh gate hashtables are global, containing
all of the mpaths for every mesh interface, but the paths are
all tied logically to a single interface.  The common case is
just a single mesh interface, so optimize for that by moving
the global hashtable into the per-interface struct.

Doing so allows us to drop sdata pointer comparisons inside
the lookups and also saves a few bytes of BSS and data.
Signed-off-by: default avatarBob Copeland <me@bobcopeland.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 12880d16
...@@ -1499,7 +1499,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, ...@@ -1499,7 +1499,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
memset(pinfo, 0, sizeof(*pinfo)); memset(pinfo, 0, sizeof(*pinfo));
pinfo->generation = mesh_paths_generation; pinfo->generation = mpath->sdata->u.mesh.mesh_paths_generation;
pinfo->filled = MPATH_INFO_FRAME_QLEN | pinfo->filled = MPATH_INFO_FRAME_QLEN |
MPATH_INFO_SN | MPATH_INFO_SN |
...@@ -1577,7 +1577,7 @@ static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp, ...@@ -1577,7 +1577,7 @@ static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp,
memset(pinfo, 0, sizeof(*pinfo)); memset(pinfo, 0, sizeof(*pinfo));
memcpy(mpp, mpath->mpp, ETH_ALEN); memcpy(mpp, mpath->mpp, ETH_ALEN);
pinfo->generation = mpp_paths_generation; pinfo->generation = mpath->sdata->u.mesh.mpp_paths_generation;
} }
static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev,
......
...@@ -696,6 +696,18 @@ struct ieee80211_if_mesh { ...@@ -696,6 +696,18 @@ 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 __rcu *mpp_paths; /* Store paths for MPP&MAP */
int mesh_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
......
...@@ -25,7 +25,6 @@ bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt) ...@@ -25,7 +25,6 @@ bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
void ieee80211s_init(void) void ieee80211s_init(void)
{ {
mesh_pathtbl_init();
mesh_allocated = 1; mesh_allocated = 1;
rm_cache = kmem_cache_create("mesh_rmc", sizeof(struct rmc_entry), rm_cache = kmem_cache_create("mesh_rmc", sizeof(struct rmc_entry),
0, 0, NULL); 0, 0, NULL);
...@@ -35,7 +34,6 @@ void ieee80211s_stop(void) ...@@ -35,7 +34,6 @@ void ieee80211s_stop(void)
{ {
if (!mesh_allocated) if (!mesh_allocated)
return; return;
mesh_pathtbl_unregister();
kmem_cache_destroy(rm_cache); kmem_cache_destroy(rm_cache);
} }
...@@ -902,6 +900,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) ...@@ -902,6 +900,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
/* flush STAs and mpaths on this iface */ /* flush STAs and mpaths on this iface */
sta_info_flush(sdata); sta_info_flush(sdata);
mesh_path_flush_by_iface(sdata); mesh_path_flush_by_iface(sdata);
mesh_pathtbl_unregister(sdata);
/* free all potentially still buffered group-addressed frames */ /* free all potentially still buffered group-addressed frames */
local->total_ps_buffered -= skb_queue_len(&ifmsh->ps.bc_buf); local->total_ps_buffered -= skb_queue_len(&ifmsh->ps.bc_buf);
...@@ -1349,10 +1348,10 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) ...@@ -1349,10 +1348,10 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
mesh_path_start_discovery(sdata); mesh_path_start_discovery(sdata);
if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags)) if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags))
mesh_mpath_table_grow(); mesh_mpath_table_grow(sdata);
if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags)) if (test_and_clear_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags))
mesh_mpp_table_grow(); 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);
...@@ -1388,6 +1387,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) ...@@ -1388,6 +1387,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
/* Allocate all mesh structures when creating the first mesh interface. */ /* Allocate all mesh structures when creating the first mesh interface. */
if (!mesh_allocated) if (!mesh_allocated)
ieee80211s_init(); ieee80211s_init();
mesh_pathtbl_init(sdata);
setup_timer(&ifmsh->mesh_path_timer, setup_timer(&ifmsh->mesh_path_timer,
ieee80211_mesh_path_timer, ieee80211_mesh_path_timer,
(unsigned long) sdata); (unsigned long) sdata);
......
...@@ -300,8 +300,8 @@ void mesh_sta_cleanup(struct sta_info *sta); ...@@ -300,8 +300,8 @@ void mesh_sta_cleanup(struct sta_info *sta);
/* Private interfaces */ /* Private interfaces */
/* Mesh tables */ /* Mesh tables */
void mesh_mpath_table_grow(void); void mesh_mpath_table_grow(struct ieee80211_sub_if_data *sdata);
void mesh_mpp_table_grow(void); 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,
...@@ -309,8 +309,8 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, ...@@ -309,8 +309,8 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
void mesh_path_flush_pending(struct mesh_path *mpath); void mesh_path_flush_pending(struct mesh_path *mpath);
void mesh_path_tx_pending(struct mesh_path *mpath); void mesh_path_tx_pending(struct mesh_path *mpath);
int mesh_pathtbl_init(void); int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata);
void mesh_pathtbl_unregister(void); void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata);
int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr); int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr);
void mesh_path_timer(unsigned long data); void mesh_path_timer(unsigned long data);
void mesh_path_flush_by_nexthop(struct sta_info *sta); void mesh_path_flush_by_nexthop(struct sta_info *sta);
...@@ -319,8 +319,6 @@ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, ...@@ -319,8 +319,6 @@ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
extern int mesh_paths_generation;
extern int mpp_paths_generation;
#ifdef CONFIG_MAC80211_MESH #ifdef CONFIG_MAC80211_MESH
static inline static inline
......
This diff is collapsed.
...@@ -2212,7 +2212,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, ...@@ -2212,7 +2212,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
} }
if (mppath && mpath) if (mppath && mpath)
mesh_path_del(mpath->sdata, mpath->dst); mesh_path_del(sdata, mpath->dst);
} }
/* /*
......
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