From patchwork Sat May 12 22:21:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Ricardo Leitner X-Patchwork-Id: 912477 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZWP4mTzR"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40k1dd6WMSz9s28 for ; Sun, 13 May 2018 08:21:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751920AbeELWVX (ORCPT ); Sat, 12 May 2018 18:21:23 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:44455 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751890AbeELWVU (ORCPT ); Sat, 12 May 2018 18:21:20 -0400 Received: by mail-qt0-f194.google.com with SMTP id d3-v6so11670956qtp.11; Sat, 12 May 2018 15:21:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8za/TkL/bAHQ0F81Cz0pBwGBpvm0M7r6mQeCXReVI8Q=; b=ZWP4mTzRVOUpIcRol6mYdW0UJCtNF+R9uVeIgXvXi6xsdlzVZGc9K02km6EM4/sV6B rnVq7b056HPx9krccuEnyIXFoAQOlKgOUnoluMNXc3hwozGVxfm2dcJA4nFMGDMhQdFI atRSOjJWWrZl3AaBh73zvHxjd62OSXCPCQHp/1v731y89retZ978en8OsoL8ltRby1Uo nsz/Q/Qi/rWekQzrn3pobJ/lqtxnCr2/pX4aF8QtLouao5elQYi/pHXFRzfTTydKIWtS sBl4W7awabV473MFXT03Pi+nMmrHLnwhopsjW67NmjAHot7FU6Jrq+UDSRBY23bmAMBb gF6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8za/TkL/bAHQ0F81Cz0pBwGBpvm0M7r6mQeCXReVI8Q=; b=kZ3HLLbi7bI3m6DVXBBIwKV+E261+GVPBaIW3ADwO5dRGVtamJYOW4acHggCg6fMq+ 3ZPT5PY9iytyS4D0Sm2xPTMDgzfgIa++hC9QwOugVsjmctwWlLwDxAjrUWUW6+AKr4Zn dF5vVPxwBoYKvqEXbPTL1QrepsiGai03v/bTISO0xTEnbDlH+JhRECQYiUmneDUI0G5+ 2MkXFpPBYpOLqZVdbZ+jfhT5KfCNr8YQO+MO5pjPj73zrpOcHYiThdtn1aJ+pFuB6Rdz WROYyEPe/cJvU35xsevO2PEiMQnhRPXu7Uv8ruYoS69JMHbxRD6c+DsQtx5d1qXUfnT8 KArQ== X-Gm-Message-State: ALKqPwdK18AAeZ084K/8lWaXTs4EXT/Ks9E4aMMiTwYWnDun39eI1iFi Eqcd0CtMsUHRu5AMWhqkJgw= X-Google-Smtp-Source: AB8JxZplR3Ebih8tdrg41hRMxoSFMavzuspBvz7Ba1ssqNOnNxRj5eeNiJ6Br6KEZgbxXnUTiOWetQ== X-Received: by 2002:a0c:afda:: with SMTP id t26-v6mr3797624qvc.144.1526163679179; Sat, 12 May 2018 15:21:19 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id l3-v6sm5233335qkh.11.2018.05.12.15.21.18 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 May 2018 15:21:18 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 4D19A180C66; Sat, 12 May 2018 19:21:16 -0300 (-03) From: Marcelo Ricardo Leitner To: netdev@vger.kernel.org Cc: linux-sctp@vger.kernel.org, Neil Horman , Vlad Yasevich , Xin Long Subject: [PATCH net-next v2 8/8] sctp: rework switch cases in sctp_outq_flush_data Date: Sat, 12 May 2018 19:21:15 -0300 Message-Id: <38105db0006c63118a1020ca6ca31a2a48ca9905.1526142784.git.marcelo.leitner@gmail.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: References: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Remove an inner one, which tended to be error prone due to the cascading and it can be replaced by a simple if (). Rework the outer one so that the actual flush code is not inside it. Now we first validate if we can or cannot send data, return if not, and then the flush code. Suggested-by: Xin Long Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 191 +++++++++++++++++++++++++--------------------------- 1 file changed, 93 insertions(+), 98 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 8173dd26f5878cbf67dd7e162ac5e6b18d9a3332..a9400cb0cc249affcf2bedfc7a070d9e48843d27 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -1058,122 +1058,117 @@ static void sctp_outq_flush_data(struct sctp_outq *q, * chunk. */ if (!packet || !packet->has_cookie_echo) - break; + return; /* fallthru */ case SCTP_STATE_ESTABLISHED: case SCTP_STATE_SHUTDOWN_PENDING: case SCTP_STATE_SHUTDOWN_RECEIVED: - /* - * RFC 2960 6.1 Transmission of DATA Chunks - * - * C) When the time comes for the sender to transmit, - * before sending new DATA chunks, the sender MUST - * first transmit any outstanding DATA chunks which - * are marked for retransmission (limited by the - * current cwnd). - */ - if (!list_empty(&q->retransmit)) { - if (!sctp_outq_flush_rtx(q, _transport, transport_list, - rtx_timeout, gfp)) - break; - /* We may have switched current transport */ - transport = *_transport; - packet = &transport->packet; - } + break; - /* Apply Max.Burst limitation to the current transport in - * case it will be used for new data. We are going to - * rest it before we return, but we want to apply the limit - * to the currently queued data. - */ - if (transport) - sctp_transport_burst_limited(transport); - - /* Finally, transmit new packets. */ - while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { - __u32 sid = ntohs(chunk->subh.data_hdr->stream); - - /* Has this chunk expired? */ - if (sctp_chunk_abandoned(chunk)) { - sctp_sched_dequeue_done(q, chunk); - sctp_chunk_fail(chunk, 0); - sctp_chunk_free(chunk); - continue; - } + default: + /* Do nothing. */ + return; + } - if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { - sctp_outq_head_data(q, chunk); - break; - } + /* + * RFC 2960 6.1 Transmission of DATA Chunks + * + * C) When the time comes for the sender to transmit, + * before sending new DATA chunks, the sender MUST + * first transmit any outstanding DATA chunks which + * are marked for retransmission (limited by the + * current cwnd). + */ + if (!list_empty(&q->retransmit)) { + if (!sctp_outq_flush_rtx(q, _transport, transport_list, + rtx_timeout, gfp)) + return; + /* We may have switched current transport */ + transport = *_transport; + packet = &transport->packet; + } - if (sctp_outq_select_transport(chunk, asoc, _transport, - transport_list)) { - transport = *_transport; - packet = &transport->packet; - } + /* Apply Max.Burst limitation to the current transport in + * case it will be used for new data. We are going to + * rest it before we return, but we want to apply the limit + * to the currently queued data. + */ + if (transport) + sctp_transport_burst_limited(transport); - pr_debug("%s: outq:%p, chunk:%p[%s], tx-tsn:0x%x skb->head:%p " - "skb->users:%d\n", - __func__, q, chunk, chunk && chunk->chunk_hdr ? - sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) : - "illegal chunk", ntohl(chunk->subh.data_hdr->tsn), - chunk->skb ? chunk->skb->head : NULL, chunk->skb ? - refcount_read(&chunk->skb->users) : -1); - - /* Add the chunk to the packet. */ - status = sctp_packet_transmit_chunk(packet, chunk, 0, gfp); - switch (status) { - case SCTP_XMIT_OK: - break; + /* Finally, transmit new packets. */ + while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { + __u32 sid = ntohs(chunk->subh.data_hdr->stream); - case SCTP_XMIT_PMTU_FULL: - case SCTP_XMIT_RWND_FULL: - case SCTP_XMIT_DELAY: - /* We could not append this chunk, so put - * the chunk back on the output queue. - */ - pr_debug("%s: could not transmit tsn:0x%x, status:%d\n", - __func__, ntohl(chunk->subh.data_hdr->tsn), - status); + /* Has this chunk expired? */ + if (sctp_chunk_abandoned(chunk)) { + sctp_sched_dequeue_done(q, chunk); + sctp_chunk_fail(chunk, 0); + sctp_chunk_free(chunk); + continue; + } - sctp_outq_head_data(q, chunk); - return; - } + if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { + sctp_outq_head_data(q, chunk); + break; + } - /* The sender is in the SHUTDOWN-PENDING state, - * The sender MAY set the I-bit in the DATA - * chunk header. - */ - if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) - chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM; - if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) - asoc->stats.ouodchunks++; - else - asoc->stats.oodchunks++; + if (sctp_outq_select_transport(chunk, asoc, _transport, + transport_list)) { + transport = *_transport; + packet = &transport->packet; + } - /* Only now it's safe to consider this - * chunk as sent, sched-wise. + pr_debug("%s: outq:%p, chunk:%p[%s], tx-tsn:0x%x skb->head:%p " + "skb->users:%d\n", + __func__, q, chunk, chunk && chunk->chunk_hdr ? + sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) : + "illegal chunk", ntohl(chunk->subh.data_hdr->tsn), + chunk->skb ? chunk->skb->head : NULL, chunk->skb ? + refcount_read(&chunk->skb->users) : -1); + + /* Add the chunk to the packet. */ + status = sctp_packet_transmit_chunk(packet, chunk, 0, gfp); + if (status != SCTP_XMIT_OK) { + /* We could not append this chunk, so put + * the chunk back on the output queue. */ - sctp_sched_dequeue_done(q, chunk); + pr_debug("%s: could not transmit tsn:0x%x, status:%d\n", + __func__, ntohl(chunk->subh.data_hdr->tsn), + status); + + sctp_outq_head_data(q, chunk); + break; + } - list_add_tail(&chunk->transmitted_list, - &transport->transmitted); + /* The sender is in the SHUTDOWN-PENDING state, + * The sender MAY set the I-bit in the DATA + * chunk header. + */ + if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) + chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM; + if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) + asoc->stats.ouodchunks++; + else + asoc->stats.oodchunks++; - sctp_transport_reset_t3_rtx(transport); - transport->last_time_sent = jiffies; + /* Only now it's safe to consider this + * chunk as sent, sched-wise. + */ + sctp_sched_dequeue_done(q, chunk); - /* Only let one DATA chunk get bundled with a - * COOKIE-ECHO chunk. - */ - if (packet->has_cookie_echo) - break; - } - break; + list_add_tail(&chunk->transmitted_list, + &transport->transmitted); - default: - /* Do nothing. */ - break; + sctp_transport_reset_t3_rtx(transport); + transport->last_time_sent = jiffies; + + /* Only let one DATA chunk get bundled with a + * COOKIE-ECHO chunk. + */ + if (packet->has_cookie_echo) + break; } }