]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211: make ieee80211_find_chanctx link-unaware
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Fri, 20 Mar 2026 08:19:59 +0000 (10:19 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 24 Mar 2026 15:30:59 +0000 (16:30 +0100)
Currently we have only one user for a channel context: the link.
With NAN, a new type of the channel context user will be added - the NAN
channel.
To prepare for this, we need to separate the channel context code from
the link code.

Removes the link argument from ieee80211_find_chanctx. Since the issue that led
to commit 5e0c422d12b5 ("wifi: mac80211: reserve chanctx during find") - that
added the link argument - is relevant for any user of the channel context, add
a boolean to the chanctx itself, indicating that the chanctx is in the process
of getting used.

When this indication is set, the reference count of the channel context
will be incremented by one, so even if it is getting released from a link
(or another user) it won't be freed.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260320101954.232499e2a41f.I0b735a607e1ec7aa5749ab01c794ef99dbe82b7f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/chan.c
net/mac80211/ieee80211_i.h

index b7604118bf578dd5f634f507ab2b6e3d9645dcfb..1bcf501cfe8e9d3dd68ebf98fd09c51d0bdc4c04 100644 (file)
@@ -166,6 +166,13 @@ int ieee80211_chanctx_refcount(struct ieee80211_local *local,
        for_each_chanctx_user_all(local, ctx, &iter)
                num++;
 
+       /*
+        * This ctx is in the process of getting used,
+        * take it into consideration
+        */
+       if (ctx->will_be_used)
+               num++;
+
        return num;
 }
 
@@ -769,10 +776,9 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
        _ieee80211_change_chanctx(local, ctx, old_ctx, chanreq, NULL);
 }
 
-/* Note: if successful, the returned chanctx is reserved for the link */
+/* Note: if successful, the returned chanctx will_be_used flag is set */
 static struct ieee80211_chanctx *
 ieee80211_find_chanctx(struct ieee80211_local *local,
-                      struct ieee80211_link_data *link,
                       const struct ieee80211_chan_req *chanreq,
                       enum ieee80211_chanctx_mode mode)
 {
@@ -784,9 +790,6 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
        if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
                return NULL;
 
-       if (WARN_ON(link->reserved_chanctx))
-               return NULL;
-
        list_for_each_entry(ctx, &local->chanctx_list, list) {
                const struct ieee80211_chan_req *compat;
 
@@ -807,12 +810,12 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
                        continue;
 
                /*
-                * Reserve the chanctx temporarily, as the driver might change
+                * Mark the chanctx as will be used, as the driver might change
                 * active links during callbacks we make into it below and/or
                 * later during assignment, which could (otherwise) cause the
                 * context to actually be removed.
                 */
-               link->reserved_chanctx = ctx;
+               ctx->will_be_used = true;
 
                ieee80211_change_chanctx(local, ctx, ctx, compat);
 
@@ -2066,8 +2069,8 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link,
        if (!local->in_reconfig)
                __ieee80211_link_release_channel(link, false);
 
-       ctx = ieee80211_find_chanctx(local, link, chanreq, mode);
-       /* Note: context is now reserved */
+       ctx = ieee80211_find_chanctx(local, chanreq, mode);
+       /* Note: context will_be_used flag is now set */
        if (ctx)
                reserved = true;
        else if (!ieee80211_find_available_radio(local, chanreq,
@@ -2087,9 +2090,8 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link,
        ret = ieee80211_assign_link_chanctx(link, ctx, assign_on_failure);
 
        if (reserved) {
-               /* remove reservation */
-               WARN_ON(link->reserved_chanctx != ctx);
-               link->reserved_chanctx = NULL;
+               WARN_ON(!ctx->will_be_used);
+               ctx->will_be_used = false;
        }
 
        if (ret) {
index d71e0c6d21659165b5bb176bfbf07debe88308c8..fe53812eca95c6ba1cbd7ec6d65898d4891f71c1 100644 (file)
@@ -928,6 +928,9 @@ struct ieee80211_chanctx {
 
        bool radar_detected;
 
+       /* This chanctx is in process of getting used */
+       bool will_be_used;
+
        /* MUST be last - ends in a flexible-array member. */
        struct ieee80211_chanctx_conf conf;
 };