aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2006-12-09 21:09:21 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-11 17:34:54 -0500
commitc5a1ae9a4cc4aef1505fa0aba079f834c3ee1af1 (patch)
treece26c29076ae01f762fd5b09becca79ac602a63b /net/dccp
parente312d100f19fdfe1019512b07a9d15653f254abf (diff)
[DCCP] ccid3: Perform history operations only after packet has been sent
This migrates all packet history operations into the routine ccid3_hc_tx_packet_sent, thereby removing synchronization problems that occur when, as before, the operations are spread over multiple routines. The following minor simplifications are also applied: * several simplifications now follow from this change - several tests are now no longer required * removal of one unnecessary variable (dp) Justification: Currently packet history operations span two different routines, one of which is likely to pass through several iterations of sleeping and awakening. The first routine, ccid3_hc_tx_send_packet, allocates an entry and sets a few fields. The remaining fields are filled in when the second routine (which is not within a sleeping context), ccid3_hc_tx_packet_sent, is called. This has several strong drawbacks: * it is not necessary to split history operations - all fields can be filled in by the second routine * the first routine is called multiple times, until a packet can be sent, and sleeps meanwhile - this causes a lot of difficulties with regard to keeping the list consistent * since both routines do not have a producer-consumer like synchronization, it is very difficult to maintain data across calls to these routines * the fact that the routines are called in different contexts (sleeping, not sleeping) adds further problems Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz> Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/ccids/ccid3.c38
1 files changed, 9 insertions, 29 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 6bb3f8352dad..ef68c35183ed 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -296,7 +296,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
296{ 296{
297 struct dccp_sock *dp = dccp_sk(sk); 297 struct dccp_sock *dp = dccp_sk(sk);
298 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 298 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
299 struct dccp_tx_hist_entry *new_packet;
300 struct timeval now; 299 struct timeval now;
301 suseconds_t delay; 300 suseconds_t delay;
302 301
@@ -310,21 +309,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
310 if (unlikely(skb->len == 0)) 309 if (unlikely(skb->len == 0))
311 return -EBADMSG; 310 return -EBADMSG;
312 311
313 /* See if last packet allocated was not sent */
314 new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
315 if (new_packet == NULL || new_packet->dccphtx_sent) {
316 new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist,
317 GFP_ATOMIC);
318
319 if (unlikely(new_packet == NULL)) {
320 DCCP_WARN("%s, sk=%p, not enough mem to add to history,"
321 "send refused\n", dccp_role(sk), sk);
322 return -ENOBUFS;
323 }
324
325 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
326 }
327
328 dccp_timestamp(sk, &now); 312 dccp_timestamp(sk, &now);
329 313
330 switch (hctx->ccid3hctx_state) { 314 switch (hctx->ccid3hctx_state) {
@@ -380,31 +364,27 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
380 364
381static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) 365static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
382{ 366{
383 const struct dccp_sock *dp = dccp_sk(sk);
384 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 367 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
385 struct timeval now; 368 struct timeval now;
386 struct dccp_tx_hist_entry *packet; 369 struct dccp_tx_hist_entry *packet;
387 370
388 BUG_ON(hctx == NULL); 371 BUG_ON(hctx == NULL);
389 372
390 dccp_timestamp(sk, &now);
391
392 ccid3_hc_tx_update_s(hctx, len); 373 ccid3_hc_tx_update_s(hctx, len);
393 374
394 packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist); 375 packet = dccp_tx_hist_entry_new(ccid3_tx_hist, GFP_ATOMIC);
395 if (unlikely(packet == NULL)) { 376 if (unlikely(packet == NULL)) {
396 DCCP_WARN("packet doesn't exist in history!\n"); 377 DCCP_CRIT("packet history - out of memory!");
397 return;
398 }
399 if (unlikely(packet->dccphtx_sent)) {
400 DCCP_WARN("no unsent packet in history!\n");
401 return; 378 return;
402 } 379 }
380 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, packet);
381
382 dccp_timestamp(sk, &now);
403 packet->dccphtx_tstamp = now; 383 packet->dccphtx_tstamp = now;
404 packet->dccphtx_seqno = dp->dccps_gss; 384 packet->dccphtx_seqno = dccp_sk(sk)->dccps_gss;
405 hctx->ccid3hctx_idle = 0; 385 packet->dccphtx_rtt = hctx->ccid3hctx_rtt;
406 packet->dccphtx_rtt = hctx->ccid3hctx_rtt; 386 packet->dccphtx_sent = 1;
407 packet->dccphtx_sent = 1; 387 hctx->ccid3hctx_idle = 0;
408} 388}
409 389
410static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) 390static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)