diff mbox

[v2,07/13] mac80211: improve find_chanctx() for reservations

Message ID 1395409651-26120-8-git-send-email-michal.kazior@tieto.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Michal Kazior March 21, 2014, 1:47 p.m. UTC
Relax ieee80211_find_chanctx(). If chanctx
reservation chandef is compatible with
current-future assigned interfaces chandef then
allow it to be used by new interfaces.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
 net/mac80211/chan.c | 56 +++++++++++++++++++++++++++--------------------------
 1 file changed, 29 insertions(+), 27 deletions(-)

Comments

Johannes Berg March 28, 2014, 1:08 p.m. UTC | #1
On Fri, 2014-03-21 at 14:47 +0100, Michal Kazior wrote:
> Relax ieee80211_find_chanctx(). If chanctx
> reservation chandef is compatible with
> current-future assigned interfaces chandef then
> allow it to be used by new interfaces.

Err, I don't understand. Could you elaborate?

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michal Kazior March 28, 2014, 1:32 p.m. UTC | #2
On 28 March 2014 14:08, Johannes Berg <johannes@sipsolutions.net> wrote:
> On Fri, 2014-03-21 at 14:47 +0100, Michal Kazior wrote:
>> Relax ieee80211_find_chanctx(). If chanctx
>> reservation chandef is compatible with
>> current-future assigned interfaces chandef then
>> allow it to be used by new interfaces.
>
> Err, I don't understand. Could you elaborate?

Yeah. Me too. Apparently I fail at English.

Basically this allows new vifs to be assigned to a chanctx as long as
chanctx's reservation chandefs *and* chanctx's current chandef
(implied by assigned vifs, if any) *and* the new vif chandef are
compatible. chanctx being used for in-place reservation with
conflicting channels are skipped. This also it makes it possible to
assign a vif to a chanctx that has been created for reservation only
(that hasn't been finalized yet) and has no vifs assigned whatsoever.


Micha?
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 99df19c..1361788 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -28,6 +28,29 @@  static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local)
 	return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local);
 }
 
+static const struct cfg80211_chan_def *
+ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local,
+				   struct ieee80211_chanctx *ctx,
+				   const struct cfg80211_chan_def *compat)
+{
+	struct ieee80211_sub_if_data *sdata;
+
+	lockdep_assert_held(&local->chanctx_mtx);
+
+	list_for_each_entry(sdata, &ctx->reserved_vifs,
+			    reserved_chanctx_list) {
+		if (!compat)
+			compat = &sdata->reserved_chandef;
+
+		compat = cfg80211_chandef_compatible(&sdata->reserved_chandef,
+						     compat);
+		if (!compat)
+			break;
+	}
+
+	return compat;
+}
+
 static enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta)
 {
 	switch (sta->bandwidth) {
@@ -181,27 +204,6 @@  static void ieee80211_change_chanctx(struct ieee80211_local *local,
 	}
 }
 
-static bool ieee80211_chanctx_is_reserved(struct ieee80211_local *local,
-					  struct ieee80211_chanctx *ctx)
-{
-	struct ieee80211_sub_if_data *sdata;
-	bool ret = false;
-
-	lockdep_assert_held(&local->chanctx_mtx);
-	rcu_read_lock();
-	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-		if (!ieee80211_sdata_running(sdata))
-			continue;
-		if (sdata->reserved_chanctx == ctx) {
-			ret = true;
-			break;
-		}
-	}
-
-	rcu_read_unlock();
-	return ret;
-}
-
 static struct ieee80211_chanctx *
 ieee80211_find_chanctx(struct ieee80211_local *local,
 		       const struct cfg80211_chan_def *chandef,
@@ -217,18 +219,18 @@  ieee80211_find_chanctx(struct ieee80211_local *local,
 	list_for_each_entry(ctx, &local->chanctx_list, list) {
 		const struct cfg80211_chan_def *compat;
 
-		/* We don't support chanctx reservation for multiple
-		 * vifs yet, so don't allow reserved chanctxs to be
-		 * reused.
-		 */
-		if ((ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) ||
-		    ieee80211_chanctx_is_reserved(local, ctx))
+		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
 			continue;
 
 		compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef);
 		if (!compat)
 			continue;
 
+		compat = ieee80211_chanctx_reserved_chandef(local, ctx,
+							    compat);
+		if (!compat)
+			continue;
+
 		ieee80211_change_chanctx(local, ctx, compat);
 
 		return ctx;