Commit fa04a008 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [RXRPC] net/rxrpc/ar-connection.c: fix NULL dereference
  [TCP]: Fix logic breakage due to DSACK separation
  [TCP]: Congestion control API RTT sampling fix
parents d09c6b80 16c61add
...@@ -261,6 +261,18 @@ static inline s64 ktime_to_ns(const ktime_t kt) ...@@ -261,6 +261,18 @@ static inline s64 ktime_to_ns(const ktime_t kt)
#endif #endif
/**
* ktime_equal - Compares two ktime_t variables to see if they are equal
* @cmp1: comparable1
* @cmp2: comparable2
*
* Compare two ktime_t variables, returns 1 if equal
*/
static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2)
{
return cmp1.tv64 == cmp2.tv64;
}
static inline s64 ktime_to_us(const ktime_t kt) static inline s64 ktime_to_us(const ktime_t kt)
{ {
struct timeval tv = ktime_to_timeval(kt); struct timeval tv = ktime_to_timeval(kt);
......
...@@ -1579,6 +1579,10 @@ static inline ktime_t net_timedelta(ktime_t t) ...@@ -1579,6 +1579,10 @@ static inline ktime_t net_timedelta(ktime_t t)
return ktime_sub(ktime_get_real(), t); return ktime_sub(ktime_get_real(), t);
} }
static inline ktime_t net_invalid_timestamp(void)
{
return ktime_set(0, 0);
}
extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len); extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len);
extern __sum16 __skb_checksum_complete(struct sk_buff *skb); extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
......
...@@ -90,6 +90,9 @@ static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, ktime_t last) ...@@ -90,6 +90,9 @@ static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, ktime_t last)
ca->acked = pkts_acked; ca->acked = pkts_acked;
if (ktime_equal(last, net_invalid_timestamp()))
return;
rtt = ktime_to_us(net_timedelta(last)); rtt = ktime_to_us(net_timedelta(last));
/* ignore bogus values, this prevents wraparound in alpha math */ /* ignore bogus values, this prevents wraparound in alpha math */
......
...@@ -953,7 +953,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -953,7 +953,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
int prior_fackets; int prior_fackets;
u32 lost_retrans = 0; u32 lost_retrans = 0;
int flag = 0; int flag = 0;
int dup_sack = 0; int found_dup_sack = 0;
int cached_fack_count; int cached_fack_count;
int i; int i;
int first_sack_index; int first_sack_index;
...@@ -964,20 +964,20 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -964,20 +964,20 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
/* Check for D-SACK. */ /* Check for D-SACK. */
if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) { if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) {
dup_sack = 1; found_dup_sack = 1;
tp->rx_opt.sack_ok |= 4; tp->rx_opt.sack_ok |= 4;
NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV); NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV);
} else if (num_sacks > 1 && } else if (num_sacks > 1 &&
!after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) && !after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) &&
!before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) { !before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) {
dup_sack = 1; found_dup_sack = 1;
tp->rx_opt.sack_ok |= 4; tp->rx_opt.sack_ok |= 4;
NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV); NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV);
} }
/* D-SACK for already forgotten data... /* D-SACK for already forgotten data...
* Do dumb counting. */ * Do dumb counting. */
if (dup_sack && if (found_dup_sack &&
!after(ntohl(sp[0].end_seq), prior_snd_una) && !after(ntohl(sp[0].end_seq), prior_snd_una) &&
after(ntohl(sp[0].end_seq), tp->undo_marker)) after(ntohl(sp[0].end_seq), tp->undo_marker))
tp->undo_retrans--; tp->undo_retrans--;
...@@ -1058,6 +1058,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -1058,6 +1058,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
__u32 start_seq = ntohl(sp->start_seq); __u32 start_seq = ntohl(sp->start_seq);
__u32 end_seq = ntohl(sp->end_seq); __u32 end_seq = ntohl(sp->end_seq);
int fack_count; int fack_count;
int dup_sack = (found_dup_sack && (i == first_sack_index));
skb = cached_skb; skb = cached_skb;
fack_count = cached_fack_count; fack_count = cached_fack_count;
...@@ -2409,7 +2410,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) ...@@ -2409,7 +2410,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
int acked = 0; int acked = 0;
int prior_packets = tp->packets_out; int prior_packets = tp->packets_out;
__s32 seq_rtt = -1; __s32 seq_rtt = -1;
ktime_t last_ackt = ktime_set(0,0); ktime_t last_ackt = net_invalid_timestamp();
while ((skb = tcp_write_queue_head(sk)) && while ((skb = tcp_write_queue_head(sk)) &&
skb != tcp_send_head(sk)) { skb != tcp_send_head(sk)) {
...@@ -2487,6 +2488,10 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) ...@@ -2487,6 +2488,10 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
tcp_ack_update_rtt(sk, acked, seq_rtt); tcp_ack_update_rtt(sk, acked, seq_rtt);
tcp_ack_packets_out(sk); tcp_ack_packets_out(sk);
/* Is the ACK triggering packet unambiguous? */
if (acked & FLAG_RETRANS_DATA_ACKED)
last_ackt = net_invalid_timestamp();
if (ca_ops->pkts_acked) if (ca_ops->pkts_acked)
ca_ops->pkts_acked(sk, pkts_acked, last_ackt); ca_ops->pkts_acked(sk, pkts_acked, last_ackt);
} }
......
...@@ -266,7 +266,8 @@ static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, ktime_t last) ...@@ -266,7 +266,8 @@ static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, ktime_t last)
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
struct lp *lp = inet_csk_ca(sk); struct lp *lp = inet_csk_ca(sk);
tcp_lp_rtt_sample(sk, ktime_to_us(net_timedelta(last))); if (!ktime_equal(last, net_invalid_timestamp()))
tcp_lp_rtt_sample(sk, ktime_to_us(net_timedelta(last)));
/* calc inference */ /* calc inference */
if (tcp_time_stamp > tp->rx_opt.rcv_tsecr) if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
......
...@@ -117,6 +117,9 @@ void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) ...@@ -117,6 +117,9 @@ void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last)
struct vegas *vegas = inet_csk_ca(sk); struct vegas *vegas = inet_csk_ca(sk);
u32 vrtt; u32 vrtt;
if (ktime_equal(last, net_invalid_timestamp()))
return;
/* Never allow zero rtt or baseRTT */ /* Never allow zero rtt or baseRTT */
vrtt = ktime_to_us(net_timedelta(last)) + 1; vrtt = ktime_to_us(net_timedelta(last)) + 1;
......
...@@ -74,6 +74,9 @@ static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) ...@@ -74,6 +74,9 @@ static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, ktime_t last)
struct veno *veno = inet_csk_ca(sk); struct veno *veno = inet_csk_ca(sk);
u32 vrtt; u32 vrtt;
if (ktime_equal(last, net_invalid_timestamp()))
return;
/* Never allow zero rtt or baseRTT */ /* Never allow zero rtt or baseRTT */
vrtt = ktime_to_us(net_timedelta(last)) + 1; vrtt = ktime_to_us(net_timedelta(last)) + 1;
......
...@@ -211,7 +211,7 @@ static struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp) ...@@ -211,7 +211,7 @@ static struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
conn->header_size = sizeof(struct rxrpc_header); conn->header_size = sizeof(struct rxrpc_header);
} }
_leave(" = %p{%d}", conn, conn->debug_id); _leave(" = %p{%d}", conn, conn ? conn->debug_id : 0);
return conn; return conn;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment