99
1010#include "ar-internal.h"
1111
12+ /* Override priority when generating ACKs for received DATA */
13+ static const u8 rxrpc_ack_priority [RXRPC_ACK__INVALID ] = {
14+ [RXRPC_ACK_IDLE ] = 1 ,
15+ [RXRPC_ACK_DELAY ] = 2 ,
16+ [RXRPC_ACK_REQUESTED ] = 3 ,
17+ [RXRPC_ACK_DUPLICATE ] = 4 ,
18+ [RXRPC_ACK_EXCEEDS_WINDOW ] = 5 ,
19+ [RXRPC_ACK_NOSPACE ] = 6 ,
20+ [RXRPC_ACK_OUT_OF_SEQUENCE ] = 7 ,
21+ };
22+
1223static void rxrpc_proto_abort (struct rxrpc_call * call , rxrpc_seq_t seq ,
1324 enum rxrpc_abort_reason why )
1425{
@@ -365,7 +376,7 @@ static void rxrpc_input_queue_data(struct rxrpc_call *call, struct sk_buff *skb,
365376 * Process a DATA packet.
366377 */
367378static void rxrpc_input_data_one (struct rxrpc_call * call , struct sk_buff * skb ,
368- bool * _notify )
379+ bool * _notify , rxrpc_serial_t * _ack_serial , int * _ack_reason )
369380{
370381 struct rxrpc_skb_priv * sp = rxrpc_skb (skb );
371382 struct sk_buff * oos ;
@@ -418,8 +429,6 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
418429 /* Send an immediate ACK if we fill in a hole */
419430 else if (!skb_queue_empty (& call -> rx_oos_queue ))
420431 ack_reason = RXRPC_ACK_DELAY ;
421- else
422- call -> ackr_nr_unacked ++ ;
423432
424433 window ++ ;
425434 if (after (window , wtop )) {
@@ -497,12 +506,16 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
497506 }
498507
499508send_ack :
500- if (ack_reason >= 0 )
501- rxrpc_send_ACK (call , ack_reason , serial ,
502- rxrpc_propose_ack_input_data );
503- else
504- rxrpc_propose_delay_ACK (call , serial ,
505- rxrpc_propose_ack_input_data );
509+ if (ack_reason >= 0 ) {
510+ if (rxrpc_ack_priority [ack_reason ] > rxrpc_ack_priority [* _ack_reason ]) {
511+ * _ack_serial = serial ;
512+ * _ack_reason = ack_reason ;
513+ } else if (rxrpc_ack_priority [ack_reason ] == rxrpc_ack_priority [* _ack_reason ] &&
514+ ack_reason == RXRPC_ACK_REQUESTED ) {
515+ * _ack_serial = serial ;
516+ * _ack_reason = ack_reason ;
517+ }
518+ }
506519}
507520
508521/*
@@ -513,9 +526,11 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
513526 struct rxrpc_jumbo_header jhdr ;
514527 struct rxrpc_skb_priv * sp = rxrpc_skb (skb ), * jsp ;
515528 struct sk_buff * jskb ;
529+ rxrpc_serial_t ack_serial = 0 ;
516530 unsigned int offset = sizeof (struct rxrpc_wire_header );
517531 unsigned int len = skb -> len - offset ;
518532 bool notify = false;
533+ int ack_reason = 0 ;
519534
520535 while (sp -> hdr .flags & RXRPC_JUMBO_PACKET ) {
521536 if (len < RXRPC_JUMBO_SUBPKTLEN )
@@ -535,7 +550,7 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
535550 jsp = rxrpc_skb (jskb );
536551 jsp -> offset = offset ;
537552 jsp -> len = RXRPC_JUMBO_DATALEN ;
538- rxrpc_input_data_one (call , jskb , & notify );
553+ rxrpc_input_data_one (call , jskb , & notify , & ack_serial , & ack_reason );
539554 rxrpc_free_skb (jskb , rxrpc_skb_put_jumbo_subpacket );
540555
541556 sp -> hdr .flags = jhdr .flags ;
@@ -548,7 +563,16 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
548563
549564 sp -> offset = offset ;
550565 sp -> len = len ;
551- rxrpc_input_data_one (call , skb , & notify );
566+ rxrpc_input_data_one (call , skb , & notify , & ack_serial , & ack_reason );
567+
568+ if (ack_reason > 0 ) {
569+ rxrpc_send_ACK (call , ack_reason , ack_serial ,
570+ rxrpc_propose_ack_input_data );
571+ } else {
572+ call -> ackr_nr_unacked ++ ;
573+ rxrpc_propose_delay_ACK (call , sp -> hdr .serial ,
574+ rxrpc_propose_ack_input_data );
575+ }
552576 if (notify ) {
553577 trace_rxrpc_notify_socket (call -> debug_id , sp -> hdr .serial );
554578 rxrpc_notify_socket (call );
@@ -685,9 +709,6 @@ static void rxrpc_input_ack_trailer(struct rxrpc_call *call, struct sk_buff *skb
685709 call -> tx_winsize = rwind ;
686710 }
687711
688- if (call -> cong_ssthresh > rwind )
689- call -> cong_ssthresh = rwind ;
690-
691712 mtu = min (ntohl (trailer -> maxMTU ), ntohl (trailer -> ifMTU ));
692713
693714 peer = call -> peer ;
0 commit comments