Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[DCCP] Introduce dccp_timestamp

To start the timestamps with 0.0ms, easing the integer maths in the CCIDs, this
probably will be reworked to use the to be introduced struct timeval_offset
infrastructure out of skb_get_timestamp, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>

+61 -39
+1
include/linux/dccp.h
··· 432 432 struct ccid *dccps_hc_rx_ccid; 433 433 struct ccid *dccps_hc_tx_ccid; 434 434 struct dccp_options_received dccps_options_received; 435 + struct timeval dccps_epoch; 435 436 enum dccp_role dccps_role:2; 436 437 __u8 dccps_hc_rx_insert_options:1; 437 438 __u8 dccps_hc_tx_insert_options:1;
+14 -13
net/dccp/ccids/ccid3.c
··· 169 169 } else { 170 170 struct timeval now; 171 171 172 - do_gettimeofday(&now); 172 + dccp_timestamp(sk, &now); 173 173 if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >= 174 174 hctx->ccid3hctx_rtt) { 175 175 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv, ··· 317 317 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet); 318 318 } 319 319 320 - do_gettimeofday(&now); 320 + dccp_timestamp(sk, &now); 321 321 322 322 switch (hctx->ccid3hctx_state) { 323 323 case TFRC_SSTATE_NO_SENT: ··· 382 382 return; 383 383 } 384 384 385 - do_gettimeofday(&now); 385 + dccp_timestamp(sk, &now); 386 386 387 387 /* check if we have sent a data packet */ 388 388 if (len > 0) { ··· 461 461 struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; 462 462 struct ccid3_options_received *opt_recv; 463 463 struct dccp_tx_hist_entry *packet; 464 + struct timeval now; 464 465 unsigned long next_tmout; 465 466 u32 t_elapsed; 466 467 u32 pinv; ··· 509 508 } 510 509 511 510 /* Update RTT */ 512 - r_sample = timeval_now_delta(&packet->dccphtx_tstamp); 511 + dccp_timestamp(sk, &now); 512 + r_sample = timeval_delta(&now, &packet->dccphtx_tstamp); 513 513 if (unlikely(r_sample <= t_elapsed)) 514 514 LIMIT_NETDEBUG(KERN_WARNING 515 515 "%s: r_sample=%uus, t_elapsed=%uus\n", ··· 776 774 777 775 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 778 776 779 - do_gettimeofday(&now); 777 + dccp_timestamp(sk, &now); 780 778 781 779 switch (hcrx->ccid3hcrx_state) { 782 780 case TFRC_RSTATE_NO_DATA: ··· 905 903 if (rtt == 0) 906 904 rtt = 1; 907 905 908 - delta = timeval_now_delta(&hcrx->ccid3hcrx_tstamp_last_feedback); 909 - x_recv = hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC; 910 - if (likely(delta > 1)) 911 - x_recv /= delta; 906 + dccp_timestamp(sk, &tstamp); 907 + delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback); 908 + x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta); 912 909 913 910 tmp1 = (u64)x_recv * (u64)rtt; 914 911 do_div(tmp1,10000000); ··· 982 981 if (opt_recv->dccpor_timestamp_echo == 0) 983 982 break; 984 983 p_prev = hcrx->ccid3hcrx_rtt; 985 - do_gettimeofday(&now); 984 + dccp_timestamp(sk, &now); 986 985 timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10); 987 986 r_sample = timeval_usecs(&now); 988 987 t_elapsed = opt_recv->dccpor_elapsed_time * 10; ··· 1014 1013 return; 1015 1014 } 1016 1015 1017 - packet = dccp_rx_hist_entry_new(ccid3_rx_hist, opt_recv->dccpor_ndp, 1016 + packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp, 1018 1017 skb, SLAB_ATOMIC); 1019 1018 if (packet == NULL) { 1020 1019 ccid3_pr_debug("%s, sk=%p, Not enough mem to add rx packet " ··· 1046 1045 if (ins != 0) 1047 1046 break; 1048 1047 1049 - do_gettimeofday(&now); 1048 + dccp_timestamp(sk, &now); 1050 1049 if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >= 1051 1050 hcrx->ccid3hcrx_rtt) { 1052 1051 hcrx->ccid3hcrx_tstamp_last_ack = now; ··· 1101 1100 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; 1102 1101 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist); 1103 1102 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); 1104 - do_gettimeofday(&hcrx->ccid3hcrx_tstamp_last_ack); 1103 + dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack); 1105 1104 hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack; 1106 1105 hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */ 1107 1106 return 0;
+1 -1
net/dccp/ccids/ccid3.h
··· 115 115 u64 ccid3hcrx_seqno_last_counter:48, 116 116 ccid3hcrx_state:8, 117 117 ccid3hcrx_last_counter:4; 118 - unsigned long ccid3hcrx_rtt; 118 + u32 ccid3hcrx_rtt; 119 119 u32 ccid3hcrx_p; 120 120 u32 ccid3hcrx_bytes_recv; 121 121 struct timeval ccid3hcrx_tstamp_last_feedback;
+2 -1
net/dccp/ccids/lib/packet_history.h
··· 134 134 135 135 static inline struct dccp_rx_hist_entry * 136 136 dccp_rx_hist_entry_new(struct dccp_rx_hist *hist, 137 + const struct sock *sk, 137 138 const u32 ndp, 138 139 const struct sk_buff *skb, 139 140 const unsigned int __nocast prio) ··· 149 148 entry->dccphrx_ccval = dh->dccph_ccval; 150 149 entry->dccphrx_type = dh->dccph_type; 151 150 entry->dccphrx_ndp = ndp; 152 - do_gettimeofday(&(entry->dccphrx_tstamp)); 151 + dccp_timestamp(sk, &entry->dccphrx_tstamp); 153 152 } 154 153 155 154 return entry;
+4 -12
net/dccp/dccp.h
··· 426 426 dccp_ackpkts_alloc(unsigned int len, 427 427 const unsigned int __nocast priority); 428 428 extern void dccp_ackpkts_free(struct dccp_ackpkts *ap); 429 - extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state); 429 + extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, const struct sock *sk, 430 + u64 ackno, u8 state); 430 431 extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap, 431 432 struct sock *sk, u64 ackno); 433 + 434 + extern void dccp_timestamp(const struct sock *sk, struct timeval *tv); 432 435 433 436 static inline suseconds_t timeval_usecs(const struct timeval *tv) 434 437 { ··· 469 466 tv->tv_sec--; 470 467 tv->tv_usec += USEC_PER_SEC; 471 468 } 472 - } 473 - 474 - /* 475 - * Returns the difference in usecs between timeval 476 - * passed in and current time 477 - */ 478 - static inline suseconds_t timeval_now_delta(const struct timeval *tv) 479 - { 480 - struct timeval now; 481 - do_gettimeofday(&now); 482 - return timeval_delta(&now, tv); 483 469 } 484 470 485 471 #ifdef CONFIG_IP_DCCP_DEBUG
+2 -2
net/dccp/input.c
··· 170 170 if (dp->dccps_options.dccpo_send_ack_vector) { 171 171 struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; 172 172 173 - if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, 173 + if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk, 174 174 DCCP_SKB_CB(skb)->dccpd_seq, 175 175 DCCP_ACKPKTS_STATE_RECEIVED)) { 176 176 LIMIT_NETDEBUG(KERN_WARNING "DCCP: acknowledgeable " ··· 498 498 * DCCP_ACKPKTS_STATE_ECN_MARKED 499 499 */ 500 500 if (dp->dccps_options.dccpo_send_ack_vector) { 501 - if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, 501 + if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk, 502 502 DCCP_SKB_CB(skb)->dccpd_seq, 503 503 DCCP_ACKPKTS_STATE_RECEIVED)) 504 504 goto discard;
+1
net/dccp/ipv4.c
··· 1243 1243 static int dccp_ctl_socket_init = 1; 1244 1244 1245 1245 dccp_options_init(&dp->dccps_options); 1246 + do_gettimeofday(&dp->dccps_epoch); 1246 1247 1247 1248 if (dp->dccps_options.dccpo_send_ack_vector) { 1248 1249 dp->dccps_hc_rx_ackpkts =
+1
net/dccp/minisocks.c
··· 96 96 newdp->dccps_hc_rx_ackpkts = NULL; 97 97 newdp->dccps_role = DCCP_ROLE_SERVER; 98 98 newicsk->icsk_rto = DCCP_TIMEOUT_INIT; 99 + do_gettimeofday(&newdp->dccps_epoch); 99 100 100 101 if (newdp->dccps_options.dccpo_send_ack_vector) { 101 102 newdp->dccps_hc_rx_ackpkts =
+35 -10
net/dccp/options.c
··· 140 140 opt_recv->dccpor_timestamp = ntohl(*(u32 *)value); 141 141 142 142 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; 143 - do_gettimeofday(&dp->dccps_timestamp_time); 143 + dccp_timestamp(sk, &dp->dccps_timestamp_time); 144 144 145 145 dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n", 146 146 debug_prefix, opt_recv->dccpor_timestamp, ··· 361 361 #endif 362 362 struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts; 363 363 int len = ap->dccpap_buf_vector_len + 2; 364 - const u32 elapsed_time = timeval_now_delta(&ap->dccpap_time) / 10; 364 + struct timeval now; 365 + u32 elapsed_time; 365 366 unsigned char *to, *from; 367 + 368 + dccp_timestamp(sk, &now); 369 + elapsed_time = timeval_delta(&now, &ap->dccpap_time) / 10; 366 370 367 371 if (elapsed_time != 0) 368 372 dccp_insert_option_elapsed_time(sk, skb, elapsed_time); ··· 432 428 (unsigned long long) ap->dccpap_ack_ackno); 433 429 } 434 430 431 + void dccp_timestamp(const struct sock *sk, struct timeval *tv) 432 + { 433 + const struct dccp_sock *dp = dccp_sk(sk); 434 + 435 + do_gettimeofday(tv); 436 + tv->tv_sec -= dp->dccps_epoch.tv_sec; 437 + tv->tv_usec -= dp->dccps_epoch.tv_usec; 438 + 439 + while (tv->tv_usec < 0) { 440 + tv->tv_sec--; 441 + tv->tv_usec += USEC_PER_SEC; 442 + } 443 + } 444 + 445 + EXPORT_SYMBOL_GPL(dccp_timestamp); 446 + 435 447 void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb) 436 448 { 437 449 struct timeval tv; 438 450 u32 now; 439 451 440 - do_gettimeofday(&tv); 441 - now = (tv.tv_sec * USEC_PER_SEC + tv.tv_usec) / 10; 452 + dccp_timestamp(sk, &tv); 453 + now = timeval_usecs(&tv) / 10; 442 454 /* yes this will overflow but that is the point as we want a 443 455 * 10 usec 32 bit timer which mean it wraps every 11.9 hours */ 444 456 ··· 472 452 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? 473 453 "CLIENT TX opt: " : "server TX opt: "; 474 454 #endif 455 + struct timeval now; 475 456 u32 tstamp_echo; 476 - const u32 elapsed_time = 477 - timeval_now_delta(&dp->dccps_timestamp_time) / 10; 478 - const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); 479 - const int len = 6 + elapsed_time_len; 457 + u32 elapsed_time; 458 + int len, elapsed_time_len; 480 459 unsigned char *to; 460 + 461 + dccp_timestamp(sk, &now); 462 + elapsed_time = timeval_delta(&now, &dp->dccps_timestamp_time) / 10; 463 + elapsed_time_len = dccp_elapsed_time_len(elapsed_time); 464 + len = 6 + elapsed_time_len; 481 465 482 466 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { 483 467 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert " ··· 647 623 /* 648 624 * Implements the draft-ietf-dccp-spec-11.txt Appendix A 649 625 */ 650 - int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state) 626 + int dccp_ackpkts_add(struct dccp_ackpkts *ap, const struct sock *sk, 627 + u64 ackno, u8 state) 651 628 { 652 629 /* 653 630 * Check at the right places if the buffer is full, if it is, tell the ··· 729 704 } 730 705 731 706 ap->dccpap_buf_ackno = ackno; 732 - do_gettimeofday(&ap->dccpap_time); 707 + dccp_timestamp(sk, &ap->dccpap_time); 733 708 out: 734 709 dccp_pr_debug(""); 735 710 dccp_ackpkts_print(ap);