Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab5216a5 authored by Vlad Yasevich's avatar Vlad Yasevich
Browse files

sctp: Optimize SFR-CACC transport list walking during SACK processing



There is a possibility of walking the transport list twice during
SACK processing when doing SFR-CACC algorithm.  We can restructure
the code to only do this once.

Signed-off-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
parent 2cd9b822
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -1145,29 +1145,33 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
	 * on the current primary, the CHANGEOVER_ACTIVE flag SHOULD be
	 * cleared. The CYCLING_CHANGEOVER flag SHOULD also be cleared for
	 * all destinations.
	 */
	if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) {
		primary->cacc.changeover_active = 0;
		list_for_each_entry(transport, transport_list,
				transports) {
			transport->cacc.cycling_changeover = 0;
		}
	}

	/*
	 * SFR-CACC algorithm:
	 * 2) If the SACK contains gap acks and the flag CHANGEOVER_ACTIVE
	 * is set the receiver of the SACK MUST take the following actions:
	 *
	 * A) Initialize the cacc_saw_newack to 0 for all destination
	 * addresses.
	 *
	 * Only bother if changeover_active is set. Otherwise, this is
	 * totally suboptimal to do on every SACK.
	 */
	if (gap_ack_blocks &&
	    primary->cacc.changeover_active) {
		list_for_each_entry(transport, transport_list, transports) {
	if (primary->cacc.changeover_active) {
		u8 clear_cycling = 0;

		if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) {
			primary->cacc.changeover_active = 0;
			clear_cycling = 1;
		}

		if (clear_cycling || gap_ack_blocks) {
			list_for_each_entry(transport, transport_list,
					transports) {
				if (clear_cycling)
					transport->cacc.cycling_changeover = 0;
				if (gap_ack_blocks)
					transport->cacc.cacc_saw_newack = 0;
			}
		}
	}

	/* Get the highest TSN in the sack. */
	highest_tsn = sack_ctsn;