Files
besser/danctnix-besser-pkgbuild/kernel/0017-bes2600-Patch-C2-replace-ieee80211_rx_irqsafe-with-i.patch
claude-noether fd0f5a8b71 danctnix-besser: replace cumulative patch with per-series (pkgrel=4)
Replace the single squashed 0001-bes2600-besser-cumulative-series.patch
with 20 individual per-commit patches matching the bes2600/besser-danctnix-v3
branch in marfrit/bes2600-dkms.  Also remove the duplicate 0003-arm64 entry
that was a bug in pkgrel=3.

Patch list:
  0001 c5.1   defer scan and soften WARN on firmware reject
  0002 c5.1.1 widen scan-defer backoff to 30s and decay reject_count
  0003 c5.2   recover wedged firmware via mmc_hw_reset on link break
  0004 c6.1   gate PM indication completion on pending request
  0005 c6.2   short-circuit wake handshake when chip confirmed ACTIVE
  0006 c7     self-detect when firmware does not honor PSM and skip
  0007 c5.2.1 handle multi-function SDIO cards in mmc_hw_reset
  0008 Patch A pre-empt AP-deauth-6 with reassoc on decrypt-fail storm
  0009 Patch B bus_reset on connection-loss storm
  0010 Patch F3 atomicize atomic_add() calls
  0011 Patch F2 fix missing destroy_workqueue() on error in init_common
  0012 Patch F1 fix concurrency UAF in bes2600_hw_scan / sched_scan
  0013 Patch C v3 drop sdio_rx_work relay, IRQ→bh-direct
  0014 Patch G restore SPDX identifiers + ST-Ericsson attribution
  0015 Patch D atomicize ba_lock counters, drop the spinlock
  0016 Patch E skip ps_state_lock when PSM-known-disabled
  0017 Patch C2 replace ieee80211_rx_irqsafe with ieee80211_rx_ni
  0018 Patch H bh.c hygiene cleanup (drop fossil blocks, dead stubs)
  0019 besser#18 pending_record_lock SOFTIRQ-safe fix
  0020 danctnix-flavor: export bus_reset helpers for bes2600_btuart

Build pending (pkgrel=4 makepkg in progress on boltzmann).

Signed-off-by: Claude (noether) <claude@reauktion.de>
2026-05-20 20:37:30 +02:00

158 lines
6.6 KiB
Diff

From 447240cbe8dee9d865683508f7d814e7ffe1d970 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <fritsche.markus@gmail.com>
Date: Fri, 8 May 2026 06:40:00 +0200
Subject: [PATCH 17/20] =?UTF-8?q?bes2600:=20Patch=20C2=20=E2=80=94=20repla?=
=?UTF-8?q?ce=20ieee80211=5Frx=5Firqsafe=20with=20ieee80211=5Frx=5Fni?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per Phase 4 plan PR #14 + kerneldoc audit (Task #19). Six call sites
deferred per-RX-frame mac80211 dispatch via tasklet; replace with the
synchronous-from-process-context API ieee80211_rx_ni() which does its
own local_bh_disable wrap.
Why _ni and not _list:
Phase 4 plan originally targeted ieee80211_rx_list for batch
delivery. Mining mt76 mainline (the only driver using _list)
showed the canonical pattern requires threading a struct list_head
through the per-frame call chain. bes2600s WSM dispatcher
(wsm_handle_rx -> bes2600_rx_cb / wsm.c beacon path) sits between
the bh threads SDIO read and the mac80211 hand-off; threading a
list_head through the dispatcher is a non-trivial refactor.
ieee80211_rx_ni() is the simpler drop-in: no list management, still
removes the tasklet hop. Per-call local_bh_disable cost is trivial
vs the saved tasklet schedule. Future refactor can revisit _list
if measurements warrant.
Sites converted:
- ap.c:96 (bes2600_sta_add link-id rx_queue drain on AP-mode
STA add). Was inside spin_lock_bh(&ps_state_lock);
refactored to splice the queue under the lock then
deliver after unlock — _ni runs the synchronous
mac80211 RX path inline, would otherwise hold the
lock across mac80211 dispatch. splice via
skb_queue_splice_init into a local sk_buff_head.
- sta.c:1487 (deauth-frame inject in inactivity-event handler).
Not under any lock; direct conversion.
- txrx.c:1960 (early-data + pm_unsupported branch from Patch E).
- txrx.c:1967 (early-data + LINK_SOFT-not-set branch).
- txrx.c:1971 (normal RX path in bes2600_rx_cb).
- wsm.c:2415 (beacon delivery in scan-complete WSM handler).
beacon SKB ownership is preserved by the existing
skb_copy(beacon, GFP_ATOMIC) -> beacon_bkp pattern;
no lifecycle change needed.
Mixing constraint (kerneldoc include/net/mac80211.h:5399-5430):
ieee80211_rx_ni() cannot mix with ieee80211_rx_irqsafe() for a
single hardware. All 6 sites convert atomically; no mixed state.
Build verified clean on ohm sandbox: srcversion 619A51E61BF5479AAC146E6.
Predicted Phase 7 delta: +5-15% over v3+D+E baseline (2.35 MB/s mean
on v3 alone; D+E single-rep was 3.22 MB/s). Modest improvement
expected from removing the tasklet schedule per RX frame. Smaller
deltas would still be a net win for upstream-cleanliness — the
kernel.org submission story benefits from not using _irqsafe from
process context.
---
bes2600/ap.c | 15 +++++++++++++--
bes2600/sta.c | 2 +-
bes2600/txrx.c | 6 +++---
bes2600/wsm.c | 2 +-
4 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/bes2600/ap.c b/drivers/staging/bes2600/ap.c
index 8a17545..99e2da2 100644
--- a/drivers/staging/bes2600/ap.c
+++ b/drivers/staging/bes2600/ap.c
@@ -63,8 +63,11 @@ int bes2600_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct bes2600_vif *priv = cw12xx_get_vif_from_ieee80211(vif);
struct bes2600_link_entry *entry;
struct sk_buff *skb;
+ struct sk_buff_head local_drain;
struct bes2600_common *hw_priv = hw->priv;
+ __skb_queue_head_init(&local_drain);
+
#ifdef P2P_MULTIVIF
WARN_ON(priv->if_id == CW12XX_GENERIC_IF_ID);
#endif
@@ -93,9 +96,17 @@ int bes2600_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
priv->sta_asleep_mask |= BIT(sta_priv->link_id);
entry->status = BES2600_LINK_HARD;
- while ((skb = skb_dequeue(&entry->rx_queue)))
- ieee80211_rx_irqsafe(priv->hw, skb);
+ /*
+ * Patch C2: splice the rx_queue out under the lock then deliver
+ * after unlock. ieee80211_rx_ni() runs the mac80211 RX path
+ * synchronously (formerly ieee80211_rx_irqsafe deferred to a
+ * tasklet); calling it from inside spin_lock_bh would hold the
+ * lock across mac80211's full RX dispatch.
+ */
+ skb_queue_splice_init(&entry->rx_queue, &local_drain);
spin_unlock_bh(&priv->ps_state_lock);
+ while ((skb = __skb_dequeue(&local_drain)))
+ ieee80211_rx_ni(priv->hw, skb);
#ifdef AP_AGGREGATE_FW_FIX
hw_priv->connected_sta_cnt++;
if(hw_priv->connected_sta_cnt>1) {
diff --git a/drivers/staging/bes2600/sta.c b/drivers/staging/bes2600/sta.c
index 412b2c4..476d875 100644
--- a/drivers/staging/bes2600/sta.c
+++ b/drivers/staging/bes2600/sta.c
@@ -1500,7 +1500,7 @@ void bes2600_event_handler(struct work_struct *work)
IEEE80211_STYPE_DEAUTH | IEEE80211_FCTL_TODS);
deauth->u.deauth.reason_code = WLAN_REASON_DEAUTH_LEAVING;
deauth->seq_ctrl = 0;
- ieee80211_rx_irqsafe(priv->hw, skb);
+ ieee80211_rx_ni(priv->hw, skb);
bes_devel(" Inactivity Deauth Frame sent for MAC SA %pM \t and DA %pM\n", deauth->sa, deauth->da);
queue_work(priv->hw_priv->workqueue, &priv->set_tim_work);
break;
diff --git a/drivers/staging/bes2600/txrx.c b/drivers/staging/bes2600/txrx.c
index cb718ad..9074972 100644
--- a/drivers/staging/bes2600/txrx.c
+++ b/drivers/staging/bes2600/txrx.c
@@ -1980,18 +1980,18 @@ void bes2600_rx_cb(struct bes2600_vif *priv,
* path is taken.
*/
if (hw_priv->bes_power.pm_unsupported) {
- ieee80211_rx_irqsafe(priv->hw, skb);
+ ieee80211_rx_ni(priv->hw, skb);
} else {
spin_lock_bh(&priv->ps_state_lock);
/* Double-check status with lock held */
if (entry->status == BES2600_LINK_SOFT)
skb_queue_tail(&entry->rx_queue, skb);
else
- ieee80211_rx_irqsafe(priv->hw, skb);
+ ieee80211_rx_ni(priv->hw, skb);
spin_unlock_bh(&priv->ps_state_lock);
}
} else {
- ieee80211_rx_irqsafe(priv->hw, skb);
+ ieee80211_rx_ni(priv->hw, skb);
}
*skb_p = NULL;
diff --git a/drivers/staging/bes2600/wsm.c b/drivers/staging/bes2600/wsm.c
index 908c965..2424181 100644
--- a/drivers/staging/bes2600/wsm.c
+++ b/drivers/staging/bes2600/wsm.c
@@ -2412,7 +2412,7 @@ int wsm_handle_rx(struct bes2600_common *hw_priv, int id,
if (!hw_priv->beacon_bkp)
hw_priv->beacon_bkp = \
skb_copy(hw_priv->beacon, GFP_ATOMIC);
- ieee80211_rx_irqsafe(hw_priv->hw, hw_priv->beacon);
+ ieee80211_rx_ni(hw_priv->hw, hw_priv->beacon);
hw_priv->beacon = hw_priv->beacon_bkp;
hw_priv->beacon_bkp = NULL;
--
2.54.0