From 288aa13ed7fec7f17cea47aee82d54e298458ff5 Mon Sep 17 00:00:00 2001 From: Michael Blizek Date: Wed, 23 Feb 2011 07:55:57 +0100 Subject: [PATCH] credit system --- net/cor/common.c | 67 +++++ net/cor/cor.h | 174 ++++--------- net/cor/credits.c | 670 +++++++++++++++++++++++++++--------------------- net/cor/forward.c | 2 +- net/cor/kpacket_gen.c | 79 +----- net/cor/kpacket_parse.c | 27 +- net/cor/neighbor.c | 9 +- net/cor/settings.h | 4 +- net/cor/snd.c | 4 +- net/cor/sock.c | 5 +- 10 files changed, 518 insertions(+), 523 deletions(-) diff --git a/net/cor/common.c b/net/cor/common.c index 15ff97ba3bc..3a5babf4e88 100644 --- a/net/cor/common.c +++ b/net/cor/common.c @@ -116,6 +116,73 @@ __u32 dec_log_64_11(__u8 value) return log_64_11_table[value]; } +static inline __u64 mul_saturated(__u64 a, __u64 b) +{ + __u64 res = a*b; + if (unlikely(res / a != b)) + return -1; + return res; +} + +static inline int numdigits(__u64 value) +{ + int digits = 0; + for (;value != 0;value = (value >> 1)) { + digits++; + } + return digits; +} + +/* approximate (a*b) / c without overflowing a*b */ +__u64 multiply_div(__u64 a, __u64 b, __u64 c) +{ + 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; + + BUG_ON(c == 0); + + if (alen + blen <= 64) + return (a*b)/c; + + 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); + + 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; +} + static inline int hdr_size(void) { return ((sizeof(struct cell_hdr) + sizeof(void *) - 1) / sizeof(void *) diff --git a/net/cor/cor.h b/net/cor/cor.h index c17f4f24aa2..70d16453c0e 100644 --- a/net/cor/cor.h +++ b/net/cor/cor.h @@ -102,6 +102,8 @@ struct cor_sockaddr { * 0 = 0 * 1...255 = 64*2^((value-1)/11) end result is rounded down to an integer * + * 32* 2 ^ ((value-1)/8) + * */ #define KP_ACK_CONN 5 #define KP_ACK_CONN_OOO 6 @@ -164,14 +166,9 @@ struct cor_sockaddr { #define KP_SET_MAX_CMSG_DELAY 14 /* - * KP_SET_CREDITS[1] credits[8] rate_initial[4] rate_earning[4] rate_spending[4] - */ -#define KP_SET_CREDITS 15 - -/* * KP_SET_CONN_CREDITS[1] conn_id[4] credit_rate[4] */ -#define KP_SET_CONN_CREDITS 16 +#define KP_SET_CONN_CREDITS 15 /* @@ -273,6 +270,19 @@ struct cor_sockaddr { * CDR_EXEOK_BINDATA[1] bindatalen[1-4] bindata[bindatalen] */ #define CDR_BINDATA 3 +/** + * sending 2^32 credits per millisec means that credits the neighbor owns + * should be halfed after 1 minute + * + * ((x - 4294967295)/x) ^ 60000 = 0.5 + * (x-4294967295)/x = 0.5**(1/60000) + * x/x - 4294967295/x = 0.5**(1/60000) + * 1 - 0.5**(1/60000) = 4294967295/x + * x = 4294967295 / (1 - 0.5**(1/60000)) + */ +#define CREDITS_TOTAL 371781828609998LL + + /* result codes for rcv.c/proc_packet */ #define RC_DROP 0 @@ -356,7 +366,6 @@ struct neighbor{ atomic_t ucmcnt; /* size of queue only */ __u8 ping_all_conns; - __u8 send_credits; __u8 max_cmsg_delay_sent; /* see snd.c/qos_queue */ @@ -396,26 +405,16 @@ struct neighbor{ atomic_t ooo_packets; spinlock_t credits_lock; - long jiffies_credit_update; + unsigned long jiffies_credit_update; + unsigned long jiffies_credit_decay; - /* all cretid rates are in credits/ms */ - __u64 credits; /* how much we can spend */ + /* we only keep track on how much the other side may spend */ + __u64 credits; __u32 credits_fract; - __u64 credits_diff; /* diff between the neighbor's and our calc */ - __u32 credits_diff_fract; - __s32 creditrate_initial; - __u32 creditrate_earning; - __u32 creditrate_spending; - __u32 creditrate_spending_expected; - - __s32 creditrate_spending_diff; - - __u64 debits; /* how much the other side can spend */ - __u32 debits_fract; - __s32 debitrate_initial; - __s32 debitrate_initial_adj; - __u32 debitrate_earning; - __u32 debitrate_spending; + /* credit rates are in credits/ms */ + __u32 creditrate_initial; + __u64 creditrate_earning; + __u64 creditrate_spending; /* * connecions which receive data from/send data to this node @@ -556,26 +555,26 @@ struct conn{ /** * locking order: - * If one side is SOCK or NONE/UNCONNECTED and both directions - * need to be locked, the direction with TARGET_UNCONNECTED or - * TARGET_SOCK has to be locked first, the direction with - * SOURCE_NONE or SOURCE_SOCK afterwards. If one side is TARGET_SOCK - * and the other is TARGET_UNCONNECTED, TARGET_SOCK needs to be locked - * first. This is needed for changing source/targettype, credit flow - * and TARGET_UNCONNECTED generating responses. - * If data is forwarded, (both sides are IN/OUT), only one direction - * may be locked. + * 1) If both sides are SOCK, the side with source.sock.is_client == 1 + * has to be locked first. This is needed for credits. + * 2) If one side is NONE/UNCONNECTED and the direction with + * TARGET_UNCONNECTED has to be locked first This is needed for + * changing source/targettype, credit flow and TARGET_UNCONNECTED + * generating responses. + * 3) If one side is SOCK and the other is IN/OUT, TARGET_SOCK has to be + * locked first. + * 4) If data is forwarded, (both sides are IN/OUT), only one direction + * may be locked. */ struct mutex rcv_lock; unsigned long jiffies_credit_update; struct list_head credit_list; /* state */ - __s64 credits; - __u32 credits_fract; + __u64 credits; /* credit rates, locked by credit_lock (in credit.c) */ - __u32 sender_crate; - __u32 recp_crate; + __u64 crate_in; + __u32 crate_out; /* * This is how much we *want* to forward, but how much we actually do. * 2^32 == 100% @@ -598,7 +597,7 @@ struct conn{ atomic_t pong_awaiting; /* credit rate */ - __u32 crate_in_raw; + __u64 crate_in_raw; __u32 window_seqnolimit_max; __u32 window_seqnolimit_last; @@ -632,6 +631,7 @@ struct conn{ struct list_head alwait_list; __u8 in_alwait_list; __u8 delay_flush; + __u8 is_client; __u32 wait_len; }sock; }source; @@ -670,9 +670,9 @@ struct conn{ struct resume_block rb; - /* credit rate */ - long jiffies_crate_send; - __u32 crate_out_raw; + __u64 crate_out_raw; + __u64 crate_out_raw_remote; + __s64 crate_out_remotediff; }out; struct{ @@ -736,6 +736,8 @@ extern __u8 enc_log_64_11(__u32 window_bytes); extern __u32 dec_log_64_11(__u8 window); +extern __u64 multiply_div(__u64 a, __u64 b, __u64 c); + extern char *htable_get(struct htable *ht, __u32 key, void *searcheditem); extern int htable_delete(struct htable *ht, __u32 key, void *searcheditem, @@ -778,21 +780,14 @@ extern void reset_ping(struct conn *rconn); extern void reset_conn(struct conn *conn); /* credits.c */ -extern int refresh_credits_state(struct neighbor *nb); - -extern void check_credit_state(struct neighbor *nb); +extern __u32 creditrate_initial(void); -extern int debit_adj_needed(struct neighbor *nb); +extern int refresh_conn_credits(struct conn *conn, int fromperiodic, + int locked); -extern int refresh_conn_credits(struct conn *conn, int fromperiodic); +extern void set_creditrate_initial(struct neighbor *nb, __u32 debitrate); -extern void set_credits(struct neighbor *nb, __u64 credits, - __s32 creditrate_initial, __u32 creditrate_earning, - __u32 creditrate_spending); - -extern void set_debitrate_initial(struct neighbor *nb, __u32 debitrate); - -extern void set_conn_in_crate(struct conn *rconn, __u32 crate_in); +extern void set_conn_in_crate(struct conn *rconn, __u64 crate_in); extern void connreset_credits(struct conn *conn); @@ -897,7 +892,8 @@ extern void send_connid_unknown(struct control_msg_out *cm, __u32 conn_id); extern void send_ping_all_conns(struct neighbor *nb); -extern void send_credits(struct neighbor *nb); +extern void set_creditrate_out(struct control_msg_out *cm, __u32 conn_id, + __u32 creditrate); extern void cor_kgen_init(void); @@ -1057,70 +1053,6 @@ static inline char *cor_pull_skb(struct sk_buff *skb, unsigned int len) return ptr - len; } +#define S64_MAX 9223372036854775807LL +#define S64_MIN (1LL << 63) -static inline __u64 mul_saturated(__u64 a, __u64 b) -{ - __u64 res = a*b; - if (res / a != b) - return -1; - return res; -} - -static inline int numdigits(__u64 value) -{ - int digits = 0; - for (;value != 0;value = (value >> 1)) { - digits++; - } - return digits; -} - -/* approximate (a*b) / c without overflowing a*b */ -static inline __u64 multiply_div(__u64 a, __u64 b, __u64 c) -{ - 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; - - BUG_ON(c == 0); - - if (alen + blen <= 64) - return (a*b)/c; - - 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); - - 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; -} diff --git a/net/cor/credits.c b/net/cor/credits.c index 9069b9f8f85..c5b8fd65177 100644 --- a/net/cor/credits.c +++ b/net/cor/credits.c @@ -25,210 +25,116 @@ LIST_HEAD(credit_refresh_conns); static struct delayed_work credit_refresh_work; static int refresh_running = 0; -/* credit_lock must be held while calling this */ -int refresh_credits_state(struct neighbor *nb) +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; + if (unlikely(decay_rate == 0)) + return 0; + return multiply_div(credits, decay_rate - 1, decay_rate); +} + +__u32 creditrate_initial(void) { - long jiffies_tmp = jiffies; + __u64 rate = (CREDITS_TOTAL - decay_credits(CREDITS_TOTAL)) / 3600000; + if (unlikely((rate >> 32) > 0)) + return -1; + return rate; +} - __s64 creditrate = 1000 * ((__s64)(nb->creditrate_initial + - nb->creditrate_earning - nb->creditrate_spending)); +/* credit_lock must be held while calling this */ +static void refresh_credits_state(struct neighbor *nb) +{ + unsigned long jiffies_tmp = jiffies; - __s64 crediterrorrate = 1000 * ((__s64)(nb->creditrate_spending - - nb->creditrate_spending_expected)) - - /** - * tolerance is 50% of creditsrate_initial + 2.5% of - * both spending+earning - */ - 500 * ((__s64)(nb->creditrate_initial)) - - 25 * ((__s64)(nb->creditrate_spending_expected)) - - 25 * ((__s64)(nb->creditrate_earning)); + __s64 creditrate; + __s64 credits_adj; - __s64 debitrate = 1000 * ((__s64)(nb->debitrate_initial + - nb->debitrate_initial_adj + nb->debitrate_earning - - nb->debitrate_spending)); + if (jiffies_tmp == nb->jiffies_credit_update) + return; + if (unlikely(nb->creditrate_earning >= (1LL << 63))) + creditrate = S64_MAX; + else + creditrate = nb->creditrate_earning; - __s64 credits_adj = jiffies_to_msecs(jiffies_tmp - - nb->jiffies_credit_update) * creditrate + - nb->credits_fract; + if (unlikely(creditrate - nb->creditrate_spending > creditrate)) + creditrate = S64_MIN; + else + creditrate -= nb->creditrate_spending; - __s64 creditsd_adj = jiffies_to_msecs(jiffies_tmp - - nb->jiffies_credit_update) * crediterrorrate + - nb->credits_diff_fract; + if (unlikely(creditrate + nb->creditrate_initial < creditrate)) + creditrate = S64_MAX; + else + creditrate += nb->creditrate_initial; - __s64 debits_adj = jiffies_to_msecs(jiffies_tmp - - nb->jiffies_credit_update) * debitrate + - nb->debits_fract; + creditrate = mul_saturated_signed(creditrate, 1000); - nb->jiffies_credit_update += msecs_to_jiffies(jiffies_to_msecs( + credits_adj = mul_saturated_signed(creditrate, jiffies_to_msecs( jiffies_tmp - nb->jiffies_credit_update)); + if (unlikely(credits_adj + nb->credits_fract < credits_adj)) { + credits_adj = S64_MAX; + } else { + credits_adj += nb->credits_fract; + } - if (unlikely(credits_adj < 0 && (nb->credits < -(credits_adj/HZ)))) { + 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(creditsd_adj < 0 && (nb->credits_diff < - -(creditsd_adj/HZ)))) { - nb->credits_diff = 0; - nb->credits_diff_fract = 0; - } else { - nb->credits_diff += creditsd_adj / HZ; - nb->credits_diff_fract = creditsd_adj % HZ; - } + nb->jiffies_credit_update = jiffies_tmp; - if (unlikely(debits_adj < 0 && (nb->debits < -(debits_adj/HZ)))) { - nb->debits = 0; - nb->debits_fract = 0; + if (unlikely(time_after(nb->jiffies_credit_decay + 3600*HZ, + jiffies_tmp))) { + nb->credits = decay_credits(nb->credits); - return 1; - } else { - nb->debits += debits_adj / HZ; - nb->debits_fract = debits_adj % HZ; + 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; } - - return 0; -} - -void check_credit_state(struct neighbor *nb) -{ - unsigned long iflags; - int resetconns; - int sendcredits = 0; - struct list_head *currlh; - -start: - spin_lock_irqsave( &(nb->credits_lock), iflags ); - refresh_credits_state(nb); - resetconns = (nb->debits == 0 && (( - (__s64) nb->debitrate_initial_adj + - (__s64) nb->debitrate_earning - - (__s64) nb->debitrate_spending) < 0)); - spin_unlock_irqrestore( &(nb->credits_lock), iflags ); - - if (likely(resetconns == 0)) { - if (unlikely(sendcredits)) - send_credits(nb); - return; - } else { - sendcredits = 1; - } - - mutex_lock(&(nb->conn_list_lock)); - BUG_ON(list_empty(&(nb->snd_conn_list)) && nb->num_send_conns != 0); - currlh = nb->snd_conn_list.next; - - while (currlh != &(nb->snd_conn_list)) { - int ispaying; - struct conn *sconn = container_of(currlh, struct conn, - target.out.nb_list); - struct conn *rconn = sconn->reversedir; - - mutex_lock(&(rconn->rcv_lock)); - BUG_ON(sconn->targettype != TARGET_OUT); - BUG_ON(rconn->sourcetype != SOURCE_IN); - - if (rconn->targettype == TARGET_UNCONNECTED || - (rconn->targettype == TARGET_SOCK && - rconn->target.sock.credituser != 0)) - ispaying = 1; - else - ispaying = (sconn->recp_crate > rconn->sender_crate); - - mutex_unlock(&(rconn->rcv_lock)); - - if (ispaying) { - /** - * reset_conn must not be called with conn_list_lock - * held - */ - mutex_unlock(&(nb->conn_list_lock)); - reset_conn(rconn); - goto start; - } - currlh = currlh->next; - } - - BUG(); -} - -int debit_adj_needed(struct neighbor *nb) -{ - int rc = 0; - unsigned long iflags; - __s32 expected_adj; - spin_lock_irqsave( &(nb->credits_lock), iflags ); - - refresh_credits_state(nb); - - expected_adj = nb->creditrate_initial - nb->credits_diff/10000; - if (unlikely((expected_adj < 0 || nb->debitrate_initial_adj < 0) && - ( (expected_adj * 2 < nb->debitrate_initial_adj) || - (expected_adj > nb->debitrate_initial_adj * 2) ))) { - nb->debitrate_initial_adj = (nb->debitrate_initial_adj * 15 + - expected_adj) / 16; - rc = 1; - } - - spin_unlock_irqrestore( &(nb->credits_lock), iflags ); - - return rc; } -void set_credits(struct neighbor *nb, __u64 credits, __s32 creditrate_initial, - __u32 creditrate_earning, __u32 creditrate_spending) +void set_creditrate_initial(struct neighbor *nb, __u32 creditrate) { unsigned long iflags; spin_lock_irqsave( &(nb->credits_lock), iflags ); - refresh_credits_state(nb); - - if (nb->credits_diff + nb->credits < credits) - nb->credits_diff = 0; - else - nb->credits_diff += nb->credits - credits; - nb->credits = credits; - nb->creditrate_initial = creditrate_initial; - nb->creditrate_earning = creditrate_earning; - nb->creditrate_spending = creditrate_spending; - + nb->creditrate_initial = creditrate; spin_unlock_irqrestore( &(nb->credits_lock), iflags ); } -void set_debitrate_initial(struct neighbor *nb, __u32 debitrate) +static __u64 credit_exchange_in(struct neighbor *nb, __u64 crate_in_raw) { - unsigned long iflags; - - spin_lock_irqsave( &(nb->credits_lock), iflags ); - - refresh_credits_state(nb); - nb->debitrate_initial = debitrate; - - spin_unlock_irqrestore( &(nb->credits_lock), iflags ); - - send_credits(nb); + return multiply_div(crate_in_raw, nb->credits, CREDITS_TOTAL); } -static __u32 credit_exchange_in(struct neighbor *nb, __u32 crate_in_raw) +static __u64 credit_exchange_out(struct neighbor *nb, __u64 crate_out) { - unsigned long iflags; - __u64 ret; - spin_lock_irqsave( &(nb->credits_lock), iflags ); - if (unlikely(nb->debits == 0)) - ret = crate_in_raw; - else - ret = multiply_div(nb->credits, crate_in_raw, nb->debits); - spin_unlock_irqrestore( &(nb->credits_lock), iflags ); - - if ((ret >> 32) != 0) - return -1; - return (__u32) ret; + return multiply_div(crate_out, CREDITS_TOTAL, nb->credits); } static void refresh_crate_forward(struct conn *conn, long jiffies_diff) @@ -248,7 +154,10 @@ static void refresh_crate_forward(struct conn *conn, long jiffies_diff) else BUG(); - /* buffer full shifts 1 bit more so that */ + /** + * buffer full shifts 1 bit more so only about 1/3rd there is no + * bufferspace left + */ BUG_ON(conn->crate_forward > (1 << 31)); @@ -272,100 +181,215 @@ static void refresh_crate_forward(struct conn *conn, long jiffies_diff) break; } } + + conn->crate_out = multiply_div(conn->crate_in, conn->crate_forward, + 1 << 31); } -static int get_crate_forward_grace_period(struct conn *conn) +static void send_crates_ifneeded(struct conn *conn) { + struct control_msg_out *cm; + + int send = 0; + + int grace; if (conn->tos == TOS_NORMAL) - return HZ * 2; - if (conn->tos == TOS_LATENCY) - return HZ; - if (conn->tos == TOS_THROUGHPUT) - return HZ * 5; - if (conn->tos == TOS_PRIVACY) - return HZ * 10; - - BUG(); + grace = HZ * 2; + else if (conn->tos == TOS_LATENCY) + grace = HZ; + else if (conn->tos == TOS_THROUGHPUT) + grace = HZ * 2; + else if (conn->tos == TOS_PRIVACY) + grace = HZ * 5; + else + BUG(); + + if (conn->target.out.crate_out_raw > + conn->target.out.crate_out_raw_remote && + conn->target.out.crate_out_remotediff > + conn->target.out.crate_out_raw * grace) + send = 1; + if (conn->target.out.crate_out_raw < + conn->target.out.crate_out_raw_remote && + conn->target.out.crate_out_remotediff < + (0 - conn->target.out.crate_out_raw * grace)) + send = -1; + + if (send == 0) + return; + + cm = alloc_control_msg(conn->target.out.nb, ACM_PRIORITY_MED); + + if (cm == 0) + return; + + conn->target.out.crate_out_raw_remote = conn->target.out.crate_out_raw; + + set_creditrate_out(cm, conn->target.out.conn_id, + conn->target.out.crate_out_raw_remote); } -static void refresh_conn_crates(struct conn *conn, long jiffies_diff) +static __u64 newnbrate(__u64 nbrate, __u64 oldconnrate, __u64 newconnrate) { - /* set conn->sender_crate */ + if (unlikely(nbrate < oldconnrate)) + nbrate = 0; + else + nbrate -= oldconnrate; + + if (unlikely(nbrate + newconnrate < nbrate)) + nbrate = -1; + else + nbrate += newconnrate; + + return nbrate; +} + +static void refresh_conn_crate_out(struct conn *conn, + unsigned long jiffies_diff) +{ + unsigned long iflags; + + __u64 oldrate = conn->crate_out; + + refresh_crate_forward(conn, jiffies_diff); + + if (((__s32) (conn->target.out.seqno_nextsend - + conn->target.out.seqno_windowlimit )) <= 0) + conn->last_bufferstate = 1; + else + conn->last_bufferstate = 0; + + + spin_lock_irqsave( &(conn->target.out.nb->credits_lock), iflags ); + + refresh_credits_state(conn->target.out.nb); + conn->target.out.nb->creditrate_spending = newnbrate( + conn->target.out.nb->creditrate_spending, oldrate, + conn->crate_out); + + + conn->target.out.crate_out_raw = credit_exchange_out( + conn->target.out.nb, conn->crate_out); + + spin_unlock_irqrestore( &(conn->target.out.nb->credits_lock), iflags ); + + send_crates_ifneeded(conn); +} + +static void refresh_conn_crate_in(struct conn *conn) +{ + unsigned long iflags; + + __u64 oldrate = conn->crate_in; + + spin_lock_irqsave( &(conn->source.in.nb->credits_lock), iflags ); + + refresh_credits_state(conn->source.in.nb); + + conn->crate_in = credit_exchange_in(conn->source.in.nb, + conn->source.in.crate_in_raw); + conn->source.in.nb->creditrate_earning = newnbrate( + conn->source.in.nb->creditrate_earning, oldrate, + conn->crate_in); + + spin_unlock_irqrestore( &(conn->source.in.nb->credits_lock), iflags ); +} + +static void refresh_conn_crates(struct conn *conn, unsigned long jiffies_tmp, + unsigned long jiffies_diff) +{ + /* set conn->crate_in */ if (conn->sourcetype == SOURCE_NONE) { - conn->sender_crate = conn->reversedir->recp_crate; + conn->crate_in = conn->reversedir->crate_out; } else if (conn->sourcetype == SOURCE_IN) { - conn->sender_crate = credit_exchange_in(conn->source.in.nb, - conn->source.in.crate_in_raw); + refresh_conn_crate_in(conn); } else if (conn->sourcetype == SOURCE_SOCK) { - BUG_ON(conn->reversedir->target.sock.credituser == 0 && - conn->targettype == TARGET_SOCK && - conn->reversedir->recp_crate != 0); - - if ((conn->source.sock.crate + conn->reversedir->recp_crate) < - conn->reversedir->recp_crate || ( - conn->reversedir->recp_crate + - conn->source.sock.crate) > MAX_CREDITRATE_SOCK) - conn->sender_crate = MAX_CREDITRATE_SOCK; + if (conn->reversedir->target.sock.credituser == 1) + conn->crate_in = conn->reversedir->crate_out; + else if ((conn->source.sock.crate + + conn->reversedir->crate_out) < + conn->reversedir->crate_out) + conn->crate_in = -1; else - conn->sender_crate = conn->reversedir->recp_crate + + conn->crate_in = conn->reversedir->crate_out + conn->source.sock.crate; } else { BUG(); } - /* set conn->crate_forward + conn->recp_crate */ + /* set conn->crate_forward + conn->crate_out */ if (conn->targettype == TARGET_UNCONNECTED) { - conn->recp_crate = conn->sender_crate; - conn->reversedir->sender_crate = conn->recp_crate; + conn->crate_out = conn->crate_in; } else if (conn->targettype == TARGET_SOCK) { if (conn->target.sock.credituser == 0) { - conn->recp_crate = conn->sender_crate; + conn->crate_out = conn->crate_in; } else { refresh_crate_forward(conn, jiffies_diff); - conn->recp_crate = (((__u64) conn->sender_crate) * - conn->crate_forward) / (1 << 31); - } - conn->reversedir->sender_crate = conn->recp_crate + - conn->reversedir->source.sock.crate; - if ((conn->reversedir->source.sock.crate + conn->recp_crate) < - conn->recp_crate || (conn->recp_crate + - conn->reversedir->source.sock.crate) > - MAX_CREDITRATE_SOCK) { - conn->reversedir->sender_crate = MAX_CREDITRATE_SOCK; - conn->recp_crate = MAX_CREDITRATE_SOCK - - conn->reversedir->source.sock.crate; - } - conn->last_bufferstate = (conn->reversedir->source.sock.wait_len + conn->last_bufferstate = ( + conn->reversedir->source.sock.wait_len != 0); - } else if (conn->targettype == TARGET_OUT) { - int grace = get_crate_forward_grace_period(conn); - refresh_crate_forward(conn, jiffies_diff); - - if (((__s32) (conn->target.out.seqno_nextsend - - conn->target.out.seqno_windowlimit )) <= 0) - conn->last_bufferstate = 1; - else - conn->last_bufferstate = 0; - - #warning todo set creditrate_spending_expected, crate_out_raw - - if (conn->target.out.jiffies_crate_send + grace > - conn->jiffies_credit_update + jiffies_diff) { - #warning todo send credits } + } else if (conn->targettype == TARGET_OUT) { + refresh_conn_crate_out(conn, jiffies_diff); } else { BUG(); } } -static void _refresh_conn_credits(struct conn *conn, long jiffies_diff) +static void _refresh_conn_credits(struct conn *conn) { - __s64 diff = 1000 * ((__s64) conn->sender_crate - - (__s64) conn->recp_crate) * jiffies_diff + - conn->credits_fract; + unsigned long jiffies_tmp = jiffies; + unsigned long jiffies_diff = jiffies_tmp - conn->jiffies_credit_update; + + if (jiffies_diff == 0) + goto crates; - conn->credits += diff / HZ; - conn->credits_fract = diff % HZ; + if (unlikely(conn->crate_out > conn->crate_in)) { + __u64 diff = conn->crate_out - conn->crate_in; + if (unlikely((diff * jiffies_diff) / jiffies_diff != diff)) + diff = -1; + else + diff *= jiffies_diff; + + if (unlikely(conn->credits - diff > conn->credits)) + conn->credits = 0; + else + conn->credits -= diff; + } else { + __u64 diff = conn->crate_in - conn->crate_out; + if (unlikely((diff * jiffies_diff) / jiffies_diff != diff)) + diff = -1; + else + diff *= jiffies_diff; + + if (unlikely(conn->credits + diff < conn->credits)) + conn->credits = -1; + else + conn->credits += diff; + } + + if (conn->targettype == TARGET_OUT) { + __s64 diff = conn->target.out.crate_out_raw - + conn->target.out.crate_out_raw_remote; + if (conn->target.out.crate_out_raw > + conn->target.out.crate_out_raw_remote && + diff + conn->target.out.crate_out_remotediff < + conn->target.out.crate_out_remotediff) + conn->target.out.crate_out_remotediff = S64_MAX; + else if (conn->target.out.crate_out_raw > + conn->target.out.crate_out_raw_remote && + diff + conn->target.out.crate_out_remotediff > + conn->target.out.crate_out_remotediff) + conn->target.out.crate_out_remotediff = S64_MIN; + else + conn->target.out.crate_out_remotediff += diff; + } + +crates: + refresh_conn_crates(conn, jiffies_tmp, + jiffies_tmp - conn->jiffies_credit_update); + + conn->jiffies_credit_update = jiffies_tmp; } /** @@ -376,14 +400,37 @@ static __u32 credits_lock_conn(struct conn *conn) { __u32 rc = 1; mutex_lock(&(conn->rcv_lock)); - if (conn->sourcetype != SOURCE_IN) { + if (conn->sourcetype == SOURCE_SOCK && + conn->targettype == TARGET_SOCK) { + if (conn->source.sock.is_client == 1) { + mutex_lock(&(conn->reversedir->rcv_lock)); + + BUG_ON(conn->reversedir->source.sock.is_client == 1); + + rc = 3; + } else { + mutex_unlock(&(conn->rcv_lock)); + + mutex_lock(&(conn->reversedir->rcv_lock)); + mutex_lock(&(conn->rcv_lock)); + + BUG_ON(conn->reversedir->source.sock.is_client != 1); + + rc = 6; + } + } else if (conn->targettype == TARGET_UNCONNECTED) { + mutex_lock(&(conn->reversedir->rcv_lock)); + + rc = 3; + } else if (conn->sourcetype == SOURCE_NONE || + conn->sourcetype == SOURCE_SOCK) { mutex_unlock(&(conn->rcv_lock)); mutex_lock(&(conn->reversedir->rcv_lock)); mutex_lock(&(conn->rcv_lock)); rc = 6; - } else if (conn->targettype != TARGET_OUT) { + } else if (conn->targettype == TARGET_SOCK) { mutex_lock(&(conn->reversedir->rcv_lock)); rc = 3; @@ -401,21 +448,49 @@ static void credits_unlock_conn(struct conn *conn, __u32 hints) mutex_unlock(&(conn->rcv_lock)); } -int refresh_conn_credits(struct conn *conn, int fromperiodic) +int refresh_conn_credits(struct conn *conn, int fromperiodic, int locked) { unsigned long iflags; - unsigned long jiffies_tmp; - __u32 unlockhints = credits_lock_conn(conn); + __u32 unlockhints = 0; int rc = 0; int put = 0; - if (atomic_read(&(conn->isreset)) != 0) + if (likely(locked == 0)) + unlockhints = credits_lock_conn(conn); + + if (atomic_read(&(conn->isreset)) != 0) { + if (fromperiodic) + rc = 1; goto out; + } - if (unlikely(conn->targettype == TARGET_SOCK && - conn->reversedir->targettype == TARGET_SOCK && - conn->target.sock.credituser == 0 && - conn->reversedir->target.sock.credituser == 0)) { + if (fromperiodic) { + /* quit if not time for refresh yet */ + unsigned long jiffies_tmp = jiffies; + if (time_after(conn->jiffies_credit_update + + HZ*CREDIT_REFRESHINTERVAL_SEC, jiffies_tmp)) { + int alreadyrefreshed; + + spin_lock_irqsave(&credits_list_lock, iflags); + alreadyrefreshed = &(conn->credit_list) != + credit_refresh_conns.next; + spin_unlock_irqrestore(&credits_list_lock, iflags ); + + if (unlikely(alreadyrefreshed)) + goto out; + + rc = conn->jiffies_credit_update - jiffies_tmp; + if (rc < HZ) + rc = HZ; + if (rc > HZ * CREDIT_REFRESHINTERVAL_SEC) + rc = HZ * CREDIT_REFRESHINTERVAL_SEC; + goto out; + } + } + + if (conn->targettype == TARGET_UNCONNECTED || ( + conn->targettype == TARGET_SOCK && + conn->target.sock.credituser == 0)) { if (unlikely(conn->in_credit_list)) { spin_lock_irqsave(&credits_list_lock, iflags); list_del(&(conn->credit_list)); @@ -423,33 +498,17 @@ int refresh_conn_credits(struct conn *conn, int fromperiodic) spin_unlock_irqrestore(&credits_list_lock, iflags ); put = 1; } - goto out; - } - spin_lock_irqsave(&credits_list_lock, iflags); + if (conn->sourcetype == SOURCE_NONE || ( + conn->sourcetype == SOURCE_SOCK && + conn->reversedir->target.sock.credituser == 0)) + goto out; - if (fromperiodic) { - if (unlikely(&(conn->credit_list) != credit_refresh_conns.next)) - goto out1; - jiffies_tmp = jiffies; - if (time_after(conn->jiffies_credit_update + - HZ*CREDIT_REFRESHINTERVAL_SEC, jiffies_tmp)) { - if (unlikely(conn->jiffies_credit_update - jiffies_tmp > - HZ * CREDIT_REFRESHINTERVAL_SEC)) { - /** - * catch wrap around if refresh is no executed - * for a long time - */ - rc = HZ * CREDIT_REFRESHINTERVAL_SEC; - } else { - rc = conn->jiffies_credit_update - jiffies_tmp; - if (rc < HZ) - rc = HZ; - } - goto out1; - } + goto refresh; } + spin_lock_irqsave(&credits_list_lock, iflags); + if (unlikely(conn->in_credit_list == 0)) { conn->in_credit_list = 1; kref_get(&(conn->ref)); @@ -463,38 +522,71 @@ int refresh_conn_credits(struct conn *conn, int fromperiodic) } list_add_tail(&(conn->credit_list), &credit_refresh_conns); - spin_unlock_irqrestore(&credits_list_lock, iflags ); - jiffies_tmp = jiffies; - _refresh_conn_credits(conn, jiffies_tmp - conn->jiffies_credit_update); - refresh_conn_crates(conn, jiffies_tmp - conn->jiffies_credit_update); - conn->jiffies_credit_update = jiffies_tmp; + spin_unlock_irqrestore(&credits_list_lock, iflags ); - if (0) { -out1: - spin_unlock_irqrestore(&credits_list_lock, iflags ); - } +refresh: + if (conn->sourcetype == SOURCE_NONE || ( + conn->sourcetype == SOURCE_SOCK && + conn->reversedir->target.sock.credituser == 0)) + _refresh_conn_credits(conn->reversedir); + _refresh_conn_credits(conn); + if (conn->targettype == TARGET_UNCONNECTED || ( + conn->targettype == TARGET_SOCK && + conn->target.sock.credituser == 0)) + _refresh_conn_credits(conn->reversedir); out: - credits_unlock_conn(conn, unlockhints); + if (likely(locked == 0)) + credits_unlock_conn(conn, unlockhints); + if (put) kref_put(&(conn->ref), free_conn); + return rc; } -void set_conn_in_crate(struct conn *rconn, __u32 crate_in) +void connreset_credits(struct conn *conn) { - long jiffies_tmp; + unsigned long iflags; + + __u32 unlockhints = credits_lock_conn(conn); + if (conn->in_credit_list) { + spin_lock_irqsave(&credits_list_lock, iflags); + list_del(&(conn->credit_list)); + conn->in_credit_list = 0; + spin_unlock_irqrestore(&credits_list_lock, iflags); + kref_put(&(conn->ref), free_conn); + } + if (conn->sourcetype == SOURCE_IN) { + struct neighbor *nb = conn->source.in.nb; + spin_lock_irqsave( &(nb->credits_lock), iflags); + refresh_credits_state(nb); + nb->creditrate_earning = newnbrate(nb->creditrate_earning, + conn->crate_in, 0); + spin_unlock_irqrestore( &(nb->credits_lock), iflags ); + } + + if (conn->targettype == TARGET_OUT) { + struct neighbor *nb = conn->target.out.nb; + spin_lock_irqsave( &(nb->credits_lock), iflags); + refresh_credits_state(nb); + nb->creditrate_spending = newnbrate(nb->creditrate_spending, + conn->crate_out, 0); + spin_unlock_irqrestore( &(nb->credits_lock), iflags ); + } + credits_unlock_conn(conn, unlockhints); +} + +void set_conn_in_crate(struct conn *rconn, __u64 crate_in) +{ __u32 unlockhints = credits_lock_conn(rconn); BUG_ON(rconn->sourcetype != SOURCE_IN); - jiffies_tmp = jiffies; - _refresh_conn_credits(rconn, jiffies_tmp-rconn->jiffies_credit_update); rconn->source.in.crate_in_raw = crate_in; - refresh_conn_crates(rconn, jiffies_tmp - rconn->jiffies_credit_update); - rconn->jiffies_credit_update = jiffies_tmp; + refresh_conn_credits(rconn, 0, 1); credits_unlock_conn(rconn, unlockhints); } @@ -518,7 +610,7 @@ static void background_refresh_credits(struct work_struct *work) spin_unlock_irqrestore(&credits_list_lock, iflags); if (conn != 0) - rc = refresh_conn_credits(conn, 1); + rc = refresh_conn_credits(conn, 1, 0); } if (likely(rc > 0)) { @@ -526,20 +618,6 @@ static void background_refresh_credits(struct work_struct *work) } } -void connreset_credits(struct conn *conn) -{ - __u32 unlockhints = credits_lock_conn(conn); - if (conn->in_credit_list) { - unsigned long iflags; - spin_lock_irqsave(&credits_list_lock, iflags); - list_del(&(conn->credit_list)); - conn->in_credit_list = 0; - spin_unlock_irqrestore(&credits_list_lock, iflags); - kref_put(&(conn->ref), free_conn); - } - credits_unlock_conn(conn, unlockhints); -} - void credits_init(void) { INIT_DELAYED_WORK(&credit_refresh_work, background_refresh_credits); diff --git a/net/cor/forward.c b/net/cor/forward.c index ee83e814ecf..41e0f047351 100644 --- a/net/cor/forward.c +++ b/net/cor/forward.c @@ -418,7 +418,7 @@ void flush_buf(struct conn *rconn) BUG(); } - refresh_conn_credits(rconn, 0); + refresh_conn_credits(rconn, 0, 0); unreserve_sock_buffer(rconn); if (rc == RC_FLUSH_CONN_OUT_CONG) { diff --git a/net/cor/kpacket_gen.c b/net/cor/kpacket_gen.c index fc3f67951a3..ed161f86c83 100644 --- a/net/cor/kpacket_gen.c +++ b/net/cor/kpacket_gen.c @@ -35,7 +35,6 @@ #define MSGTYPE_CONNID_UNKNOWN 10 #define MSGTYPE_PING_ALL_CONNS 11 #define MSGTYPE_SET_MAX_CMSG_DELAY 12 -#define MSGTYPE_SET_CREDITS 13 struct control_msg_out{ struct list_head lh; /* either neighbor or control_retrans_packet */ @@ -715,37 +714,6 @@ static int add_set_max_cmsg_dly(struct sk_buff *skb, struct control_retrans *cr, return 5; } -static int add_credits(struct sk_buff *skb, struct control_retrans *cr, - struct control_msg_out *cm, int spaceleft) -{ - unsigned long iflags; - char *dst; - - if (unlikely(spaceleft < 21)) - return 0; - - dst = skb_put(skb, 21); - BUG_ON(dst == 0); - - dst[0] = KP_SET_CREDITS; - - spin_lock_irqsave( &(cm->nb->credits_lock), iflags ); - - refresh_credits_state(cm->nb); - - put_u64(dst + 1, cm->nb->debits, 1); - put_u32(dst + 9, cm->nb->debitrate_initial + - cm->nb->debitrate_initial_adj, 1); - put_u32(dst + 13, cm->nb->debitrate_earning, 1); - put_u32(dst + 17, cm->nb->debitrate_spending, 1); - - spin_unlock_irqrestore( &(cm->nb->credits_lock), iflags ); - - list_add_tail(&(cm->lh), &(cr->msgs)); - - return 21; -} - static int add_message(struct sk_buff *skb, struct control_retrans *cr, struct control_msg_out *cm, int spaceleft, struct control_msg_out **split_conndata, __u32 *sc_sendlen) @@ -779,8 +747,6 @@ static int add_message(struct sk_buff *skb, struct control_retrans *cr, return add_ping_all_conns(skb, cr, cm, spaceleft); case MSGTYPE_SET_MAX_CMSG_DELAY: return add_set_max_cmsg_dly(skb, cr, cm, spaceleft); - case MSGTYPE_SET_CREDITS: - return add_credits(skb, cr, cm, spaceleft); default: BUG(); } @@ -938,26 +904,6 @@ static int ping_all_conns_needed(struct neighbor *nb) return 1; } -static int __send_messages_cred(struct neighbor *nb, struct sk_buff *skb, - struct control_retrans *cr, int spaceleft) -{ - struct control_msg_out *cm; - int rc; - - cm = alloc_control_msg(nb, ACM_PRIORITY_MED); - - if (unlikely(cm == 0)) - return 0; - - cm->type = MSGTYPE_SET_CREDITS; - cm->length = 21; - - rc = add_message(skb, cr, cm, spaceleft, 0, 0); - - nb->send_credits = 0; - return rc; -} - static int __send_messages_smcd(struct neighbor *nb, struct sk_buff *skb, struct control_retrans *cr, int spaceleft) { @@ -1026,10 +972,6 @@ static int _send_messages(struct neighbor *nb, struct sk_buff *skb, int ping, if (likely(urgentonly == 0) && unlikely(nb->max_cmsg_delay_sent == 0)) length += __send_messages_smcd(nb, skb, cr, spaceleft - length); - if (likely(urgentonly == 0) && unlikely(nb->send_credits != 0) && - msgtype_present(nb, MSGTYPE_SET_CREDITS) == 0) - length += __send_messages_cred(nb, skb, cr, spaceleft - length); - length += __send_messages(nb, skb, cr, spaceleft - length, urgentonly, &split_conndata, &sc_sendlen); @@ -1107,8 +1049,6 @@ static __u32 get_total_messages_length(struct neighbor *nb, int ping, int urgentonly) { __u32 length = nb->ucmlength; - if (likely(nb->send_credits == 0) && unlikely(debit_adj_needed(nb))) - nb->send_credits = 1; if (likely(urgentonly == 0)) { length += nb->cmlength + nb->ping_conns_remaining * 5; @@ -1136,16 +1076,9 @@ static __u32 get_total_messages_length(struct neighbor *nb, int ping, length += 1; if (unlikely(nb->max_cmsg_delay_sent == 0)) length += 5; - if (unlikely(nb->send_credits == 2) && - msgtype_present(nb, MSGTYPE_SET_CREDITS) == 0) - length += 21; } if (ping == 2 || (length > 0 && ping != 0)) length += 5; - if (likely(urgentonly == 0) && length > 0 && - unlikely(nb->send_credits == 1) && - msgtype_present(nb, MSGTYPE_SET_CREDITS) == 0) - length += 21; return length; } @@ -1159,8 +1092,6 @@ int send_messages(struct neighbor *nb, int allmsgs, int resume) int nbstate = get_neigh_state(nb); int urgentonly = (nbstate != NEIGHBOR_STATE_ACTIVE); - check_credit_state(nb); - mutex_lock(&(nb->cmsg_lock)); if (resume) @@ -1493,13 +1424,15 @@ void send_ping_all_conns(struct neighbor *nb) mutex_unlock(&(nb->cmsg_lock)); } -void send_credits(struct neighbor *nb) +/* 8*2**(x/5.5) */ +void set_creditrate_out(struct control_msg_out *cm, __u32 conn_id, + __u32 creditrate) { - mutex_lock(&(nb->cmsg_lock)); - nb->send_credits = 2; - mutex_unlock(&(nb->cmsg_lock)); + free_control_msg(cm); + #warning todo } + static int matches_connretrans(void *htentry, void *searcheditem) { struct control_retrans *cr = (struct control_retrans *) htentry; diff --git a/net/cor/kpacket_parse.c b/net/cor/kpacket_parse.c index aab93d543d9..9b62e593879 100644 --- a/net/cor/kpacket_parse.c +++ b/net/cor/kpacket_parse.c @@ -22,7 +22,7 @@ #include "cor.h" -static __u64 pull_u64(struct sk_buff *skb, int convbo) +/*static __u64 pull_u64(struct sk_buff *skb, int convbo) { char *ptr = cor_pull_skb(skb, 8); @@ -42,7 +42,7 @@ static __u64 pull_u64(struct sk_buff *skb, int convbo) if (convbo) return be64_to_cpu(ret); return ret; -} +}*/ static __u32 pull_u32(struct sk_buff *skb, int convbo) { @@ -327,8 +327,8 @@ static void parse_connect(struct neighbor *nb, struct sk_buff *skb) mutex_unlock(&(rconn->reversedir->rcv_lock)); - refresh_conn_credits(rconn, 0); - refresh_conn_credits(rconn->reversedir, 0); + refresh_conn_credits(rconn, 0, 0); + refresh_conn_credits(rconn->reversedir, 0, 0); if (0) { err1: @@ -340,17 +340,6 @@ err: } } -static void parse_set_credits(struct neighbor *nb, struct sk_buff *skb) -{ - __u64 credits = pull_u64(skb, 1); - __s32 creditrate_initial = pull_u32(skb, 1); - __u32 creditrate_earning = pull_u32(skb, 1); - __u32 creditrate_spending = pull_u32(skb, 1); - - set_credits(nb, credits, creditrate_initial, creditrate_earning, - creditrate_spending); -} - static void kernel_packet2(struct neighbor *nb, struct sk_buff *skb, __u32 seqno1) { @@ -450,10 +439,6 @@ static void kernel_packet2(struct neighbor *nb, struct sk_buff *skb, atomic_set(&(nb->max_remote_cmsg_delay), max_cmsg_dly); ack = 1; break; - case KP_SET_CREDITS: - parse_set_credits(nb, skb); - ack = 1; - break; case KP_SET_CONN_CREDITS: conn_cmd(nb, skb, seqno1, code, parse_set_conn_credits, discard_set_conn_credits); @@ -536,10 +521,6 @@ void kernel_packet(struct neighbor *nb, struct sk_buff *skb, __u32 seqno) if (cor_pull_skb(skb2, 4) == 0) goto discard; break; - case KP_SET_CREDITS: - if (cor_pull_skb(skb2, 20) == 0) - goto discard; - break; case KP_SET_CONN_CREDITS: if (cor_pull_skb(skb2, 8) == 0) goto discard; diff --git a/net/cor/neighbor.c b/net/cor/neighbor.c index a22cc76b78e..0219501a3aa 100644 --- a/net/cor/neighbor.c +++ b/net/cor/neighbor.c @@ -123,6 +123,7 @@ static struct neighbor *alloc_neighbor(gfp_t allocflags) 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; get_random_bytes((char *) &seqno, sizeof(seqno)); mutex_init(&(nb->pingcookie_lock)); atomic_set(&(nb->latency), 1000000); @@ -399,7 +400,7 @@ static void _refresh_initial_debitsrate(struct net_device *dev, nb_list); if (curr->dev == dev) - set_debitrate_initial(curr, + set_creditrate_initial(curr, debitsrate/neighbors); currlh = currlh->next; @@ -411,6 +412,7 @@ static void refresh_initial_debitsrate(void) { struct list_head *currlh1; __u32 ifcnt = 0; + __u32 creditrate; currlh1 = nb_list.next; @@ -434,6 +436,8 @@ present1: currlh1 = currlh1->next; } + creditrate = creditrate_initial(); + currlh1 = nb_list.next; while (currlh1 != &nb_list) { @@ -449,8 +453,7 @@ present1: goto present2; } - _refresh_initial_debitsrate(curr1->dev, - CREDIT_RATE_INITIAL/ifcnt); + _refresh_initial_debitsrate(curr1->dev, creditrate/ifcnt); present2: diff --git a/net/cor/settings.h b/net/cor/settings.h index e54f0897756..9a7f6922ac0 100644 --- a/net/cor/settings.h +++ b/net/cor/settings.h @@ -35,9 +35,9 @@ #define NB_STALL_TIME_MS 10000 #define NB_KILL_TIME_MS 30000 -#define CREDIT_RATE_INITIAL 10000 -#define MAX_CREDITRATE_SOCK 268435465 #define CREDIT_REFRESHINTERVAL_SEC 30 +/* time until half the credits are gone */ +#define CREDIT_DECAYTIME_HOURS 600 #define BUFFERASSIGN_INIT 4194304 #define BUFFERASSIGN_SPEED 2097152 diff --git a/net/cor/snd.c b/net/cor/snd.c index 626a1d1cffa..3117da22da1 100644 --- a/net/cor/snd.c +++ b/net/cor/snd.c @@ -80,7 +80,7 @@ static int _resume_conns(struct qos_queue *q) lh = lh->next; - refresh_conn_credits(rconn, 0); + refresh_conn_credits(rconn, 0, 0); mutex_lock(&(rconn->rcv_lock)); @@ -130,7 +130,7 @@ static int _resume_conns(struct qos_queue *q) } mutex_unlock(&(best->rcv_lock)); - refresh_conn_credits(best, 0); + refresh_conn_credits(best, 0, 0); unreserve_sock_buffer(best); if (rc == RC_FLUSH_CONN_OUT_OK_SENT) diff --git a/net/cor/sock.c b/net/cor/sock.c index c1ba8077802..e08d3f6ed57 100644 --- a/net/cor/sock.c +++ b/net/cor/sock.c @@ -539,6 +539,7 @@ int cor_socket_connect(struct socket *sock, struct sockaddr *vaddr, conn_init_sock_source(rconn); rconn->source.sock.sbt = sbt; conn_init_sock_target(rconn->reversedir); + rconn->source.sock.is_client = 1; mutex_unlock(&(rconn->reversedir->rcv_lock)); mutex_unlock(&(rconn->rcv_lock)); @@ -683,7 +684,7 @@ int cor_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int blocking = (msg->msg_flags & MSG_DONTWAIT) == 0; __s32 bufferfree; - __u64 max = (((__u64) 1) << 32) - 1; + __u64 max = (1LL << 32) - 1; __u32 totallen = (total_len > max ? max : total_len); if (unlikely(rc)) @@ -813,7 +814,7 @@ out: mutex_unlock(&(sconn->rcv_lock)); if (likely(copied > 0)) { - refresh_conn_credits(sconn, 0); + refresh_conn_credits(sconn, 0, 0); unreserve_sock_buffer(sconn); wake_sender(sconn); } -- 2.11.4.GIT