Linux wireless drivers development
 help / color / mirror / Atom feed
From: Chun-Cheng Chang <frank0988855428@gmail.com>
To: Jeff Johnson <jjohnson@kernel.org>
Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org,
	Chun-Cheng Chang <frank0988855428@gmail.com>
Subject: [PATCH v2] wifi: ath: avoid repeated divisions in DFS PRI detector
Date: Thu,  2 Jul 2026 03:52:36 +0000	[thread overview]
Message-ID: <20260702035236.392328-1-frank0988855428@gmail.com> (raw)
In-Reply-To: <20260701170424.380202-1-frank0988855428@gmail.com>

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: Chun-Cheng Chang <frank0988855428@gmail.com>
---
Changes in v2:
- Use a known identity for the author and Signed-off-by tags.

 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


      parent reply	other threads:[~2026-07-02  3:52 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-01 17:04 [PATCH] wifi: ath: avoid repeated divisions in DFS PRI detector frank0988
2026-07-01 19:08 ` Jeff Johnson
2026-07-02  3:52 ` Chun-Cheng Chang [this message]

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=20260702035236.392328-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