From patchwork Fri May 11 23:28:28 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: 912258 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="nIfoQSb9"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40jR9n6nmDz9s1b for ; Sat, 12 May 2018 09:28:45 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751386AbeEKX2k (ORCPT ); Fri, 11 May 2018 19:28:40 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:45856 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751345AbeEKX2j (ORCPT ); Fri, 11 May 2018 19:28:39 -0400 Received: by mail-qt0-f195.google.com with SMTP id j42-v6so9190260qtj.12; Fri, 11 May 2018 16:28:38 -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=YyTtGWVy0MEFTb/349RlJa2wplQBDbZzqD+E0Pe00WY=; b=nIfoQSb9NtczWQhIutNQHb7fdDZUABDK+jKA+LGowFQqQb1mYteGPukFTXDV4Ji42N ymu0Qlg8fbVNV+X43ov3ouSyyVgtjF4yOUmT19LpL/+45jIXbpoBwptdMnSXVowZ+nzz kNtTUNM8Bi/hHlTJsc0wNv0jxURefrS3GuzEZhq+w81BqnJmRTkAnfKotQKRwNE0ayL6 n12XQDjLrz1FvXtBX8KQrFiUs2HL8UgucZwynLgy2BjGLKu2bOs183CiEgDDSpZWYxDP SJeXX9VdUB35j9K15auz0xx/oOKRh7bWXFl3SRiDwYwr3HCWEImfCbA0FKNMO405JBbJ nMlg== 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=YyTtGWVy0MEFTb/349RlJa2wplQBDbZzqD+E0Pe00WY=; b=MJaLHqmKSWNRTcqMZuTN75YI8JVIef1VcB85vMjJJASm+YEfydSj8kbHgANHy6p/3X xdzZLDsx8mLjv33qredhcpeosh/6k+jjYXXVwhb8g8txUBG+822zoQBbPJURoKYHuBaM iPgp3frjPQ3sPzHsCFoKNdJocAqWD4lVcrt48tV9nsH14esqM1CqE8WSIjRJq7F1smBi 6EHjd6E6gOqmFxjnB2C17hWd8HDQZPElW34EyBPY6LxgGbku0KIsXZSJ7czw+twx55jO Au46b0sUPkp64m8UieT3E4zwr65odj+Y7Jx+V+W6t9W/aImy8cFRg6wxC+LXsur3oEzu jlrA== X-Gm-Message-State: ALKqPwetzbpYwtpCtQRp9ouPOKMLyV5yNUtrB/lflPkqtipr5zY/z27E sl7aJ1+JnH0KP/o2KjmlnTQ= X-Google-Smtp-Source: AB8JxZr1F97xHoFax3/Lp9BMkBcloW6V3UKQN6LhEz3zZarUKdas+HjTOhbQn3AdgWUw0l/lTG4YYw== X-Received: by 2002:ac8:36d1:: with SMTP id b17-v6mr83156qtc.148.1526081318270; Fri, 11 May 2018 16:28:38 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id k46-v6sm3616936qta.65.2018.05.11.16.28.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 May 2018 16:28:37 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 903C6180C3B; Fri, 11 May 2018 20:28:35 -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 1/8] sctp: add sctp_packet_singleton Date: Fri, 11 May 2018 20:28:28 -0300 Message-Id: <3a5891776a3b203d92c22df4794b0828ac92274d.1526077476.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 Factor out the code for generating singletons. It's used only once, but helps to keep the context contained. The const variables are to ease the reading of subsequent calls in there. Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index dee7cbd5483149024f2f3195db2fe4d473b1a00a..300bd0dfc7c14c9df579dbe2f9e78dd8356ae1a3 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -776,6 +776,20 @@ void sctp_outq_uncork(struct sctp_outq *q, gfp_t gfp) sctp_outq_flush(q, 0, gfp); } +static int sctp_packet_singleton(struct sctp_transport *transport, + struct sctp_chunk *chunk, gfp_t gfp) +{ + const struct sctp_association *asoc = transport->asoc; + const __u16 sport = asoc->base.bind_addr.port; + const __u16 dport = asoc->peer.port; + const __u32 vtag = asoc->peer.i.init_tag; + struct sctp_packet singleton; + + sctp_packet_init(&singleton, transport, sport, dport); + sctp_packet_config(&singleton, vtag, 0); + sctp_packet_append_chunk(&singleton, chunk); + return sctp_packet_transmit(&singleton, gfp); +} /* * Try to flush an outqueue. @@ -789,10 +803,7 @@ void sctp_outq_uncork(struct sctp_outq *q, gfp_t gfp) static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) { struct sctp_packet *packet; - struct sctp_packet singleton; struct sctp_association *asoc = q->asoc; - __u16 sport = asoc->base.bind_addr.port; - __u16 dport = asoc->peer.port; __u32 vtag = asoc->peer.i.init_tag; struct sctp_transport *transport = NULL; struct sctp_transport *new_transport; @@ -905,10 +916,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) case SCTP_CID_INIT: case SCTP_CID_INIT_ACK: case SCTP_CID_SHUTDOWN_COMPLETE: - sctp_packet_init(&singleton, transport, sport, dport); - sctp_packet_config(&singleton, vtag, 0); - sctp_packet_append_chunk(&singleton, chunk); - error = sctp_packet_transmit(&singleton, gfp); + error = sctp_packet_singleton(transport, chunk, gfp); if (error < 0) { asoc->base.sk->sk_err = -error; return; From patchwork Fri May 11 23:28:37 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: 912259 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="qip5B3La"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40jR9y4r19z9s1b for ; Sat, 12 May 2018 09:28:54 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751596AbeEKX2s (ORCPT ); Fri, 11 May 2018 19:28:48 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:40359 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751345AbeEKX2q (ORCPT ); Fri, 11 May 2018 19:28:46 -0400 Received: by mail-qt0-f194.google.com with SMTP id h2-v6so9229864qtp.7; Fri, 11 May 2018 16:28:46 -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=sFOD0cQFU2cnz5cZR1JwX9xAY4oRei+bCn2rR2n1I7U=; b=qip5B3La92U2jZcH+i4lp4t/JnElZmAI51Xgzbl6thmgINNXh+lqvbb+l9fXPv/o1l +uF8H1HR1ukEvXv7ctEXv50DrsUavln0xWjzMxeM5DMhjbGcCGzAHY00VnNDtJNhiI0V YfKcjMrYHvSoaCyc1KvERL1KO6zD5Joc1pm0XItaOclb4f0P7vIm+GrqjeSStt+XgAXP VnGLtfmc0yERh1ve7Re2S/PbLmt7O2ADdsm3+oa8cxDAO0CtlIPlBeRVmHiw4g2lXSX+ kBIskVE/gACXRzKQvQ9Q8YfuZ+dBMJNfPxswlAs815D2Ac2wCjWhZfhrZaVU0koh8aQ6 W8GQ== 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=sFOD0cQFU2cnz5cZR1JwX9xAY4oRei+bCn2rR2n1I7U=; b=k4l8lOVOya0wHf7pP5GBtc1wFpcLGzqLL0E3dNCmlfmyxlxZYXNUmT1NVLN50czZvv /SIqsuMQLzgRk7pjj6OcdPHOk77b2dO00vYI9arC3iApu69KpZXhJyMu7CQEpnmw0RZW 3Glbueg7G2FgGygPZgoY+vYEfPzAGHvo649ctn/V60cDdYAv5bKBl49amb3bEz1byON2 WtLLLJLzsHJov7vuSuY41fw6/dAGna0bkSGlaP+I2CnSVnhbLtHe1+s4LJLMaHxWQLpr up8LxKvsgZqi/rvwbxf39sr7cMV/FcRTopmfLZo4WR+O1ExvrS015osKu8YnFEHlXRzz ASvw== X-Gm-Message-State: ALKqPweLP8vvjHENzFJDLiJqQUOWkxl21iXyjDTUdtUWJnURSQ2/woBz ilcYq8FPJ4ora24foMKIduo= X-Google-Smtp-Source: AB8JxZquHWQWDhA+wd4gvjH2a6KrgAcK4OvXIgktcVp+ZNft1S185RsACZPEfKNGonww5l7VvumNug== X-Received: by 2002:aed:21c5:: with SMTP id m5-v6mr51795qtc.211.1526081325633; Fri, 11 May 2018 16:28:45 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id m8-v6sm2980998qth.24.2018.05.11.16.28.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 May 2018 16:28:45 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 2A129180C3B; Fri, 11 May 2018 20:28:43 -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 2/8] sctp: factor out sctp_outq_select_transport Date: Fri, 11 May 2018 20:28:37 -0300 Message-Id: <4b7935c08dea4610292965ad1c002843c9f98831.1526077476.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 We had two spots doing such complex operation and they were very close to each other, a bit more tailored to here or there. This patch unifies these under the same function, sctp_outq_select_transport, which knows how to handle control chunks and original transmissions (but not retransmissions). Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 187 +++++++++++++++++++++++++--------------------------- 1 file changed, 90 insertions(+), 97 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 300bd0dfc7c14c9df579dbe2f9e78dd8356ae1a3..bda50596d4bfebeac03966c5a161473df1c1986a 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -791,6 +791,90 @@ static int sctp_packet_singleton(struct sctp_transport *transport, return sctp_packet_transmit(&singleton, gfp); } +static bool sctp_outq_select_transport(struct sctp_chunk *chunk, + struct sctp_association *asoc, + struct sctp_transport **transport, + struct list_head *transport_list) +{ + struct sctp_transport *new_transport = chunk->transport; + struct sctp_transport *curr = *transport; + bool changed = false; + + if (!new_transport) { + if (!sctp_chunk_is_data(chunk)) { + /* + * If we have a prior transport pointer, see if + * the destination address of the chunk + * matches the destination address of the + * current transport. If not a match, then + * try to look up the transport with a given + * destination address. We do this because + * after processing ASCONFs, we may have new + * transports created. + */ + if (curr && sctp_cmp_addr_exact(&chunk->dest, + &curr->ipaddr)) + new_transport = curr; + else + new_transport = sctp_assoc_lookup_paddr(asoc, + &chunk->dest); + } + + /* if we still don't have a new transport, then + * use the current active path. + */ + if (!new_transport) + new_transport = asoc->peer.active_path; + } else { + __u8 type; + + switch (new_transport->state) { + case SCTP_INACTIVE: + case SCTP_UNCONFIRMED: + case SCTP_PF: + /* If the chunk is Heartbeat or Heartbeat Ack, + * send it to chunk->transport, even if it's + * inactive. + * + * 3.3.6 Heartbeat Acknowledgement: + * ... + * A HEARTBEAT ACK is always sent to the source IP + * address of the IP datagram containing the + * HEARTBEAT chunk to which this ack is responding. + * ... + * + * ASCONF_ACKs also must be sent to the source. + */ + type = chunk->chunk_hdr->type; + if (type != SCTP_CID_HEARTBEAT && + type != SCTP_CID_HEARTBEAT_ACK && + type != SCTP_CID_ASCONF_ACK) + new_transport = asoc->peer.active_path; + break; + default: + break; + } + } + + /* Are we switching transports? Take care of transport locks. */ + if (new_transport != curr) { + changed = true; + curr = new_transport; + *transport = curr; + if (list_empty(&curr->send_ready)) + list_add_tail(&curr->send_ready, transport_list); + + sctp_packet_config(&curr->packet, asoc->peer.i.init_tag, + asoc->peer.ecn_capable); + /* We've switched transports, so apply the + * Burst limit to the new transport. + */ + sctp_transport_burst_limited(curr); + } + + return changed; +} + /* * Try to flush an outqueue. * @@ -806,7 +890,6 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) struct sctp_association *asoc = q->asoc; __u32 vtag = asoc->peer.i.init_tag; struct sctp_transport *transport = NULL; - struct sctp_transport *new_transport; struct sctp_chunk *chunk, *tmp; enum sctp_xmit status; int error = 0; @@ -843,68 +926,12 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) list_del_init(&chunk->list); - /* Pick the right transport to use. */ - new_transport = chunk->transport; - - if (!new_transport) { - /* - * If we have a prior transport pointer, see if - * the destination address of the chunk - * matches the destination address of the - * current transport. If not a match, then - * try to look up the transport with a given - * destination address. We do this because - * after processing ASCONFs, we may have new - * transports created. - */ - if (transport && - sctp_cmp_addr_exact(&chunk->dest, - &transport->ipaddr)) - new_transport = transport; - else - new_transport = sctp_assoc_lookup_paddr(asoc, - &chunk->dest); - - /* if we still don't have a new transport, then - * use the current active path. - */ - if (!new_transport) - new_transport = asoc->peer.active_path; - } else if ((new_transport->state == SCTP_INACTIVE) || - (new_transport->state == SCTP_UNCONFIRMED) || - (new_transport->state == SCTP_PF)) { - /* If the chunk is Heartbeat or Heartbeat Ack, - * send it to chunk->transport, even if it's - * inactive. - * - * 3.3.6 Heartbeat Acknowledgement: - * ... - * A HEARTBEAT ACK is always sent to the source IP - * address of the IP datagram containing the - * HEARTBEAT chunk to which this ack is responding. - * ... - * - * ASCONF_ACKs also must be sent to the source. - */ - if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT && - chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT_ACK && - chunk->chunk_hdr->type != SCTP_CID_ASCONF_ACK) - new_transport = asoc->peer.active_path; - } - - /* Are we switching transports? - * Take care of transport locks. + /* Pick the right transport to use. Should always be true for + * the first chunk as we don't have a transport by then. */ - if (new_transport != transport) { - transport = new_transport; - if (list_empty(&transport->send_ready)) { - list_add_tail(&transport->send_ready, - &transport_list); - } + if (sctp_outq_select_transport(chunk, asoc, &transport, + &transport_list)) packet = &transport->packet; - sctp_packet_config(packet, vtag, - asoc->peer.ecn_capable); - } switch (chunk->chunk_hdr->type) { /* @@ -1072,43 +1099,9 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) goto sctp_flush_out; } - /* If there is a specified transport, use it. - * Otherwise, we want to use the active path. - */ - new_transport = chunk->transport; - if (!new_transport || - ((new_transport->state == SCTP_INACTIVE) || - (new_transport->state == SCTP_UNCONFIRMED) || - (new_transport->state == SCTP_PF))) - new_transport = asoc->peer.active_path; - if (new_transport->state == SCTP_UNCONFIRMED) { - WARN_ONCE(1, "Attempt to send packet on unconfirmed path."); - sctp_sched_dequeue_done(q, chunk); - sctp_chunk_fail(chunk, 0); - sctp_chunk_free(chunk); - continue; - } - - /* Change packets if necessary. */ - if (new_transport != transport) { - transport = new_transport; - - /* Schedule to have this transport's - * packet flushed. - */ - if (list_empty(&transport->send_ready)) { - list_add_tail(&transport->send_ready, - &transport_list); - } - + if (sctp_outq_select_transport(chunk, asoc, &transport, + &transport_list)) packet = &transport->packet; - sctp_packet_config(packet, vtag, - asoc->peer.ecn_capable); - /* We've switched transports, so apply the - * Burst limit to the new 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", From patchwork Fri May 11 23:28:45 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: 912260 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="FIOM1Z+7"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40jRB25SfTz9s1b for ; Sat, 12 May 2018 09:28:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751764AbeEKX24 (ORCPT ); Fri, 11 May 2018 19:28:56 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:36603 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751620AbeEKX2w (ORCPT ); Fri, 11 May 2018 19:28:52 -0400 Received: by mail-qt0-f195.google.com with SMTP id q6-v6so9230799qtn.3; Fri, 11 May 2018 16:28:51 -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=Ll/RxMd6XnZZljsiCrltObZI6tARFOZ/8w2gDd9LGJg=; b=FIOM1Z+7YttI3OBDimZej8Tj5hN2gFLVu4AU4ubmLLo3qvmc6O3fPOZhE2mD+oc+q7 HbAOe683iwjNdAyRJ/Y3+Hpp/ikkO60zGya7Xh/NysZvVI4emvezPUVwbX8k+SwLgtm/ 1jCuf4mLFNpRStjm1OYaYrGiJ1GGf86oV8ETHK1RTsY3YIt6e6noKGMIswhR0iNwPOze OZo5I2gNsHhINz336p9txYDWjycXNuIn61wSo94VTGTLSJjtv3hW4G7hOrYNHRkFPSNa GSsMwwXPC01Xa+nAvZ/WkLc7abT0RgMvRiX1l9VN2aEvzRmEl5S17sSRLQrla3UVUsF1 TSSQ== 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=Ll/RxMd6XnZZljsiCrltObZI6tARFOZ/8w2gDd9LGJg=; b=tokjYWLqSKtxAZZnYT2YZDSXrYecjiu3yXuzC4oPSRTQkqiMxoEifijfiNIcliRUKN hYQlOI51OCcqvZ/tPNnINWxoGrpuc3O4ld5HQmQRX+ef+ddCuu8dzF94pZsm/999w44Q x9eSnaITA4Ma3wAyhoAM/7voxdKpf0hl4v6EPT9MmTJzVQ95P1gASkFgqPqy2M+jQN0/ GQ2pm/OapTi70Q98M/SbJqaCJUTelvw5Fv99p6f25BZmPzKi2/f9qf1bFR5OdB8os/W1 adzqnnL9Fx9IdpeEERSjIwfOAN7Xa+gIvKaAGs2/Jq+Jtm6miNImUfVOk9qWqxfg3ysw WboA== X-Gm-Message-State: ALKqPwfqiQtl/1WmLNcK4k4eBpGWNB1xhp1XLjps/Izkq/7tfb6/5FRk Z/M1GBGSXhDcIomK8wPZFpQ= X-Google-Smtp-Source: AB8JxZrT+MXZO6sgJ+6REr1cTaRwU3AFBfZOyFoCpFkCLyZ9iCu6Cgpi5IIVBWFUqPEIV/SoNkwHjg== X-Received: by 2002:ac8:2315:: with SMTP id a21-v6mr60797qta.73.1526081331177; Fri, 11 May 2018 16:28:51 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id 193-v6sm1802810qkh.2.2018.05.11.16.28.50 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 May 2018 16:28:50 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 65F5A180C3B; Fri, 11 May 2018 20:28:48 -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 3/8] sctp: move the flush of ctrl chunks into its own function Date: Fri, 11 May 2018 20:28:45 -0300 Message-Id: <23e474529812a3e804b1a4311ec48f250b81bbc5.1526077476.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..1081e1eea703be5d65d9828c3e4265fbb7a155f9 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; From patchwork Fri May 11 23:28:50 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: 912261 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="VghP17qu"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40jRB50wQlz9s1b for ; Sat, 12 May 2018 09:29:01 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751828AbeEKX27 (ORCPT ); Fri, 11 May 2018 19:28:59 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:38850 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751664AbeEKX2z (ORCPT ); Fri, 11 May 2018 19:28:55 -0400 Received: by mail-qt0-f194.google.com with SMTP id m9-v6so9222736qtb.5; Fri, 11 May 2018 16:28:55 -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=Qknf3s8/VOzmLpY/sC8AtC87CjGfVJI2CKoLyc2FlQ4=; b=VghP17quZLCvq5kJAGItKtycPYFd6o7EUhi0LnjCYBVS0v7Dx0oG9OhIbJfnCZsAzB gyhCRuG9Cg59tjZuLN1WpFXKmbB1YTuekPE52Ygkyy5E/Sx9s+qGCUL5n+u0U6z504v0 S6bxrZiheGMnxfpS2iY988yar4V5TnjQaInuf2bY/j7Ci13sRS+Bh8TpHDFohdeOJ7Fv LFMe/zTOSALyju3tXElFKBzymfzxLXXD7EFJSa0cFltKvRQ481le8TTk0pBKdZeRTnog RZN26+nA75rL601PPYfXOFrs0izCS2tP55smPOe8bQmlEs3Ni+0lnPkEKSyule7dvPRl 65zQ== 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=Qknf3s8/VOzmLpY/sC8AtC87CjGfVJI2CKoLyc2FlQ4=; b=XW3+3npyYq0MEsHw6bVE4aTuiDxkvOvS1TuQqrSj3bEcUoIhtN/ELQmOGxiZAaKKsi rhUQp4itBTyqT2TqkC8EVC7p3/rQQsi6t12q762KPc6OUlh0mNNKFQgJxEhdrY4vFd6E iHMOoIDHW11Rgot2v9fQDxnK0aSiKLooJpAe9YAmMMlX/J+ZxeAhGiP6zJzJaxROyFck EZuM0avufp/RXc7SLzZr21fOIXHZZk157CPlxwaNoFt7DT63XuzXHKk3mpbH3P4vULdJ W4LsLYNa3NH89JSjjVjwze9kfASp4YdA86ij2wRsoJOYkVT9J13IJGHh9hGTVw/0U/9F iC/g== X-Gm-Message-State: ALKqPwe4D8Y+uNcx1j1mCFYjy22kT13nIoA2Hjp7Ar3POo3GMQ5WH/j+ 8Qqm/7ObPOqAfFnfF1wj3Gesu7IAUqs= X-Google-Smtp-Source: AB8JxZpnmDJMXBpn4xrPKjnFrsSTxv4fpu1qio9JLPeLGBekPu9NaOzN36Hn2mRB6cD6phwcr5j5gw== X-Received: by 2002:a0c:a465:: with SMTP id w92-v6mr450377qvw.46.1526081334956; Fri, 11 May 2018 16:28:54 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id y7-v6sm2981870qtn.48.2018.05.11.16.28.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 May 2018 16:28:54 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 372CF180C3B; Fri, 11 May 2018 20:28:52 -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 4/8] sctp: move outq data rtx code out of sctp_outq_flush Date: Fri, 11 May 2018 20:28:50 -0300 Message-Id: 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 This patch renames current sctp_outq_flush_rtx to __sctp_outq_flush_rtx and create a new sctp_outq_flush_rtx, with the code that was on sctp_outq_flush. Again, the idea is to have functions with small and defined objectives. Yes, there is an open-coded path selection in the now sctp_outq_flush_rtx. That is kept as is for now because it may be very different when we implement retransmission path selection algorithms for CMT-SCTP. Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 101 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 1081e1eea703be5d65d9828c3e4265fbb7a155f9..74c3961eec4fca8b4ce9bb380f8465fae4625763 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -601,14 +601,14 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, /* * Transmit DATA chunks on the retransmit queue. Upon return from - * sctp_outq_flush_rtx() the packet 'pkt' may contain chunks which + * __sctp_outq_flush_rtx() the packet 'pkt' may contain chunks which * need to be transmitted by the caller. * We assume that pkt->transport has already been set. * * The return value is a normal kernel error return value. */ -static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, - int rtx_timeout, int *start_timer) +static int __sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, + int rtx_timeout, int *start_timer) { struct sctp_transport *transport = pkt->transport; struct sctp_chunk *chunk, *chunk1; @@ -987,6 +987,57 @@ static void sctp_outq_flush_ctrl(struct sctp_outq *q, } } +/* Returns false if new data shouldn't be sent */ +static bool sctp_outq_flush_rtx(struct sctp_outq *q, + struct sctp_transport **_transport, + struct list_head *transport_list, + int rtx_timeout) +{ + struct sctp_transport *transport = *_transport; + struct sctp_packet *packet = transport ? &transport->packet : NULL; + struct sctp_association *asoc = q->asoc; + int error, start_timer = 0; + + if (asoc->peer.retran_path->state == SCTP_UNCONFIRMED) + return false; + + if (transport != asoc->peer.retran_path) { + /* Switch transports & prepare the packet. */ + transport = asoc->peer.retran_path; + *_transport = transport; + + if (list_empty(&transport->send_ready)) + list_add_tail(&transport->send_ready, + transport_list); + + packet = &transport->packet; + sctp_packet_config(packet, asoc->peer.i.init_tag, + asoc->peer.ecn_capable); + } + + error = __sctp_outq_flush_rtx(q, packet, rtx_timeout, &start_timer); + if (error < 0) + asoc->base.sk->sk_err = -error; + + if (start_timer) { + sctp_transport_reset_t3_rtx(transport); + transport->last_time_sent = jiffies; + } + + /* This can happen on COOKIE-ECHO resend. Only + * one chunk can get bundled with a COOKIE-ECHO. + */ + if (packet->has_cookie_echo) + return false; + + /* Don't send new data if there is still data + * waiting to retransmit. + */ + if (!list_empty(&q->retransmit)) + return false; + + return true; +} /* * Try to flush an outqueue. * @@ -1000,12 +1051,10 @@ 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; @@ -1052,45 +1101,11 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) * current cwnd). */ if (!list_empty(&q->retransmit)) { - if (asoc->peer.retran_path->state == SCTP_UNCONFIRMED) - goto sctp_flush_out; - if (transport == asoc->peer.retran_path) - goto retran; - - /* Switch transports & prepare the packet. */ - - transport = asoc->peer.retran_path; - - if (list_empty(&transport->send_ready)) { - list_add_tail(&transport->send_ready, - &transport_list); - } - + if (!sctp_outq_flush_rtx(q, _transport, transport_list, + rtx_timeout)) + break; + /* We may have switched current transport */ packet = &transport->packet; - sctp_packet_config(packet, vtag, - asoc->peer.ecn_capable); - retran: - error = sctp_outq_flush_rtx(q, packet, - rtx_timeout, &start_timer); - if (error < 0) - asoc->base.sk->sk_err = -error; - - if (start_timer) { - sctp_transport_reset_t3_rtx(transport); - transport->last_time_sent = jiffies; - } - - /* This can happen on COOKIE-ECHO resend. Only - * one chunk can get bundled with a COOKIE-ECHO. - */ - if (packet->has_cookie_echo) - goto sctp_flush_out; - - /* Don't send new data if there is still data - * waiting to retransmit. - */ - if (!list_empty(&q->retransmit)) - goto sctp_flush_out; } /* Apply Max.Burst limitation to the current transport in From patchwork Fri May 11 23:28:54 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: 912263 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="aP5CAqnK"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40jRBL0kNWz9s1b for ; Sat, 12 May 2018 09:29:14 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751904AbeEKX3F (ORCPT ); Fri, 11 May 2018 19:29:05 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:33151 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751839AbeEKX3C (ORCPT ); Fri, 11 May 2018 19:29:02 -0400 Received: by mail-qt0-f195.google.com with SMTP id e8-v6so9229692qth.0; Fri, 11 May 2018 16:29:02 -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=MF+1Vzdkx8INNFVva+5QHuSToF5o4w6WTl2iEZ8rits=; b=aP5CAqnKw8jyjFfZ8xD2oGAMgtS6sPgtCaECK+FBNQ8pKIHhykbSyP8U0bSAEfh6O0 lqg8RVcj9pHOc0cXiUcSSK0ZkvFIgOkAUjTAt8hC21Q+cRt5n+6a1mn+R9jBsON56nmf CwDu8zUPPeg48EC1iKMqAuaktXNlsypth63y5NkSImBakFaAGQUkuxFCwwk4rihvHl5O CJRET8lfLm34c/Og/rcCXGQhZIrPowB0+hILpHjBoxzMscs9Uhj0BiODcwZOcvZ4xW3b u5Pby1bL4+BwQkoekmv06Mb75y9f4AxKjSqNsS9/lXfpKaIVOPVHQiLZrIA99tFJbcH0 g64Q== 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=MF+1Vzdkx8INNFVva+5QHuSToF5o4w6WTl2iEZ8rits=; b=PEgWAv0NM+qXYnOJNj9UuSTR6G2oaB+hoP5u6IlF8syyJZs7rHLoGU9xZPVhyuW/xC CpcaNR/eOwjlgODTgm47ZfuSb0oz1m6E3HwKXAX/6OgfxDdMWik4r+7oBQK6O2U/uS/V KZT+464miH8178WmlQhdYtv7Brijwjt7fWwq/eVcHesOWFacYnkG5S8QuMQtNiEOten/ rU698/zKp3RxXzYfS8O21Y93cpBhcnBtmkE6APC0vY9czKIhsSuwE0Hu0B6thW8uEbuL A1SVj3n+vXM13sXAVvbdKi4zF/hQ7skpQVSwMHkS02oLK7X1XKw9ddrO/ZXmsIqzzXn3 6a7g== X-Gm-Message-State: ALKqPwc7AcoebeV4FU7POz20xykuMNUvnIjLdDQeKLrLzMBV0cksacwk Rzo0oZ7vxC+4mvGmAuDLLtqteoQEbmo= X-Google-Smtp-Source: AB8JxZqkVnf8cgi/u0hRZGlhVWpQ5WH6h5O95GnwT0U0wCmzsupv5M6Sdsco7IyJAiZWjMMow1qczw== X-Received: by 2002:ac8:2c56:: with SMTP id e22-v6mr88148qta.74.1526081341405; Fri, 11 May 2018 16:29:01 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id e23-v6sm3043141qtp.19.2018.05.11.16.29.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 May 2018 16:29:00 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 4FE37180C3B; Fri, 11 May 2018 20:28:58 -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 5/8] sctp: move flushing of data chunks out of sctp_outq_flush Date: Fri, 11 May 2018 20:28:54 -0300 Message-Id: <5bb63f578cf2084164e4de817f333b3e59178318.1526077476.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 To the new sctp_outq_flush_data. Again, smaller functions and with well defined objectives. Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 144 ++++++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 71 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 74c3961eec4fca8b4ce9bb380f8465fae4625763..e445a59db26004553984088d50e458a93b03dcb8 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -1038,45 +1038,17 @@ static bool sctp_outq_flush_rtx(struct sctp_outq *q, return true; } -/* - * 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_data(struct sctp_outq *q, + struct sctp_transport **_transport, + struct list_head *transport_list, + int rtx_timeout, gfp_t gfp) { - struct sctp_packet *packet; + struct sctp_transport *transport = *_transport; + struct sctp_packet *packet = transport ? &transport->packet : NULL; struct sctp_association *asoc = q->asoc; - struct sctp_transport *transport = NULL; struct sctp_chunk *chunk; enum sctp_xmit status; - int error = 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; /* Is it OK to send data chunks? */ switch (asoc->state) { @@ -1105,6 +1077,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) rtx_timeout)) break; /* We may have switched current transport */ + transport = *_transport; packet = &transport->packet; } @@ -1130,12 +1103,14 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { sctp_outq_head_data(q, chunk); - goto sctp_flush_out; + break; } if (sctp_outq_select_transport(chunk, asoc, &transport, - &transport_list)) + &transport_list)) { + transport = *_transport; packet = &transport->packet; + } pr_debug("%s: outq:%p, chunk:%p[%s], tx-tsn:0x%x skb->head:%p " "skb->users:%d\n", @@ -1147,8 +1122,10 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) /* Add the chunk to the packet. */ status = sctp_packet_transmit_chunk(packet, chunk, 0, gfp); - switch (status) { + case SCTP_XMIT_OK: + break; + case SCTP_XMIT_PMTU_FULL: case SCTP_XMIT_RWND_FULL: case SCTP_XMIT_DELAY: @@ -1160,41 +1137,25 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) status); sctp_outq_head_data(q, chunk); - goto sctp_flush_out; - - case SCTP_XMIT_OK: - /* 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++; - - /* Only now it's safe to consider this - * chunk as sent, sched-wise. - */ - sctp_sched_dequeue_done(q, chunk); - - break; - - default: - BUG(); + return; } - /* BUG: We assume that the sctp_packet_transmit() - * call below will succeed all the time and add the - * chunk to the transmitted list and restart the - * timers. - * It is possible that the call can fail under OOM - * conditions. - * - * Is this really a problem? Won't this behave - * like a lost TSN? + /* 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++; + + /* Only now it's safe to consider this + * chunk as sent, sched-wise. + */ + sctp_sched_dequeue_done(q, chunk); + list_add_tail(&chunk->transmitted_list, &transport->transmitted); @@ -1205,7 +1166,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) * COOKIE-ECHO chunk. */ if (packet->has_cookie_echo) - goto sctp_flush_out; + break; } break; @@ -1213,6 +1174,47 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) /* Do nothing. */ break; } +} + +/* + * 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; + struct sctp_transport *transport = NULL; + int error = 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; + + sctp_outq_flush_data(q, &transport, &transport_list, rtx_timeout, gfp); sctp_flush_out: From patchwork Fri May 11 23:29:00 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: 912264 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="YuV6bSKi"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40jRBM1Kzzz9s28 for ; Sat, 12 May 2018 09:29:15 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751934AbeEKX3L (ORCPT ); Fri, 11 May 2018 19:29:11 -0400 Received: from mail-qt0-f196.google.com ([209.85.216.196]:41276 "EHLO mail-qt0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751217AbeEKX3H (ORCPT ); Fri, 11 May 2018 19:29:07 -0400 Received: by mail-qt0-f196.google.com with SMTP id g13-v6so9212376qth.8; Fri, 11 May 2018 16:29:06 -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=0/XDajZmSqnFkjfwUvOsxj+w+PIbnj/kG1MmjkGY6d0=; b=YuV6bSKi+TpC7zjqe3StDMg1SPdXlB+WFIqwZYlQpAFJCLYiHVkzlbCBYTekE5RWLS G/dRCXaOeTTv5BcL2BxV2H/sGy1vIxv4mOMy8/Ez/JnbtQPptf2hx0SbGEjWisbz0L1N +IzJhAZv1PjGQfUvU8RX7Gg4/JwkbLJIVo7bt+CKQEBTyLqvyc2uj9uEjyGVa03p8ABX z38dRprL85/PGOFfgQL9wE6zpdTJCTxNw1q97GRNSi1hDl84kjND+IiuX/8mMhgOdDSf +3eXArTB1lkGQAQrelQhMq20Z7LkNFYI0t2XLNWtBzPc2tj+3L+5qGBeg9X2/rqhK0rL uJsA== 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=0/XDajZmSqnFkjfwUvOsxj+w+PIbnj/kG1MmjkGY6d0=; b=lA/4/5LsMhSgPxVj2NLHHvr/Y08DeC+J55EJ0QCQjSzh9PDdrmR5sHtGHMkVdEViTd NUTHUn6INUozcSo+4pQmcJX/deo+1JEZM09FG0b463aLKtyXuFvwjPaMhqPnslkBZF5o M57kaUKistLFDJ8ORaPvegHNcAX/g/ieJuC7olQ7pRpeYntxQW7QCLBb5vs5OZ71lsVA yXzbkySW7mHqPuB0Kwt9g5sY86W7E7NZw3EhPAlQT6oZjZXT8SurqTJzZo9ce7LFuOGI Vb10pxaxhY0Z3+yWnctM9M8FHFXpnvn8qDRqnkUyfuZRZczZemFlh1TDDxRfX3AqlBsp 9GBw== X-Gm-Message-State: ALKqPwd3MYrrK0S9kmLH/FkODjD0bJ7vs7w47+QF2iPXRUpgBFGN2+Fn Xej8xA7bWFBJGF3VYu/5G0I= X-Google-Smtp-Source: AB8JxZpg7JJAh49nw9f/L6nux83VDusET9Q/KAmxgms9/96oebkYXnerEL/er4pXk8yj9PjRHguGRQ== X-Received: by 2002:a0c:9557:: with SMTP id m23-v6mr426485qvm.142.1526081346407; Fri, 11 May 2018 16:29:06 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id t22-v6sm3526418qtj.63.2018.05.11.16.29.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 May 2018 16:29:05 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id E7037180C3B; Fri, 11 May 2018 20:29:03 -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 6/8] sctp: move transport flush code out of sctp_outq_flush Date: Fri, 11 May 2018 20:29:00 -0300 Message-Id: <0b335685619527018d1209580a8ac25d3d610d12.1526077476.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 To the new sctp_outq_flush_transports. Comment on Nagle is outdated and removed. Nagle is performed earlier, while checking if the chunk fits the packet: if the outq length is not enough to fill the packet, it returns SCTP_XMIT_DELAY. So by when it gets to sctp_outq_flush_transports, it has to go through all enlisted transports. Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 56 +++++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index e445a59db26004553984088d50e458a93b03dcb8..e867bde0b2d93f730f0cb89ad2f54a2094f47833 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -1176,6 +1176,29 @@ static void sctp_outq_flush_data(struct sctp_outq *q, } } +static void sctp_outq_flush_transports(struct sctp_outq *q, + struct list_head *transport_list, + gfp_t gfp) +{ + struct list_head *ltransport; + struct sctp_packet *packet; + struct sctp_transport *t; + int error = 0; + + while ((ltransport = sctp_list_dequeue(transport_list)) != NULL) { + t = list_entry(ltransport, struct sctp_transport, send_ready); + packet = &t->packet; + if (!sctp_packet_empty(packet)) { + error = sctp_packet_transmit(packet, gfp); + if (error < 0) + q->asoc->base.sk->sk_err = -error; + } + + /* Clear the burst limited state, if any */ + sctp_transport_burst_reset(t); + } +} + /* * Try to flush an outqueue. * @@ -1187,17 +1210,10 @@ static void sctp_outq_flush_data(struct sctp_outq *q, */ 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; + /* Current transport being used. It's NOT the same as curr active one */ struct sctp_transport *transport = NULL; - int error = 0; - /* These transports have chunks to send. */ - struct list_head transport_list; - struct list_head *ltransport; - - INIT_LIST_HEAD(&transport_list); - packet = NULL; + LIST_HEAD(transport_list); /* * 6.10 Bundling @@ -1218,27 +1234,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) sctp_flush_out: - /* Before returning, examine all the transports touched in - * this call. Right now, we bluntly force clear all the - * transports. Things might change after we implement Nagle. - * But such an examination is still required. - * - * --xguo - */ - while ((ltransport = sctp_list_dequeue(&transport_list)) != NULL) { - struct sctp_transport *t = list_entry(ltransport, - struct sctp_transport, - send_ready); - packet = &t->packet; - if (!sctp_packet_empty(packet)) { - error = sctp_packet_transmit(packet, gfp); - if (error < 0) - asoc->base.sk->sk_err = -error; - } - - /* Clear the burst limited state, if any */ - sctp_transport_burst_reset(t); - } + sctp_outq_flush_transports(q, &transport_list, gfp); } /* Update unack_data based on the incoming SACK chunk */ From patchwork Fri May 11 23:29:06 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: 912266 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="D1nbL6pI"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40jRBZ4ppDz9s1w for ; Sat, 12 May 2018 09:29:26 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751962AbeEKX3Y (ORCPT ); Fri, 11 May 2018 19:29:24 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:33191 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751217AbeEKX3X (ORCPT ); Fri, 11 May 2018 19:29:23 -0400 Received: by mail-qt0-f194.google.com with SMTP id e8-v6so9230387qth.0; Fri, 11 May 2018 16:29:22 -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=yfqDvCuAx0IObeMIHUvy09jUwjWo3UwhGt5amPN8o3U=; b=D1nbL6pIi/4Qv1/big7ZQNPrXzMasXiJc7ZiQQW3TvZSJ0iF2qQR59p2zEiTd61xVP Tm/IkMY0gUJWWEJJk/sgXLzQyXedR7b/ewSDDlEKzBUSaU5RdZvCCRugSK2cX8PQqTEa NVAygKcTR/gnz6sHh1lNwhf66oHBIwAaUJonEmwAgpKpyee1ZA5D2zYkSVt7N9CGqZjU Qn2vV6x4kVws8MoPCZHRnp5kGjddK1DmE9XQdIiAlK8UcAGYr6VAGBU3tOZIoSv15YI0 Hj/NP7INApd+kIhR56V3d3588PcWVBcq3EXjwCbgVbI4HxdT3hrOCnDl62b7n2xGwq3y UQpw== 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=yfqDvCuAx0IObeMIHUvy09jUwjWo3UwhGt5amPN8o3U=; b=MHbUNPFNi2xP58iSbXJJI4L5H9pXQUWtmvRErJVYFYM/wd4AY4L2b3qtjMGbZ+sJYe Wji5T1wws8Kgp/XKap82MB39pV12pbJB1r+ZPlHtLaKlwLYxqjls7aF0MbVfh+1ryzVl JCM3LyxnoldomBqTlxchXioG4Mu/wkkhUbv89O8m8qaa0gr8p4qsfmu9oZG+lFQX0dgI xyWbVkZOu5cmhL4XlcKbKLaJUiEHLkca9qtI25hQzNnc4C//hP136Go7a0HdgR9a5PDy Ega/GrrQciop8cs/vGQ0zMDNEM8QB2ecrO8kMf41K+x2W0Wz5HqcpKjZc/pFdF8nWCrF BQAg== X-Gm-Message-State: ALKqPwc7ez+VOPaslOH7WN8IlhuSecyIlCS9rn6XTnk/ftJcnMCo4Wia fDd6UOyARRKCBQBK4uyYyCCgx67Xlr8= X-Google-Smtp-Source: AB8JxZpqKYb7WHp7v3lhbVPUEeZz8dIs7ZxtzrholtSrdgPNR+/cfya7Dmqef8aCINuUpD9haMmE6g== X-Received: by 2002:ac8:361:: with SMTP id w33-v6mr87086qtg.58.1526081362125; Fri, 11 May 2018 16:29:22 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id 42-v6sm3349846qte.41.2018.05.11.16.29.21 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 May 2018 16:29:21 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id C9690180C3B; Fri, 11 May 2018 20:29:19 -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 7/8] sctp: make use of gfp on retransmissions Date: Fri, 11 May 2018 20:29:06 -0300 Message-Id: <4f25778a5e79d1c39b22dfec82b30af96476dbeb.1526077476.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 Retransmissions may be triggered when in user context, so lets make use of gfp. Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index e867bde0b2d93f730f0cb89ad2f54a2094f47833..388e0665057be6ca7864b8bfdc0925e95e8b2858 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -608,7 +608,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, * The return value is a normal kernel error return value. */ static int __sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, - int rtx_timeout, int *start_timer) + int rtx_timeout, int *start_timer, gfp_t gfp) { struct sctp_transport *transport = pkt->transport; struct sctp_chunk *chunk, *chunk1; @@ -684,12 +684,12 @@ static int __sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, * control chunks are already freed so there * is nothing we can do. */ - sctp_packet_transmit(pkt, GFP_ATOMIC); + sctp_packet_transmit(pkt, gfp); goto redo; } /* Send this packet. */ - error = sctp_packet_transmit(pkt, GFP_ATOMIC); + error = sctp_packet_transmit(pkt, gfp); /* If we are retransmitting, we should only * send a single packet. @@ -705,7 +705,7 @@ static int __sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, case SCTP_XMIT_RWND_FULL: /* Send this packet. */ - error = sctp_packet_transmit(pkt, GFP_ATOMIC); + error = sctp_packet_transmit(pkt, gfp); /* Stop sending DATA as there is no more room * at the receiver. @@ -715,7 +715,7 @@ static int __sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, case SCTP_XMIT_DELAY: /* Send this packet. */ - error = sctp_packet_transmit(pkt, GFP_ATOMIC); + error = sctp_packet_transmit(pkt, gfp); /* Stop sending DATA because of nagle delay. */ done = 1; @@ -991,7 +991,7 @@ static void sctp_outq_flush_ctrl(struct sctp_outq *q, static bool sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_transport **_transport, struct list_head *transport_list, - int rtx_timeout) + int rtx_timeout, gfp_t gfp) { struct sctp_transport *transport = *_transport; struct sctp_packet *packet = transport ? &transport->packet : NULL; @@ -1015,7 +1015,8 @@ static bool sctp_outq_flush_rtx(struct sctp_outq *q, asoc->peer.ecn_capable); } - error = __sctp_outq_flush_rtx(q, packet, rtx_timeout, &start_timer); + error = __sctp_outq_flush_rtx(q, packet, rtx_timeout, &start_timer, + gfp); if (error < 0) asoc->base.sk->sk_err = -error; @@ -1074,7 +1075,7 @@ static void sctp_outq_flush_data(struct sctp_outq *q, */ if (!list_empty(&q->retransmit)) { if (!sctp_outq_flush_rtx(q, _transport, transport_list, - rtx_timeout)) + rtx_timeout, gfp)) break; /* We may have switched current transport */ transport = *_transport; From patchwork Fri May 11 23:29:22 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: 912267 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="gf2wr0dv"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40jRBs2Gj9z9s1w for ; Sat, 12 May 2018 09:29:41 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752014AbeEKX3i (ORCPT ); Fri, 11 May 2018 19:29:38 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:41339 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751217AbeEKX3g (ORCPT ); Fri, 11 May 2018 19:29:36 -0400 Received: by mail-qt0-f194.google.com with SMTP id g13-v6so9213315qth.8; Fri, 11 May 2018 16:29:35 -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=OR4rZMfdI+zWbh8EWkG78zgT8LEOtwHoZAFtRHuHazw=; b=gf2wr0dvOte1beICo2w+PtXseZhtqhfDur74u5POZ5Aval5cBpp+aJsDQ43sVDgasb 2ziMMPEZQiOabNMZ5V/7BY00WBQiVaAtvxpOpMVCWQTyEQuDhFIhdpVAaQ5HVdo/NIlA O8SDwvooBQK98GZ2DqtF8QMI0MrbTmGPOs9DWdMU9JZmi+8oIFI0qm3qWffRqjEGdkDJ M7KmPRmeLU27f55TEDH8uMpR3QGNt2qUA1zkRsfwW/j2hH6W44cUIK/KwJFQ7hQvxb3/ FmEYvuJoo1JcEX5TGUBe5lskjIrOx3dBek+oi2wkJi+WuC3dkRREYyu1tUyiLEF4TOJp 7SZw== 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=OR4rZMfdI+zWbh8EWkG78zgT8LEOtwHoZAFtRHuHazw=; b=FC51t9c83GjEvFvwTh3lqW/R1FmdjXDoyQFERoiCqurKrh1F9sAfXMqmyqIKUj0mAM R71goJeznyX2PPaD0SX2duL4ZbOVqDkItb+nwpMZS8vEXhvk9wr2BIb+HxctSDdSkPa9 +hatMB440KpQ7EYqOy2xM/sABSpW2ce/WVzou685lKDBrL9k+DKMyLIaY9J3AaHjF1wB xTwre6/4gvfbF/jP/VZUxtxEPkCQGXq1BrddqcQR7MaKX0djDtLtF879CUd6Ar9elZ77 M+XKB7OSOoAF7FIOLKF3yey+AfAXcIsS8xGUPNGVX631GkDWLj03CE3woUM71W+CODdZ CIGQ== X-Gm-Message-State: ALKqPwcCQZuLAmcROl8TsPTsU6HxxcuTyniiw+oBEyO+ACTicdoA+SOV NeToZZMJIGRB5/4J5yBsU4o= X-Google-Smtp-Source: AB8JxZplrwejIUO0oymEh0zxj+aINj745ncFbJLc8PZvWcamqCRYMcswZ366xOXpMUXXJxWiYPIhPA== X-Received: by 2002:ac8:3343:: with SMTP id u3-v6mr64972qta.55.1526081375242; Fri, 11 May 2018 16:29:35 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id z135-v6sm3305061qka.1.2018.05.11.16.29.34 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 11 May 2018 16:29:34 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 87954180C3B; Fri, 11 May 2018 20:29:32 -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 8/8] sctp: rework switch cases in sctp_outq_flush_data Date: Fri, 11 May 2018 20:29:22 -0300 Message-Id: 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 388e0665057be6ca7864b8bfdc0925e95e8b2858..c7f65bcd7bd6ee6996080d091bda1651f7bb8c44 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); - list_add_tail(&chunk->transmitted_list, - &transport->transmitted); + sctp_outq_head_data(q, chunk); + break; + } - sctp_transport_reset_t3_rtx(transport); - transport->last_time_sent = jiffies; + /* 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++; - /* Only let one DATA chunk get bundled with a - * COOKIE-ECHO chunk. - */ - if (packet->has_cookie_echo) - break; - } - break; + /* Only now it's safe to consider this + * chunk as sent, sched-wise. + */ + sctp_sched_dequeue_done(q, chunk); - default: - /* Do nothing. */ - break; + list_add_tail(&chunk->transmitted_list, + &transport->transmitted); + + 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; } }