From: frank0988 <frank0988855428@gmail.com>
To: Jeff Johnson <jjohnson@kernel.org>
Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org,
frank0988 <frank0988855428@gmail.com>
Subject: [PATCH] wifi: ath: avoid repeated divisions in DFS PRI detector
Date: Wed, 1 Jul 2026 17:04:23 +0000 [thread overview]
Message-ID: <20260701170424.380202-1-frank0988855428@gmail.com> (raw)
pde_get_multiple() is called repeatedly with the same PRI (Pulse
Repetition Interval) value while validating candidate and existing PRI
sequences.
Cache the reciprocal value for each sequence structure and leverage
reciprocal_divide() in the hot path. This keeps the existing matching
logic and tolerance checks intact while replacing expensive hardware
integer divisions with low-cost multiply-and-shift operations.
Testing with a userspace model of the same detector logic demonstrated
identical detector states and outputs across 100 verification traces.
To eliminate memory allocator noise, an isolated micro-benchmark using
a static object pool showed that the reciprocal variant reduces CPU
cycles by approximately 3.4%.
Signed-off-by: frank0988 <frank0988855428@gmail.com>
---
drivers/net/wireless/ath/dfs_pri_detector.c | 14 +++++++++++---
drivers/net/wireless/ath/dfs_pri_detector.h | 3 +++
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/dfs_pri_detector.c b/drivers/net/wireless/ath/dfs_pri_detector.c
index 388f9d1913bd..520fd1567a0b 100644
--- a/drivers/net/wireless/ath/dfs_pri_detector.c
+++ b/drivers/net/wireless/ath/dfs_pri_detector.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <linux/reciprocal_div.h>
#include "ath.h"
#include "dfs_pattern_detector.h"
@@ -41,7 +42,9 @@ struct pulse_elem {
* pde_get_multiple() - get number of multiples considering a given tolerance
* Return value: factor if abs(val - factor*fraction) <= tolerance, 0 otherwise
*/
-static u32 pde_get_multiple(u32 val, u32 fraction, u32 tolerance)
+static u32 pde_get_multiple(u32 val, u32 fraction,
+ struct reciprocal_value fraction_recip,
+ u32 tolerance)
{
u32 remainder;
u32 factor;
@@ -56,8 +59,8 @@ static u32 pde_get_multiple(u32 val, u32 fraction, u32 tolerance)
/* val and fraction are within tolerance */
return 1;
- factor = val / fraction;
- remainder = val % fraction;
+ factor = reciprocal_divide(val, fraction_recip);
+ remainder = val - factor * fraction;
if (remainder > tolerance) {
/* no exact match */
if ((fraction - remainder) <= tolerance)
@@ -247,6 +250,9 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde,
ps.last_ts = ts;
ps.pri = GET_PRI_TO_USE(pde->rs->pri_min,
pde->rs->pri_max, ts - p->ts);
+ ps.pri_recip = (struct reciprocal_value){};
+ if (ps.pri)
+ ps.pri_recip = reciprocal_value(ps.pri);
ps.dur = ps.pri * (pde->rs->ppb - 1)
+ 2 * pde->rs->max_pri_tolerance;
@@ -261,6 +267,7 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde,
break;
/* check if pulse match (multi)PRI */
factor = pde_get_multiple(ps.last_ts - p2->ts, ps.pri,
+ ps.pri_recip,
pde->rs->max_pri_tolerance);
if (factor > 0) {
ps.count++;
@@ -318,6 +325,7 @@ pseq_handler_add_to_existing_seqs(struct pri_detector *pde, u64 ts)
delta_ts = ts - ps->last_ts;
factor = pde_get_multiple(delta_ts, ps->pri,
+ ps->pri_recip,
pde->rs->max_pri_tolerance);
if (factor > 0) {
ps->last_ts = ts;
diff --git a/drivers/net/wireless/ath/dfs_pri_detector.h b/drivers/net/wireless/ath/dfs_pri_detector.h
index 86339f2b4d3a..c519466cff8b 100644
--- a/drivers/net/wireless/ath/dfs_pri_detector.h
+++ b/drivers/net/wireless/ath/dfs_pri_detector.h
@@ -18,6 +18,7 @@
#define DFS_PRI_DETECTOR_H
#include <linux/list.h>
+#include <linux/reciprocal_div.h>
extern struct ath_dfs_pool_stats global_dfs_pool_stats;
@@ -25,6 +26,7 @@ extern struct ath_dfs_pool_stats global_dfs_pool_stats;
* struct pri_sequence - sequence of pulses matching one PRI
* @head: list_head
* @pri: pulse repetition interval (PRI) in usecs
+ * @pri_recip: cached reciprocal value for PRI divisions
* @dur: duration of sequence in usecs
* @count: number of pulses in this sequence
* @count_falses: number of not matching pulses in this sequence
@@ -35,6 +37,7 @@ extern struct ath_dfs_pool_stats global_dfs_pool_stats;
struct pri_sequence {
struct list_head head;
u32 pri;
+ struct reciprocal_value pri_recip;
u32 dur;
u32 count;
u32 count_falses;
--
2.53.0
next reply other threads:[~2026-07-01 17:04 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 17:04 frank0988 [this message]
2026-07-01 19:08 ` [PATCH] wifi: ath: avoid repeated divisions in DFS PRI detector Jeff Johnson
2026-07-02 3:52 ` [PATCH v2] " Chun-Cheng Chang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260701170424.380202-1-frank0988855428@gmail.com \
--to=frank0988855428@gmail.com \
--cc=jjohnson@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox