net: sctp: migrate most recently used transport to ktime
authorDaniel Borkmann <dborkman@redhat.com>
Wed, 11 Jun 2014 16:19:30 +0000 (18:19 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 11 Jun 2014 19:23:17 +0000 (12:23 -0700)
Be more precise in transport path selection and use ktime
helpers instead of jiffies to compare and pick the better
primary and secondary recently used transports. This also
avoids any side-effects during a possible roll-over, and
could lead to better path decision-making.

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sctp/structs.h
net/sctp/associola.c
net/sctp/endpointola.c
net/sctp/transport.c

index 0dfcc92..f38588b 100644 (file)
@@ -838,10 +838,10 @@ struct sctp_transport {
        unsigned long sackdelay;
        __u32 sackfreq;
 
-       /* When was the last time (in jiffies) that we heard from this
-        * transport?  We use this to pick new active and retran paths.
+       /* When was the last time that we heard from this transport? We use
+        * this to pick new active and retran paths.
         */
-       unsigned long last_time_heard;
+       ktime_t last_time_heard;
 
        /* Last time(in jiffies) when cwnd is reduced due to the congestion
         * indication based on ECNE chunk.
index 9f1cc6f..620c99e 100644 (file)
@@ -1036,7 +1036,7 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
                }
 
                if (chunk->transport)
-                       chunk->transport->last_time_heard = jiffies;
+                       chunk->transport->last_time_heard = ktime_get();
 
                /* Run through the state machine. */
                error = sctp_do_sm(net, SCTP_EVENT_T_CHUNK, subtype,
@@ -1283,11 +1283,13 @@ static void sctp_select_active_and_retran_path(struct sctp_association *asoc)
                    trans->state == SCTP_PF)
                        continue;
                if (trans_pri == NULL ||
-                   trans->last_time_heard > trans_pri->last_time_heard) {
+                   ktime_after(trans->last_time_heard,
+                               trans_pri->last_time_heard)) {
                        trans_sec = trans_pri;
                        trans_pri = trans;
                } else if (trans_sec == NULL ||
-                          trans->last_time_heard > trans_sec->last_time_heard) {
+                          ktime_after(trans->last_time_heard,
+                                      trans_sec->last_time_heard)) {
                        trans_sec = trans;
                }
        }
index 3d9f429..9da76ba 100644 (file)
@@ -481,7 +481,7 @@ normal:
                }
 
                if (chunk->transport)
-                       chunk->transport->last_time_heard = jiffies;
+                       chunk->transport->last_time_heard = ktime_get();
 
                error = sctp_do_sm(net, SCTP_EVENT_T_CHUNK, subtype, state,
                                   ep, asoc, chunk, GFP_ATOMIC);
index 1d348d1..7dd672f 100644 (file)
@@ -72,7 +72,7 @@ static struct sctp_transport *sctp_transport_init(struct net *net,
         */
        peer->rto = msecs_to_jiffies(net->sctp.rto_initial);
 
-       peer->last_time_heard = jiffies;
+       peer->last_time_heard = ktime_get();
        peer->last_time_ecne_reduced = jiffies;
 
        peer->param_flags = SPP_HB_DISABLE |