From patchwork Sat May 12 22:21:01 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: 912473 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="lCm7O0LU"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40k1dM49syz9s1w for ; Sun, 13 May 2018 08:21:11 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751634AbeELWVH (ORCPT ); Sat, 12 May 2018 18:21:07 -0400 Received: from mail-qt0-f196.google.com ([209.85.216.196]:36610 "EHLO mail-qt0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751110AbeELWVF (ORCPT ); Sat, 12 May 2018 18:21:05 -0400 Received: by mail-qt0-f196.google.com with SMTP id q6-v6so11698780qtn.3; Sat, 12 May 2018 15:21:05 -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=sPYPHsAK04S8RGS49s6tHqVbn4v5ztrIWaz0ryTaGCg=; b=lCm7O0LUDohcBB5CVmInha+wEccMsAEus/u8Lry8m6u1nbfTNyBUvAXD3kxkEQap5D HuFSMgfjjPzymV3nAyjCcB/NrqkWa6ALtbcdOEhzplcKhRTM79icOztQTsiIMp3jmq8V 8dWQUsP6kYU1Ts4LOAwC/ZOn6+51mZNSSXfPk00+Dl0eK9xSVF1bYQjIszCHsjLfWK+O LUeIGvhDv9JYybUzO8/jPwKeEhaS1YUIz909tCo4Dgb5yVBWeuK7uiwIX+cpfj/gXoF4 XndiiONKbf4VdjrdL2WokIb2YI+OrB8MDY8GPv8p3hTq3yJpOOdafq6N8/gLqSTqXNF0 kTdQ== 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=sPYPHsAK04S8RGS49s6tHqVbn4v5ztrIWaz0ryTaGCg=; b=kL10fXmD8chNKAgUg5nTgbF7cDXLriyOYqEsVUdMeSDSPoOokyLQRcV34KnDpBw0Re MWFCL3FYmUHS03w6TeLsDP4ghFnWQx6KqFPghXD+jPzVEa2no9pnFqIsaL52Xao0hIQq dGTdT7rcaE40c7B+IVJ9zzKyQO5QQFyYrON6XU1N9l5kswSr3HRDdWGRpGXpMvEkt9d7 ursZWsr1NHhnILTm4apezHSzbfjnjgUFVU9Wb60+6ZgQ9NvRYTY4p8dCjK2Cc4WzCFhc bOZBQtIwL5ip6bSc8AduQ8mMjIha4x88fCO5YODSjjXhNcao5xIpHfWEScTkvWMccrLP gP/A== X-Gm-Message-State: ALKqPwehs8f0QyvWJAp5XUAlDMYmR3n1fFcoOM5L7/Z0/jDcWdc54Iag cojkM9ZFb26TLaOBLJ3MIbM= X-Google-Smtp-Source: AB8JxZoS4+yv3AQddBbmmB6EbA3b/GZDtiY/N/Gp3g4hNV4f35R/7fnLpNzUutKFEyp2fhi9j89E9g== X-Received: by 2002:ac8:2c98:: with SMTP id 24-v6mr3470581qtw.420.1526163664533; Sat, 12 May 2018 15:21:04 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id u24-v6sm5123878qku.18.2018.05.12.15.21.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 May 2018 15:21:04 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id CC8031811B3; Sat, 12 May 2018 19:21:01 -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 3/8] sctp: move the flush of ctrl chunks into its own function Date: Sat, 12 May 2018 19:21:01 -0300 Message-Id: <629f02a784ff90761adee451a870c7548069287d.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 Named sctp_outq_flush_ctrl and, with that, keep the contexts contained. One small fix embedded is the reset of one_packet at every iteration. This allows bundling of some control chunks in case they were preceded by another control chunk that cannot be bundled. Other than this, it has the same behavior. Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 89 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 35 deletions(-) -- 2.14.3 diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index bda50596d4bfebeac03966c5a161473df1c1986a..800202c68cb89f1086ee7d3a4493dc752c8bf6ac 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -875,45 +875,21 @@ static bool sctp_outq_select_transport(struct sctp_chunk *chunk, return changed; } -/* - * Try to flush an outqueue. - * - * Description: Send everything in q which we legally can, subject to - * congestion limitations. - * * Note: This function can be called from multiple contexts so appropriate - * locking concerns must be made. Today we use the sock lock to protect - * this function. - */ -static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) +static void sctp_outq_flush_ctrl(struct sctp_outq *q, + struct sctp_transport **_transport, + struct list_head *transport_list, + gfp_t gfp) { - struct sctp_packet *packet; + struct sctp_transport *transport = *_transport; struct sctp_association *asoc = q->asoc; - __u32 vtag = asoc->peer.i.init_tag; - struct sctp_transport *transport = NULL; + struct sctp_packet *packet = NULL; struct sctp_chunk *chunk, *tmp; enum sctp_xmit status; - int error = 0; - int start_timer = 0; - int one_packet = 0; - - /* These transports have chunks to send. */ - struct list_head transport_list; - struct list_head *ltransport; - - INIT_LIST_HEAD(&transport_list); - packet = NULL; - - /* - * 6.10 Bundling - * ... - * When bundling control chunks with DATA chunks, an - * endpoint MUST place control chunks first in the outbound - * SCTP packet. The transmitter MUST transmit DATA chunks - * within a SCTP packet in increasing order of TSN. - * ... - */ + int one_packet, error; list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { + one_packet = 0; + /* RFC 5061, 5.3 * F1) This means that until such time as the ASCONF * containing the add is acknowledged, the sender MUST @@ -930,8 +906,10 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) * the first chunk as we don't have a transport by then. */ if (sctp_outq_select_transport(chunk, asoc, &transport, - &transport_list)) + transport_list)) { + transport = *_transport; packet = &transport->packet; + } switch (chunk->chunk_hdr->type) { /* @@ -954,6 +932,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) if (sctp_test_T_bit(chunk)) packet->vtag = asoc->c.my_vtag; /* fallthru */ + /* The following chunks are "response" chunks, i.e. * they are generated in response to something we * received. If we are sending these, then we can @@ -979,7 +958,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) case SCTP_CID_RECONF: status = sctp_packet_transmit_chunk(packet, chunk, one_packet, gfp); - if (status != SCTP_XMIT_OK) { + if (status != SCTP_XMIT_OK) { /* put the chunk back */ list_add(&chunk->list, &q->control_chunk_list); break; @@ -1006,6 +985,46 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) BUG(); } } +} + +/* + * Try to flush an outqueue. + * + * Description: Send everything in q which we legally can, subject to + * congestion limitations. + * * Note: This function can be called from multiple contexts so appropriate + * locking concerns must be made. Today we use the sock lock to protect + * this function. + */ +static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) +{ + struct sctp_packet *packet; + struct sctp_association *asoc = q->asoc; + __u32 vtag = asoc->peer.i.init_tag; + struct sctp_transport *transport = NULL; + struct sctp_chunk *chunk; + enum sctp_xmit status; + int error = 0; + int start_timer = 0; + + /* These transports have chunks to send. */ + struct list_head transport_list; + struct list_head *ltransport; + + INIT_LIST_HEAD(&transport_list); + packet = NULL; + + /* + * 6.10 Bundling + * ... + * When bundling control chunks with DATA chunks, an + * endpoint MUST place control chunks first in the outbound + * SCTP packet. The transmitter MUST transmit DATA chunks + * within a SCTP packet in increasing order of TSN. + * ... + */ + + sctp_outq_flush_ctrl(q, &transport, &transport_list, gfp); if (q->asoc->src_out_of_asoc_ok) goto sctp_flush_out;