Author: tuexen
Date: Fri Feb 10 07:44:03 2012
New Revision: 231360
URL: http://svn.freebsd.org/changeset/base/231360

Log:
  MFC r217469:
  Add support for resource pooling to CMT.
  An original version of the patch was developed by Martin Becke
  and Thomas Dreibholz.

Modified:
  stable/8/sys/netinet/sctp_cc_functions.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)

Modified: stable/8/sys/netinet/sctp_cc_functions.c
==============================================================================
--- stable/8/sys/netinet/sctp_cc_functions.c    Fri Feb 10 07:42:38 2012        
(r231359)
+++ stable/8/sys/netinet/sctp_cc_functions.c    Fri Feb 10 07:44:03 2012        
(r231360)
@@ -66,6 +66,13 @@ sctp_set_initial_cc_param(struct sctp_tc
                        cwnd_in_mtu = assoc->max_burst;
                net->cwnd = (net->mtu - sizeof(struct sctphdr)) * cwnd_in_mtu;
        }
+       if (stcb->asoc.sctp_cmt_on_off == 2) {
+               /* In case of resource pooling initialize appropriately */
+               net->cwnd /= assoc->numnets;
+               if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) {
+                       net->cwnd = net->mtu - sizeof(struct sctphdr);
+               }
+       }
        net->ssthresh = assoc->peers_rwnd;
 
        SDT_PROBE(sctp, cwnd, net, init,
@@ -82,7 +89,17 @@ sctp_cwnd_update_after_fr(struct sctp_tc
     struct sctp_association *asoc)
 {
        struct sctp_nets *net;
+       uint32_t t_ssthresh, t_cwnd;
 
+       /* MT FIXME: Don't compute this over and over again */
+       t_ssthresh = 0;
+       t_cwnd = 0;
+       if (asoc->sctp_cmt_on_off == 2) {
+               TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
+                       t_ssthresh += net->ssthresh;
+                       t_cwnd += net->cwnd;
+               }
+       }
        /*-
         * CMT fast recovery code. Need to debug. ((sctp_cmt_on_off > 0) &&
         * (net->fast_retran_loss_recovery == 0)))
@@ -101,9 +118,23 @@ sctp_cwnd_update_after_fr(struct sctp_tc
                                struct sctp_tmit_chunk *lchk;
                                int old_cwnd = net->cwnd;
 
-                               net->ssthresh = net->cwnd / 2;
-                               if (net->ssthresh < (net->mtu * 2)) {
-                                       net->ssthresh = 2 * net->mtu;
+                               if (asoc->sctp_cmt_on_off == 2) {
+                                       net->ssthresh = (uint32_t) (((uint64_t) 
4 *
+                                           (uint64_t) net->mtu *
+                                           (uint64_t) net->ssthresh) /
+                                           (uint64_t) t_ssthresh);
+                                       if ((net->cwnd > t_cwnd / 2) &&
+                                           (net->ssthresh < net->cwnd - t_cwnd 
/ 2)) {
+                                               net->ssthresh = net->cwnd - 
t_cwnd / 2;
+                                       }
+                                       if (net->ssthresh < net->mtu) {
+                                               net->ssthresh = net->mtu;
+                                       }
+                               } else {
+                                       net->ssthresh = net->cwnd / 2;
+                                       if (net->ssthresh < (net->mtu * 2)) {
+                                               net->ssthresh = 2 * net->mtu;
+                                       }
                                }
                                net->cwnd = net->ssthresh;
                                SDT_PROBE(sctp, cwnd, net, fr,
@@ -167,7 +198,17 @@ sctp_cwnd_update_after_sack(struct sctp_
 {
        struct sctp_nets *net;
        int old_cwnd;
+       uint32_t t_ssthresh, t_cwnd, incr;
 
+       /* MT FIXME: Don't compute this over and over again */
+       t_ssthresh = 0;
+       t_cwnd = 0;
+       if (stcb->asoc.sctp_cmt_on_off == 2) {
+               TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
+                       t_ssthresh += net->ssthresh;
+                       t_cwnd += net->cwnd;
+               }
+       }
        /******************************/
        /* update cwnd and Early FR   */
        /******************************/
@@ -178,11 +219,8 @@ sctp_cwnd_update_after_sack(struct sctp_
                 * CMT fast recovery code. Need to debug.
                 */
                if (net->fast_retran_loss_recovery && net->new_pseudo_cumack) {
-                       if (compare_with_wrap(asoc->last_acked_seq,
-                           net->fast_recovery_tsn, MAX_TSN) ||
-                           (asoc->last_acked_seq == net->fast_recovery_tsn) ||
-                           compare_with_wrap(net->pseudo_cumack, 
net->fast_recovery_tsn, MAX_TSN) ||
-                           (net->pseudo_cumack == net->fast_recovery_tsn)) {
+                       if (SCTP_TSN_GE(asoc->last_acked_seq, 
net->fast_recovery_tsn) ||
+                           SCTP_TSN_GE(net->pseudo_cumack, 
net->fast_recovery_tsn)) {
                                net->will_exit_fast_recovery = 1;
                        }
                }
@@ -304,32 +342,39 @@ sctp_cwnd_update_after_sack(struct sctp_
                        if (net->cwnd <= net->ssthresh) {
                                /* We are in slow start */
                                if (net->flight_size + net->net_ack >= 
net->cwnd) {
-                                       if (net->net_ack > (net->mtu * 
SCTP_BASE_SYSCTL(sctp_L2_abc_variable))) {
-                                               old_cwnd = net->cwnd;
-                                               net->cwnd += (net->mtu * 
SCTP_BASE_SYSCTL(sctp_L2_abc_variable));
-                                               SDT_PROBE(sctp, cwnd, net, ack,
-                                                   stcb->asoc.my_vtag,
-                                                   ((stcb->sctp_ep->sctp_lport 
<< 16) | (stcb->rport)),
-                                                   net,
-                                                   old_cwnd, net->cwnd);
-                                               if 
(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
-                                                       sctp_log_cwnd(stcb, 
net, net->mtu,
-                                                           
SCTP_CWND_LOG_FROM_SS);
+                                       old_cwnd = net->cwnd;
+                                       if (stcb->asoc.sctp_cmt_on_off == 2) {
+                                               uint32_t limit;
+
+                                               limit = (uint32_t) (((uint64_t) 
net->mtu *
+                                                   (uint64_t) 
SCTP_BASE_SYSCTL(sctp_L2_abc_variable) *
+                                                   (uint64_t) net->ssthresh) /
+                                                   (uint64_t) t_ssthresh);
+                                               incr = (uint32_t) (((uint64_t) 
net->net_ack *
+                                                   (uint64_t) net->ssthresh) /
+                                                   (uint64_t) t_ssthresh);
+                                               if (incr > limit) {
+                                                       incr = limit;
+                                               }
+                                               if (incr == 0) {
+                                                       incr = 1;
                                                }
                                        } else {
-                                               old_cwnd = net->cwnd;
-                                               net->cwnd += net->net_ack;
-                                               SDT_PROBE(sctp, cwnd, net, ack,
-                                                   stcb->asoc.my_vtag,
-                                                   ((stcb->sctp_ep->sctp_lport 
<< 16) | (stcb->rport)),
-                                                   net,
-                                                   old_cwnd, net->cwnd);
-
-                                               if 
(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
-                                                       sctp_log_cwnd(stcb, 
net, net->net_ack,
-                                                           
SCTP_CWND_LOG_FROM_SS);
+                                               incr = net->net_ack;
+                                               if (incr > net->mtu * 
SCTP_BASE_SYSCTL(sctp_L2_abc_variable)) {
+                                                       incr = net->mtu * 
SCTP_BASE_SYSCTL(sctp_L2_abc_variable);
                                                }
                                        }
+                                       net->cwnd += incr;
+                                       if 
(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
+                                               sctp_log_cwnd(stcb, net, incr,
+                                                   SCTP_CWND_LOG_FROM_SS);
+                                       }
+                                       SDT_PROBE(sctp, cwnd, net, ack,
+                                           stcb->asoc.my_vtag,
+                                           ((stcb->sctp_ep->sctp_lport << 16) 
| (stcb->rport)),
+                                           net,
+                                           old_cwnd, net->cwnd);
                                } else {
                                        if 
(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
                                                sctp_log_cwnd(stcb, net, 
net->net_ack,
@@ -338,6 +383,8 @@ sctp_cwnd_update_after_sack(struct sctp_
                                }
                        } else {
                                /* We are in congestion avoidance */
+                               uint32_t incr;
+
                                /*
                                 * Add to pba
                                 */
@@ -347,7 +394,17 @@ sctp_cwnd_update_after_sack(struct sctp_
                                    (net->partial_bytes_acked >= net->cwnd)) {
                                        net->partial_bytes_acked -= net->cwnd;
                                        old_cwnd = net->cwnd;
-                                       net->cwnd += net->mtu;
+                                       if (asoc->sctp_cmt_on_off == 2) {
+                                               incr = (uint32_t) (((uint64_t) 
net->mtu *
+                                                   (uint64_t) net->ssthresh) /
+                                                   (uint64_t) t_ssthresh);
+                                               if (incr == 0) {
+                                                       incr = 1;
+                                               }
+                                       } else {
+                                               incr = net->mtu;
+                                       }
+                                       net->cwnd += incr;
                                        SDT_PROBE(sctp, cwnd, net, ack,
                                            stcb->asoc.my_vtag,
                                            ((stcb->sctp_ep->sctp_lport << 16) 
| (stcb->rport)),
@@ -394,8 +451,32 @@ void
 sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
 {
        int old_cwnd = net->cwnd;
+       uint32_t t_ssthresh, t_cwnd;
 
-       net->ssthresh = max(net->cwnd / 2, 4 * net->mtu);
+       /* MT FIXME: Don't compute this over and over again */
+       t_ssthresh = 0;
+       t_cwnd = 0;
+       if (stcb->asoc.sctp_cmt_on_off == 2) {
+               struct sctp_nets *lnet;
+
+               TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
+                       t_ssthresh += lnet->ssthresh;
+                       t_cwnd += lnet->cwnd;
+               }
+               net->ssthresh = (uint32_t) (((uint64_t) 4 *
+                   (uint64_t) net->mtu *
+                   (uint64_t) net->ssthresh) /
+                   (uint64_t) t_ssthresh);
+               if ((net->cwnd > t_cwnd / 2) &&
+                   (net->ssthresh < net->cwnd - t_cwnd / 2)) {
+                       net->ssthresh = net->cwnd - t_cwnd / 2;
+               }
+               if (net->ssthresh < net->mtu) {
+                       net->ssthresh = net->mtu;
+               }
+       } else {
+               net->ssthresh = max(net->cwnd / 2, 4 * net->mtu);
+       }
        net->cwnd = net->mtu;
        net->partial_bytes_acked = 0;
        SDT_PROBE(sctp, cwnd, net, to,
@@ -844,11 +925,8 @@ sctp_hs_cwnd_update_after_sack(struct sc
                 * CMT fast recovery code. Need to debug.
                 */
                if (net->fast_retran_loss_recovery && net->new_pseudo_cumack) {
-                       if (compare_with_wrap(asoc->last_acked_seq,
-                           net->fast_recovery_tsn, MAX_TSN) ||
-                           (asoc->last_acked_seq == net->fast_recovery_tsn) ||
-                           compare_with_wrap(net->pseudo_cumack, 
net->fast_recovery_tsn, MAX_TSN) ||
-                           (net->pseudo_cumack == net->fast_recovery_tsn)) {
+                       if (SCTP_TSN_GE(asoc->last_acked_seq, 
net->fast_recovery_tsn) ||
+                           SCTP_TSN_GE(net->pseudo_cumack, 
net->fast_recovery_tsn)) {
                                net->will_exit_fast_recovery = 1;
                        }
                }
@@ -1329,11 +1407,8 @@ sctp_htcp_cwnd_update_after_sack(struct 
                 * CMT fast recovery code. Need to debug.
                 */
                if (net->fast_retran_loss_recovery && net->new_pseudo_cumack) {
-                       if (compare_with_wrap(asoc->last_acked_seq,
-                           net->fast_recovery_tsn, MAX_TSN) ||
-                           (asoc->last_acked_seq == net->fast_recovery_tsn) ||
-                           compare_with_wrap(net->pseudo_cumack, 
net->fast_recovery_tsn, MAX_TSN) ||
-                           (net->pseudo_cumack == net->fast_recovery_tsn)) {
+                       if (SCTP_TSN_GE(asoc->last_acked_seq, 
net->fast_recovery_tsn) ||
+                           SCTP_TSN_GE(net->pseudo_cumack, 
net->fast_recovery_tsn)) {
                                net->will_exit_fast_recovery = 1;
                        }
                }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to