From 29a9c21d994528ab93db75dd782afc72c3085366 Mon Sep 17 00:00:00 2001 From: Michael Blizek Date: Fri, 24 Jun 2011 09:43:14 +0200 Subject: [PATCH] accurate multiply_div, credit calculations, connid_reuse bugfixes --- net/cor/common.c | 123 +++++++++++++++++---------- net/cor/cor.h | 21 +++-- net/cor/credits.c | 241 +++++++++++++++++++++++++++++------------------------ net/cor/neighbor.c | 15 ++-- net/cor/settings.h | 1 + 5 files changed, 237 insertions(+), 164 deletions(-) diff --git a/net/cor/common.c b/net/cor/common.c index 2ff85701b94..6e7bb962f7c 100644 --- a/net/cor/common.c +++ b/net/cor/common.c @@ -446,54 +446,89 @@ static inline int numdigits(__u64 value) return digits; } -/* approximate (a*b) / c without overflowing a*b */ -__u64 __attribute__((const)) multiply_div(__u64 a, __u64 b, __u64 c) +static void mul(__u64 a, __u64 b, __u64 *reshigh, __u64 *reslow) { - int alen = numdigits(a); - int blen = numdigits(b); - int clen = numdigits(c); - - BUG_ON(alen < 0 || alen > 64); - BUG_ON(blen < 0 || blen > 64); - BUG_ON(clen < 0 || clen > 64); - - BUG_ON((a == 0 && alen != 0) || (a != 0 && alen == 0)); - BUG_ON((b == 0 && blen != 0) || (b != 0 && blen == 0)); - BUG_ON((c == 0 && clen != 0) || (c != 0 && clen == 0)); - - BUG_ON(a >= b && alen < blen); - BUG_ON(a >= c && alen < clen); - BUG_ON(b >= a && blen < alen); - BUG_ON(b >= c && blen < clen); - BUG_ON(c >= a && clen < alen); - BUG_ON(c >= b && clen < blen); - - if (alen == 0 || blen == 0) - return 0; + __u32 al = a; + __u32 ah = (a >> 32); + __u32 bl = b; + __u32 bh = (b >> 32); + + __u64 r1 = ((__u64) al) * bl; + __u64 r20 = (r1 >> 32); + __u64 r21 = ((__u64) ah) * bl; + __u64 r22 = ((__u64) al) * bh; + __u64 r2 = r20 + ((r21 << 32) >> 32) + ((r22 << 32) >> 32); + __u64 r30 = (r21 >> 32) + (r22 >> 32) + (r2 >> 32); + __u64 r31 = ((__u64) ah) * bh; + + BUG_ON(reshigh == 0); + BUG_ON(reslow == 0); + + (*reslow) = ((r1 << 32) >> 32) + (r2 << 32); + (*reshigh) = r30 + r31; +} + +/* calculate (a*b+rem)/c */ +__u64 multiply_div2(__u64 a, __u64 b, __s64 rem, __u64 c, __u64 *remainder) +{ + __u64 res = 0; + __u64 reshigh = 0; + __u64 reslow = 0; + int u; + + __u64 high = 0; + __u64 low = 0; + + mul(a, b, &high, &low); + + if (rem < 0) { + __u64 rem0 = (rem == S64_MIN) ? (((__u64) S64_MAX) + 1) : + (0 - rem); + if (low - rem0 > low) + high--; + low -= rem0; + } else { + if (low + ((__u64) rem) < low) + high++; + low += ((__u64) rem); + } - BUG_ON(c == 0); - if (alen + blen <= 64) - return (a*b)/c; + for(u=63;u>=0;u--) { + __u64 tmphigh; + __u64 tmplow; - if (a >= b && alen > clen + 16) - return mul_saturated(a/c, b); - else if (a < b && blen > clen + 16) - return mul_saturated(b/c, a); + __u64 tmpres = res + (1LL << u); + + mul(c, tmpres, &tmphigh, &tmplow); + + if (tmphigh > high) + continue; + if (tmphigh < high) + goto apply; + + if (tmplow > low) + continue; + if (tmplow < low) + goto apply; + + if (remainder != 0) + (*remainder) = 0; + return tmpres; +apply: + res = tmpres; + reshigh = tmphigh; + reslow = tmplow; + } + + if (remainder != 0) { + (*remainder) = low - reslow; + if ((*remainder) > c) + (*remainder) = 0; - while (alen + blen > 64) { - if (alen > blen || (alen == blen && a > b)) { - alen--; - a = (a >> 1); - } else { - blen--; - b = (b >> 1); - } - clen--; - c = (c >> 1); } - return (a*b)/c; + return res; } static inline int hdr_size(void) @@ -913,6 +948,8 @@ int conn_init_out(struct conn *trgt_unconn_ll, struct neighbor *nb) if (unlikely(src_none_ll->source.in.cir == 0)) goto out; + memset(src_none_ll->source.in.cir, 0, sizeof(struct connid_reuse_item)); + if (unlikely(connid_alloc(src_none_ll))) { rc = 1; goto out_freecir; @@ -1007,8 +1044,8 @@ struct conn* alloc_conn(gfp_t allocflags) mutex_init(&(cn1->rcv_lock)); mutex_init(&(cn2->rcv_lock)); - cn1->jiffies_credit_update = jiffies; - cn2->jiffies_credit_update = cn1->jiffies_credit_update; + cn1->ktime_credit_update = ktime_get(); + cn2->ktime_credit_update = cn1->ktime_credit_update; cn1->crate_forward = ((1 << 31) - (((__u32) 1 << 31) / 10)); cn2->crate_forward = ((1 << 31) - (((__u32) 1 << 31) / 10)); diff --git a/net/cor/cor.h b/net/cor/cor.h index fba256e7c26..42b4d00c1cc 100644 --- a/net/cor/cor.h +++ b/net/cor/cor.h @@ -448,12 +448,12 @@ struct neighbor{ atomic_t ooo_packets; spinlock_t credits_lock; - unsigned long jiffies_credit_update; - unsigned long jiffies_credit_decay; + ktime_t ktime_credit_update; + ktime_t ktime_credit_decay; /* we only keep track on how much the other side may spend */ __u64 credits; - __u32 credits_fract; + __s32 credits_rem; /* credit rates are in credits/sec */ __u32 creditrate_initial; __u64 creditrate_earning; @@ -634,10 +634,11 @@ struct conn{ struct mutex rcv_lock; - unsigned long jiffies_credit_update; + ktime_t ktime_credit_update; struct list_head credit_list; /* state */ __u64 credits; + __s32 credits_rem; /* credit rates per second, locked by credit_lock (in credit.c) */ __u64 crate_in; __u32 crate_out; @@ -821,7 +822,14 @@ extern __u16 __attribute__((const)) enc_log_300_24(__u64 value); extern __u64 __attribute__((const)) dec_log_300_24(__u16 value); -extern __u64 __attribute__((const)) multiply_div(__u64 a, __u64 b, __u64 c); +extern __u64 multiply_div2(__u64 a, __u64 b, __s64 rem, __u64 c, + __u64 *remainder); + +static inline __u64 __attribute__((const)) multiply_div(__u64 a, __u64 b, + __u64 c) +{ + return multiply_div2(a, b, 0, c, 0); +} extern char *htable_get(struct htable *ht, __u32 key, void *searcheditem); @@ -872,7 +880,8 @@ extern __u32 creditrate_initial(void); extern int refresh_conn_credits(struct conn *conn, int fromperiodic, int locked); -extern void set_creditrate_initial(struct neighbor *nb, __u32 debitrate); +extern void set_creditrate_initial(struct neighbor *nb, __u32 debitrate, + ktime_t now); extern void set_conn_in_decaytime(struct neighbor *nb, __u32 conn_id, struct conn *src_in, __u8 decaytime_seqno, __u16 decaytime); diff --git a/net/cor/credits.c b/net/cor/credits.c index f91569ac657..12e0a6fb634 100644 --- a/net/cor/credits.c +++ b/net/cor/credits.c @@ -24,18 +24,6 @@ LIST_HEAD(credit_refresh_conns); static struct delayed_work credit_refresh_work; static int refresh_running = 0; -static inline __s64 mul_saturated_signed(__s64 a, __u64 b) -{ - __s64 res = a*b; - if (unlikely(res / a != b)) { - if (a < 0) - return S64_MIN; - else - return S64_MAX; - } - return res; -} - static __u64 decay_credits(__u64 credits) { int decay_rate = (CREDIT_DECAYTIME_HOURS * 3) / 2; @@ -53,72 +41,82 @@ __u32 creditrate_initial(void) } /* credit_lock must be held while calling this */ -static void refresh_credits_state(struct neighbor *nb) +static void refresh_credits_state(struct neighbor *nb, ktime_t now) { - unsigned long jiffies_tmp = jiffies; + __u64 creditrate_add; + __u64 creditrate_sub; - __s64 creditrate; - __s64 credits_adj; - - if (jiffies_tmp == nb->jiffies_credit_update) + if (ktime_before_eq(now, nb->ktime_credit_update)) return; - if (unlikely(nb->creditrate_earning > S64_MAX)) - creditrate = S64_MAX; + creditrate_add = nb->creditrate_earning; + if (unlikely(creditrate_add + nb->creditrate_initial < creditrate_add)) + creditrate_add = -1; else - creditrate = nb->creditrate_earning; + creditrate_add += nb->creditrate_initial; - if (unlikely(creditrate - nb->creditrate_spending > creditrate)) - creditrate = S64_MIN; - else - creditrate -= nb->creditrate_spending; + creditrate_sub = multiply_div(nb->creditrate_spending, + 1000 - CREDIT_EXCHANGETAX_PERMILLE, 1000); - if (unlikely(creditrate + nb->creditrate_initial < creditrate)) - creditrate = S64_MAX; - else - creditrate += nb->creditrate_initial; + if (creditrate_sub > creditrate_add) { + __u64 rem; - credits_adj = mul_saturated_signed(creditrate, jiffies_tmp - - nb->jiffies_credit_update); + __u64 adj = multiply_div2(creditrate_sub - creditrate_add, + 0 - nb->credits_rem, ktime_to_ns(now) - + ktime_to_ns(nb->ktime_credit_update), + 1000000000, &rem); - if (unlikely(credits_adj + nb->credits_fract < credits_adj)) { - credits_adj = S64_MAX; - } else { - credits_adj += nb->credits_fract; - } + BUG_ON(rem >= 1000000000); - if (unlikely((credits_adj < 0 && (nb->credits < -(credits_adj/HZ))) || - credits_adj == S64_MIN)) { - nb->credits = 0; - nb->credits_fract = 0; - } else if (unlikely(credits_adj > 0 && (nb->credits + credits_adj/HZ) < - nb->credits)) { - nb->credits = -1; - nb->credits_fract = 0; - } else { - nb->credits += credits_adj / HZ; - nb->credits_fract = credits_adj % HZ; + if (unlikely(nb->credits < adj)) { + nb->credits = 0; + nb->credits_rem = 0; + } else { + nb->credits -= adj; + nb->credits_rem = 0 - rem; + } + } else if (creditrate_sub < creditrate_add) { + __u64 rem; + + __u64 adj = multiply_div2(creditrate_add - creditrate_sub, + nb->credits_rem, ktime_to_ns(now) - + ktime_to_ns(nb->ktime_credit_update), + 1000000000, &rem); + + BUG_ON(rem >= 1000000000); + + if (unlikely(nb->credits + adj < nb->credits)) { + nb->credits = -1; + nb->credits_rem = 0; + } else { + nb->credits += adj; + nb->credits_rem = rem; + } } - nb->jiffies_credit_update = jiffies_tmp; + nb->ktime_credit_update = now; - if (unlikely(time_after(nb->jiffies_credit_decay + 3600*HZ, - jiffies_tmp))) { + if (unlikely(ktime_after(ktime_add_us(nb->ktime_credit_decay, + 3600LL * 1000000), now))) { nb->credits = decay_credits(nb->credits); - nb->jiffies_credit_decay += 3600*HZ; - if (unlikely(time_after(nb->jiffies_credit_decay + 3600*HZ, - jiffies_tmp))) - nb->jiffies_credit_decay = jiffies_tmp - 3600*HZ; + nb->ktime_credit_decay = ktime_add_us( + nb->ktime_credit_decay, 3600LL * 1000000); + + if (unlikely(ktime_after(ktime_add_us(nb->ktime_credit_decay, + 3600LL * 1000000), now))) { + nb->ktime_credit_decay = ktime_sub_us(now, + 3600LL * 1000000); + } } } -void set_creditrate_initial(struct neighbor *nb, __u32 creditrate) +void set_creditrate_initial(struct neighbor *nb, __u32 creditrate, ktime_t now) { unsigned long iflags; spin_lock_irqsave(&(nb->credits_lock), iflags); - refresh_credits_state(nb); + refresh_credits_state(nb, now); nb->creditrate_initial = creditrate; spin_unlock_irqrestore(&(nb->credits_lock), iflags); } @@ -131,15 +129,15 @@ static __u64 decay_time_to_crate(struct neighbor *nb, __u16 decay_time_raw) return nb->credits / (decay_time * 3 / 2); } -#warning todo exchange tax static __u16 crate_to_decay_time(struct neighbor *nb, __u64 crate_out) { if (crate_out <= 2) return enc_log_300_24(0); - return enc_log_300_24(nb->credits / (crate_out / 3 * 2)); + return enc_log_300_24(nb->credits / multiply_div(crate_out, + 2*(1000 - CREDIT_EXCHANGETAX_PERMILLE), 3 * 1000)); } -static void refresh_crate_forward(struct conn *cn_lc, long jiffies_diff) +static void refresh_crate_forward(struct conn *cn_lc, __u64 timediff_ns) { __u8 last_bufferstate = cn_lc->last_bufferstate; @@ -163,15 +161,19 @@ static void refresh_crate_forward(struct conn *cn_lc, long jiffies_diff) BUG_ON(cn_lc->crate_forward > (1 << 31)); - for (;jiffies_diff < 0;jiffies_diff--) { + while (timediff_ns > 0) { + __u64 currdiff = timediff_ns; + if (currdiff > 1000000) + currdiff = 1000000; + if (last_bufferstate == 0) - cn_lc->crate_forward = ( ((__u64) cn_lc->crate_forward) * - (HZ << (shift_base - 2))) / - (HZ << shift_base); + cn_lc->crate_forward = ( ((__u64)cn_lc->crate_forward) * + (currdiff << (shift_base - 2))) / + (currdiff << shift_base); else - cn_lc->crate_forward = ( ((__u64) cn_lc->crate_forward) * - (HZ << shift_base)) / - (HZ << (shift_base - 1)); + cn_lc->crate_forward = ( ((__u64)cn_lc->crate_forward) * + (currdiff << shift_base)) / + (currdiff << (shift_base - 1)); if (cn_lc->crate_forward > (1 << 31)) { cn_lc->crate_forward = (1 << 31); @@ -182,6 +184,8 @@ static void refresh_crate_forward(struct conn *cn_lc, long jiffies_diff) cn_lc->crate_forward = (1 << 16); break; } + + timediff_ns -= currdiff; } cn_lc->crate_out = multiply_div(cn_lc->crate_in, cn_lc->crate_forward, @@ -245,8 +249,8 @@ static __u64 newnbrate(__u64 nbrate, __u64 oldconnrate, __u64 newconnrate) return nbrate; } -static void refresh_conn_crate_out(struct conn *trgt_out_lc, - unsigned long jiffies_diff) +static void refresh_conn_crate_out(struct conn *trgt_out_lc, ktime_t now, + __u64 timediff_ns) { unsigned long iflags; @@ -256,7 +260,7 @@ static void refresh_conn_crate_out(struct conn *trgt_out_lc, __u16 crate; if (likely(trgt_out_lc->target.out.conn_id != 0)) { - refresh_crate_forward(trgt_out_lc, jiffies_diff); + refresh_crate_forward(trgt_out_lc, timediff_ns); if (((__s32) (trgt_out_lc->target.out.seqno_nextsend - trgt_out_lc->target.out.seqno_windowlimit)) <=0) @@ -268,7 +272,7 @@ static void refresh_conn_crate_out(struct conn *trgt_out_lc, spin_lock_irqsave(&(trgt_out_lc->target.out.nb->credits_lock), iflags); oldrate = trgt_out_lc->crate_out; - refresh_credits_state(trgt_out_lc->target.out.nb); + refresh_credits_state(trgt_out_lc->target.out.nb, now); trgt_out_lc->target.out.nb->creditrate_spending = newnbrate( trgt_out_lc->target.out.nb->creditrate_spending, oldrate, trgt_out_lc->crate_out); @@ -284,7 +288,7 @@ static void refresh_conn_crate_out(struct conn *trgt_out_lc, } } -static void refresh_conn_crate_in(struct conn *src_in_lc) +static void refresh_conn_crate_in(struct conn *src_in_lc, ktime_t now) { unsigned long iflags; @@ -292,7 +296,7 @@ static void refresh_conn_crate_in(struct conn *src_in_lc) spin_lock_irqsave(&(src_in_lc->source.in.nb->credits_lock), iflags); - refresh_credits_state(src_in_lc->source.in.nb); + refresh_credits_state(src_in_lc->source.in.nb, now); src_in_lc->crate_in = decay_time_to_crate(src_in_lc->source.in.nb, src_in_lc->source.in.decaytime); @@ -304,13 +308,14 @@ static void refresh_conn_crate_in(struct conn *src_in_lc) iflags); } -static void refresh_conn_crates(struct conn *cn_lc, unsigned long jiffies_diff) +static void refresh_conn_crates(struct conn *cn_lc, ktime_t now, + __u64 timediff_ns) { /* set conn->crate_in */ if (cn_lc->sourcetype == SOURCE_NONE) { cn_lc->crate_in = cn_lc->reversedir->crate_out; } else if (cn_lc->sourcetype == SOURCE_IN) { - refresh_conn_crate_in(cn_lc); + refresh_conn_crate_in(cn_lc, now); } else if (cn_lc->sourcetype == SOURCE_SOCK) { if (cn_lc->reversedir->target.sock.credituser == 1) cn_lc->crate_in = cn_lc->reversedir->crate_out; @@ -332,56 +337,67 @@ static void refresh_conn_crates(struct conn *cn_lc, unsigned long jiffies_diff) if (cn_lc->target.sock.credituser == 0) { cn_lc->crate_out = cn_lc->crate_in; } else { - refresh_crate_forward(cn_lc, jiffies_diff); + refresh_crate_forward(cn_lc, timediff_ns); cn_lc->last_bufferstate = ( cn_lc->reversedir->source.sock.wait_len != 0); } } else if (cn_lc->targettype == TARGET_OUT) { - refresh_conn_crate_out(cn_lc, jiffies_diff); + refresh_conn_crate_out(cn_lc, now, timediff_ns); } else { BUG(); } } -static void _refresh_conn_credits(struct conn *cn_lc) +static void _refresh_conn_credits(struct conn *cn_lc, ktime_t now) { - unsigned long jiffies_tmp = jiffies; - unsigned long jiffies_diff = jiffies_tmp - cn_lc->jiffies_credit_update; + __u64 timediff_ns = ktime_to_ns(now) - + ktime_to_ns(cn_lc->ktime_credit_update); - if (jiffies_diff == 0) + if (ktime_before_eq(now, cn_lc->ktime_credit_update)) { + timediff_ns = 0; goto crates; - - #warning todo rates in in secs + } if (unlikely(cn_lc->crate_out > cn_lc->crate_in)) { - __u64 diff = cn_lc->crate_out - cn_lc->crate_in; - if (unlikely((diff * jiffies_diff) / jiffies_diff != diff)) - diff = -1; - else - diff *= jiffies_diff; + __u64 rem; + + __u64 adj = multiply_div2(cn_lc->crate_out - cn_lc->crate_in, + 0 - cn_lc->credits_rem, timediff_ns, + 1000000000, &rem); - if (unlikely(cn_lc->credits - diff > cn_lc->credits)) + BUG_ON(rem >= 1000000000); + + if (unlikely(cn_lc->credits < adj)) { cn_lc->credits = 0; - else - cn_lc->credits -= diff; + cn_lc->credits_rem = 0; + } else { + cn_lc->credits -= adj; + cn_lc->credits_rem = 0 - rem; + } } else { - __u64 diff = cn_lc->crate_in - cn_lc->crate_out; - if (unlikely((diff * jiffies_diff) / jiffies_diff != diff)) - diff = -1; - else - diff *= jiffies_diff; + __u64 rem; + + __u64 adj = multiply_div2(cn_lc->crate_in - cn_lc->crate_out, + cn_lc->credits_rem, timediff_ns, + 1000000000, &rem); + + BUG_ON(rem >= 1000000000); - if (unlikely(cn_lc->credits + diff < cn_lc->credits)) + if (unlikely(cn_lc->credits + adj < cn_lc->credits)) { cn_lc->credits = -1; - else - cn_lc->credits += diff; + cn_lc->credits_rem = 0; + } else { + cn_lc->credits += adj; + cn_lc->credits_rem = rem; + } } crates: - refresh_conn_crates(cn_lc, jiffies_tmp - cn_lc->jiffies_credit_update); + refresh_conn_crates(cn_lc, now, timediff_ns); - cn_lc->jiffies_credit_update = jiffies_tmp; + if (timediff_ns != 0) + cn_lc->ktime_credit_update = now; } static void credits_unlock_conn(struct conn *cn, __u32 hints) @@ -421,6 +437,7 @@ int refresh_conn_credits(struct conn *cn, int fromperiodic, int locked) __u32 unlockhints = 0; int rc = 0; int put = 0; + ktime_t now; if (likely(locked == 0)) unlockhints = credits_lock_conn(cn); @@ -431,11 +448,12 @@ int refresh_conn_credits(struct conn *cn, int fromperiodic, int locked) goto out; } + now = ktime_get(); + if (fromperiodic) { /* quit if not time for refresh yet */ - unsigned long jiffies_tmp = jiffies; - if (time_after(cn->jiffies_credit_update + - HZ*CREDIT_REFRESHINTERVAL_SEC, jiffies_tmp)) { + if (ktime_after(ktime_add_us(cn->ktime_credit_update, + CREDIT_REFRESHINTERVAL_SEC * 1000000), now)) { int alreadyrefreshed; spin_lock_irqsave(&credits_list_lock, iflags); @@ -446,10 +464,13 @@ int refresh_conn_credits(struct conn *cn, int fromperiodic, int locked) if (unlikely(alreadyrefreshed)) goto out; - rc = cn->jiffies_credit_update - jiffies_tmp; + rc = usecs_to_jiffies(ktime_us_delta(ktime_add_us( + cn->ktime_credit_update, + CREDIT_REFRESHINTERVAL_SEC * 1000000), + now)) + 1; if (rc < HZ) rc = HZ; - if (rc > HZ * CREDIT_REFRESHINTERVAL_SEC) + if (unlikely(rc > HZ * CREDIT_REFRESHINTERVAL_SEC)) rc = HZ * CREDIT_REFRESHINTERVAL_SEC; goto out; } @@ -496,14 +517,14 @@ refresh: if (cn->sourcetype == SOURCE_NONE || ( cn->sourcetype == SOURCE_SOCK && cn->reversedir->target.sock.credituser == 0)) - _refresh_conn_credits(cn->reversedir); - _refresh_conn_credits(cn); + _refresh_conn_credits(cn->reversedir, now); + _refresh_conn_credits(cn, now); if (cn->targettype == TARGET_UNCONNECTED || ( cn->targettype == TARGET_OUT && cn->target.out.conn_id == 0) || ( cn->targettype == TARGET_SOCK && cn->target.sock.credituser == 0)) - _refresh_conn_credits(cn->reversedir); + _refresh_conn_credits(cn->reversedir, now); out: if (likely(locked == 0)) @@ -531,7 +552,7 @@ void connreset_credits(struct conn *cn) if (cn->sourcetype == SOURCE_IN) { struct neighbor *nb = cn->source.in.nb; spin_lock_irqsave(&(nb->credits_lock), iflags); - refresh_credits_state(nb); + refresh_credits_state(nb, ktime_get()); nb->creditrate_earning = newnbrate(nb->creditrate_earning, cn->crate_in, 0); spin_unlock_irqrestore(&(nb->credits_lock), iflags); @@ -540,7 +561,7 @@ void connreset_credits(struct conn *cn) if (cn->targettype == TARGET_OUT) { struct neighbor *nb = cn->target.out.nb; spin_lock_irqsave(&(nb->credits_lock), iflags); - refresh_credits_state(nb); + refresh_credits_state(nb, ktime_get()); nb->creditrate_spending = newnbrate(nb->creditrate_spending, cn->crate_out, 0); spin_unlock_irqrestore(&(nb->credits_lock), iflags); diff --git a/net/cor/neighbor.c b/net/cor/neighbor.c index 7a866ee9d20..e33966d1451 100644 --- a/net/cor/neighbor.c +++ b/net/cor/neighbor.c @@ -131,14 +131,17 @@ static struct neighbor *alloc_neighbor(gfp_t allocflags) nb->cmsg_interval = 1000000; atomic_set(&(nb->ooo_packets), 0); spin_lock_init(&(nb->credits_lock)); - nb->jiffies_credit_update = nb->last_ping_time; - nb->jiffies_credit_decay = nb->last_ping_time; + nb->ktime_credit_update = ktime_get(); + nb->ktime_credit_decay = nb->ktime_credit_decay; spin_lock_init(&(nb->busytill_lock)); nb->busy_till = jiffies; atomic_set(&(nb->latency), 1000000); atomic_set(&(nb->max_remote_cmsg_delay), 1000000); spin_lock_init(&(nb->state_lock)); get_random_bytes((char *) &seqno, sizeof(seqno)); + spin_lock_init(&(nb->connid_reuse_lock)); + INIT_LIST_HEAD(&(nb->connid_reuse_list)); + nb->connid_reuse_pingcnt = 0; atomic_set(&(nb->kpacket_seqno), seqno); spin_lock_init(&(nb->conn_list_lock)); INIT_LIST_HEAD(&(nb->rcv_conn_list)); @@ -391,10 +394,11 @@ cont2: static void _refresh_initial_debitsrate(struct net_device *dev, __u32 debitsrate) { + ktime_t now; __u32 neighbors = 0; struct list_head *currlh; - currlh = nb_list.next; + currlh = nb_list.next; while (currlh != &nb_list) { struct neighbor *curr = container_of(currlh, struct neighbor, nb_list); @@ -405,15 +409,16 @@ static void _refresh_initial_debitsrate(struct net_device *dev, currlh = currlh->next; } - currlh = nb_list.next; + now = ktime_get(); + currlh = nb_list.next; while (currlh != &nb_list) { struct neighbor *curr = container_of(currlh, struct neighbor, nb_list); if (curr->dev == dev) set_creditrate_initial(curr, - debitsrate/neighbors); + debitsrate/neighbors, now); currlh = currlh->next; } diff --git a/net/cor/settings.h b/net/cor/settings.h index b469da1074b..6631723bb2d 100644 --- a/net/cor/settings.h +++ b/net/cor/settings.h @@ -43,6 +43,7 @@ /* time until half the credits are gone */ /* minimum == 2 h, otherwise int overflow when adding initial_credits */ #define CREDIT_DECAYTIME_HOURS 600 +#define CREDIT_EXCHANGETAX_PERMILLE 25 #define BUFFERASSIGN_INIT 4194304 #define BUFFERASSIGN_SPEED 2097152 -- 2.11.4.GIT