Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 44274
b: refs/heads/master
c: d63d836
h: refs/heads/master
v: v3
  • Loading branch information
Gerrit Renker authored and David S. Miller committed Dec 11, 2006
1 parent 9ce4418 commit 51c6247
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 36 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f9e5b573f7249b0e04a03457b55081d1f60f2bf
refs/heads/master: d63d8364cfe17fc9bb738f554f452595f76f21d2
19 changes: 0 additions & 19 deletions trunk/net/dccp/ccids/ccid3.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,23 +171,4 @@ static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
return ccid_priv(dccp_sk(sk)->dccps_hc_rx_ccid);
}

static inline u64 scaled_div(u64 a, u32 b)
{
BUG_ON(b==0);
a *= 1000000;
do_div(a, b);
return a;
}

static inline u32 scaled_div32(u64 a, u32 b)
{
u64 result = scaled_div(a, b);

if (result > UINT_MAX) {
DCCP_CRIT("Overflow: a(%llu)/b(%u) > ~0U",
(unsigned long long)a, b);
return UINT_MAX;
}
return result;
}
#endif /* _DCCP_CCID3_H_ */
23 changes: 22 additions & 1 deletion trunk/net/dccp/ccids/lib/tfrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,29 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/

#include <linux/types.h>
#include <asm/div64.h>

/* integer-arithmetic divisions of type (a * 1000000)/b */
static inline u64 scaled_div(u64 a, u32 b)
{
BUG_ON(b==0);
a *= 1000000;
do_div(a, b);
return a;
}

static inline u32 scaled_div32(u64 a, u32 b)
{
u64 result = scaled_div(a, b);

if (result > UINT_MAX) {
DCCP_CRIT("Overflow: a(%llu)/b(%u) > ~0U",
(unsigned long long)a, b);
return UINT_MAX;
}
return result;
}

extern u32 tfrc_calc_x(u16 s, u32 R, u32 p);
extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
Expand Down
28 changes: 13 additions & 15 deletions trunk/net/dccp/ccids/lib/tfrc_equation.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
*/

#include <linux/module.h>
#include <asm/div64.h>
#include "../../dccp.h"
#include "tfrc.h"

Expand Down Expand Up @@ -616,15 +615,12 @@ static inline u32 tfrc_binsearch(u32 fval, u8 small)
* @R: RTT scaled by 1000000 (i.e., microseconds)
* @p: loss ratio estimate scaled by 1000000
* Returns X_calc in bytes per second (not scaled).
*
* Note: DO NOT alter this code unless you run test cases against it,
* as the code has been optimized to stop underflow/overflow.
*/
u32 tfrc_calc_x(u16 s, u32 R, u32 p)
{
int index;
u16 index;
u32 f;
u64 tmp1, tmp2;
u64 result;

/* check against invalid parameters and divide-by-zero */
BUG_ON(p > 1000000); /* p must not exceed 100% */
Expand All @@ -650,15 +646,17 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
f = tfrc_calc_x_lookup[index][0];
}

/* The following computes X = s/(R*f(p)) in bytes per second. Since f(p)
* and R are both scaled by 1000000, we need to multiply by 1000000^2.
* ==> DO NOT alter this unless you test against overflow on 32 bit */
tmp1 = ((u64)s * 100000000);
tmp2 = ((u64)R * (u64)f);
do_div(tmp2, 10000);
do_div(tmp1, tmp2);

return (u32)tmp1;
/*
* Compute X = s/(R*f(p)) in bytes per second.
* Since f(p) and R are both scaled by 1000000, we need to multiply by
* 1000000^2. To avoid overflow, the result is computed in two stages.
* This works under almost all reasonable operational conditions, for a
* wide range of parameters. Yet, should some strange combination of
* parameters result in overflow, the use of scaled_div32 will catch
* this and return UINT_MAX - which is a logically adequate consequence.
*/
result = scaled_div(s, R);
return scaled_div32(result, f);
}

EXPORT_SYMBOL_GPL(tfrc_calc_x);
Expand Down

0 comments on commit 51c6247

Please sign in to comment.