Files
bes2600-dkms/bes2600/bh.h
T
test0r c4797b1dbf bes2600: deliver RX SKBs directly into wsm_handle_rx from sdio_rx_work
Patch C — collapse the sdio_rx_work → rx_queue → bh_work relay into a
direct call from bes2600_sdio_extract_packets into a new helper
bes2600_bh_handle_rx_skb that performs the per-SKB bookkeeping
previously done inside bes2600_bh_rx_helper after pipe_read.

What this saves per RX frame:
  - two spinlock acquires on self->rx_queue->lock
    (skb_queue_tail in extract_packets + skb_dequeue in pipe_read)
  - one bh wait-queue wake-up per IRQ batch
    (sdio_rx_work no longer calls self->irq_handler)

Pre-patch baseline on ohm (4 MB/s sender, ~5 min, srcversion 1B3B3ED0):
  - 387,532 RX packets, 578 MB, 1.36 MB/s observed receive
  - sdio_rx_work dispatched 34,994 times = 86.4/s = 90.3 per 1000 RX pkts
  - sdio_tx_work dispatched 111,770 times = 276.1/s
  - bes2600_bh_work redispatches: 0  (single long-lived work item,
    refutes earlier review claim of "9 events per frame")

API contract for wsm_handle_rx (cited in bh.c block comment):
  - declared wsm.h:2108, defined wsm.c:2211, EXPORT_SYMBOL wsm.c:2463
  - process context, sleepable
  - caller MUST hold no bes2600 spinlock; SDIO mutex is released at
    bes2600_sdio.c before extract_packets is called
  - SKB ownership: zeroes *skb_p if consumed, caller frees otherwise.
    bes2600_bh_handle_rx_skb frees on every path (success + error)

After patch, bh thread retains responsibility for TX work.  TX-confirm
packets that release a TX buffer wake the bh thread via
bes2600_bh_wakeup() inside bes2600_bh_handle_rx_skb (mirrors the in-bh
tx=1 signaling the old bh_rx_helper used to do).  Early-boot IRQs
before fw_started are still served via the GPIO IRQ handler's fallback
self->irq_handler path; that branch is unchanged.

Minimum-diff scope:
  - struct sbus_priv->rx_queue + ->rx_queue_lock are still defined and
    initialised (allocated but never used after this patch).  Removed
    in a follow-up hygiene patch, not bundled here.
  - bes2600_sdio_pipe_read still exists; returns NULL after this patch
    (rx_queue always empty).  Removed in same follow-up.
  - bes2600_bh_rx_helper still exists and still calls pipe_read; it
    now always returns 0.  Wasted 1 spinlock + skb_dequeue per bh wake;
    quantified in Phase 7 to decide whether worth a follow-up.

Awaiting Phase 7 verification on ohm.  Per Phase 4 plan §4.5 predicted
delta:
  - rx_queue->lock acquire rate: 1914/s -> 0  (high confidence)
  - _raw_spin_unlock_irqrestore CPU%: 20% -> 12-15%  (medium)
  - observed RX KB/s @ 4 MB/s: floor lifts toward >= 1 MB/s sustained
    (medium; rep 3's 75 KB/s death has multiple causes)

Phase 7 will N=3 ramp 1 -> 2 -> 4 -> 8 MB/s with identical
instrumentation pre/post.  See notes/patch-c-phase4-plan-2026-05-07.md
in marfrit/besser for the plan; this commit is the Phase 6 deliverable.
2026-05-07 19:49:57 +02:00

56 lines
1.8 KiB
C

/*
* Device handling thread interface for mac80211 BES2600 drivers
*
* Copyright (c) 2010, Bestechnic
* Author:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef BES2600_BH_H
#define BES2600_BH_H
#include <linux/version.h>
/* extern */ struct bes2600_common;
#define SDIO_BLOCK_SIZE (528)
#define KEY_FRAME_SW_RETRY
#ifdef KEY_FRAME_SW_RETRY
#define CW1200_MAX_SW_RETRY_CNT (2)
#endif
int bes2600_register_bh(struct bes2600_common *hw_priv);
void bes2600_unregister_bh(struct bes2600_common *hw_priv);
void bes2600_irq_handler(struct bes2600_common *hw_priv);
void bes2600_bh_wakeup(struct bes2600_common *hw_priv);
int bes2600_bh_suspend(struct bes2600_common *hw_priv);
int bes2600_bh_resume(struct bes2600_common *hw_priv);
/* Must be called from BH thread. */
void bes2600_enable_powersave(struct bes2600_vif *priv,
bool enable);
int wsm_release_tx_buffer(struct bes2600_common *hw_priv, int count);
int wsm_release_vif_tx_buffer(struct bes2600_common *hw_priv, int if_id,
int count);
/*
* Direct-deliver an RX SKB into the WSM/mac80211 stack.
* Process context, sleepable, caller holds no bes2600 spinlock.
* Function frees skb on every path. See bh.c for full contract.
*/
int bes2600_bh_handle_rx_skb(struct bes2600_common *hw_priv,
struct sk_buff *skb);
int bes2600_bh_sw_process(struct bes2600_common *hw_priv,
struct wsm_tx_confirm *tx_confirm);
void bes2600_bh_inc_pending_count(struct bes2600_common *hw_priv, int idx);
void bes2600_bh_dec_pending_count(struct bes2600_common *hw_priv, int idx);
void bes2600_bh_mcu_active_monitor(struct timer_list* t);
void bes2600_bh_lmac_active_monitor(struct timer_list* t);
#endif /* BES2600_BH_H */