diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2014-01-21 20:29:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-22 02:17:20 -0500 |
commit | 89770b0a69ee0e0e5e99c722192d535115f73778 (patch) | |
tree | a8c96a91c2417dc81f5ce08aa59ebcfd456e0335 | |
parent | f337db64af059c9a94278a8b0ab97d87259ff62f (diff) |
net: introduce reciprocal_scale helper and convert users
As David Laight suggests, we shouldn't necessarily call this
reciprocal_divide() when users didn't requested a reciprocal_value();
lets keep the basic idea and call it reciprocal_scale(). More
background information on this topic can be found in [1].
Joint work with Hannes Frederic Sowa.
[1] http://homepage.cs.uiowa.edu/~jones/bcd/divide.html
Suggested-by: David Laight <david.laight@aculab.com>
Cc: Jakub Zawadzki <darkjames-ws@darkjames.pl>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/kernel.h | 19 | ||||
-rw-r--r-- | include/net/codel.h | 4 | ||||
-rw-r--r-- | net/packet/af_packet.c | 3 |
3 files changed, 21 insertions, 5 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index ecb87544cc5d..03d8a6b0e2e8 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -193,6 +193,25 @@ extern int _cond_resched(void); | |||
193 | (__x < 0) ? -__x : __x; \ | 193 | (__x < 0) ? -__x : __x; \ |
194 | }) | 194 | }) |
195 | 195 | ||
196 | /** | ||
197 | * reciprocal_scale - "scale" a value into range [0, ep_ro) | ||
198 | * @val: value | ||
199 | * @ep_ro: right open interval endpoint | ||
200 | * | ||
201 | * Perform a "reciprocal multiplication" in order to "scale" a value into | ||
202 | * range [0, ep_ro), where the upper interval endpoint is right-open. | ||
203 | * This is useful, e.g. for accessing a index of an array containing | ||
204 | * ep_ro elements, for example. Think of it as sort of modulus, only that | ||
205 | * the result isn't that of modulo. ;) Note that if initial input is a | ||
206 | * small value, then result will return 0. | ||
207 | * | ||
208 | * Return: a result based on val in interval [0, ep_ro). | ||
209 | */ | ||
210 | static inline u32 reciprocal_scale(u32 val, u32 ep_ro) | ||
211 | { | ||
212 | return (u32)(((u64) val * ep_ro) >> 32); | ||
213 | } | ||
214 | |||
196 | #if defined(CONFIG_MMU) && \ | 215 | #if defined(CONFIG_MMU) && \ |
197 | (defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_DEBUG_ATOMIC_SLEEP)) | 216 | (defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_DEBUG_ATOMIC_SLEEP)) |
198 | void might_fault(void); | 217 | void might_fault(void); |
diff --git a/include/net/codel.h b/include/net/codel.h index 3b04ff5f6f8d..fe0eab32ce76 100644 --- a/include/net/codel.h +++ b/include/net/codel.h | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/skbuff.h> | 46 | #include <linux/skbuff.h> |
47 | #include <net/pkt_sched.h> | 47 | #include <net/pkt_sched.h> |
48 | #include <net/inet_ecn.h> | 48 | #include <net/inet_ecn.h> |
49 | #include <linux/reciprocal_div.h> | ||
50 | 49 | ||
51 | /* Controlling Queue Delay (CoDel) algorithm | 50 | /* Controlling Queue Delay (CoDel) algorithm |
52 | * ========================================= | 51 | * ========================================= |
@@ -211,10 +210,9 @@ static codel_time_t codel_control_law(codel_time_t t, | |||
211 | codel_time_t interval, | 210 | codel_time_t interval, |
212 | u32 rec_inv_sqrt) | 211 | u32 rec_inv_sqrt) |
213 | { | 212 | { |
214 | return t + reciprocal_divide(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT); | 213 | return t + reciprocal_scale(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT); |
215 | } | 214 | } |
216 | 215 | ||
217 | |||
218 | static bool codel_should_drop(const struct sk_buff *skb, | 216 | static bool codel_should_drop(const struct sk_buff *skb, |
219 | struct Qdisc *sch, | 217 | struct Qdisc *sch, |
220 | struct codel_vars *vars, | 218 | struct codel_vars *vars, |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index df3cbdd585c7..97346162803d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -88,7 +88,6 @@ | |||
88 | #include <linux/virtio_net.h> | 88 | #include <linux/virtio_net.h> |
89 | #include <linux/errqueue.h> | 89 | #include <linux/errqueue.h> |
90 | #include <linux/net_tstamp.h> | 90 | #include <linux/net_tstamp.h> |
91 | #include <linux/reciprocal_div.h> | ||
92 | #include <linux/percpu.h> | 91 | #include <linux/percpu.h> |
93 | #ifdef CONFIG_INET | 92 | #ifdef CONFIG_INET |
94 | #include <net/inet_common.h> | 93 | #include <net/inet_common.h> |
@@ -1262,7 +1261,7 @@ static unsigned int fanout_demux_hash(struct packet_fanout *f, | |||
1262 | struct sk_buff *skb, | 1261 | struct sk_buff *skb, |
1263 | unsigned int num) | 1262 | unsigned int num) |
1264 | { | 1263 | { |
1265 | return reciprocal_divide(skb->rxhash, num); | 1264 | return reciprocal_scale(skb->rxhash, num); |
1266 | } | 1265 | } |
1267 | 1266 | ||
1268 | static unsigned int fanout_demux_lb(struct packet_fanout *f, | 1267 | static unsigned int fanout_demux_lb(struct packet_fanout *f, |