From patchwork Sat May 12 22:20: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: 912471 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="Lk9iNWLk"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40k1dL02tjz9s1w for ; Sun, 13 May 2018 08:21:10 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751284AbeELWVB (ORCPT ); Sat, 12 May 2018 18:21:01 -0400 Received: from mail-qt0-f196.google.com ([209.85.216.196]:42735 "EHLO mail-qt0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751110AbeELWU7 (ORCPT ); Sat, 12 May 2018 18:20:59 -0400 Received: by mail-qt0-f196.google.com with SMTP id c2-v6so11681185qtn.9; Sat, 12 May 2018 15:20:59 -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=Lk9iNWLk9jDLgtoMM0oKUt6SReZi9f64Hhk/sZLo0HpebHujnzhR28mlYYFWCP8ORh qunHv7VYoYWGXz5oGY5zgGJnv4BEyLhhOG+o1cPCg639hiPbWPVG+vPZbuB+RebSP4CL tEQj4bj1Y5eliPO60W3YZrauuhM9V3JbAAz1KvJpWnSJsLDKrNZCL/reMSidNMwTPmCR 6cSx8hkjk5OPNMPlr9wc/umTgNOb8Q0HD7g4bBhaRD2f/VvpYxn3Z3HdggIXRKi8HoKT pwVSKeyVvzIvM3X/smSOlzkqtj5MfZwi9umeD9vbq9gPjd9leTziCynmHxUo0OdaVilT m+JQ== 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=FtdAGvYFYJPAHYp3OWEwaeVF16I8yWBH2er8uBOaBF229DyToOvuQyc75hiwLgujQK c9WtTI9GCcM1VLcYRuNVuP5l2MYXz832P+Z9+He7p5a1p9yzH6FIDkwNwPLFQUSYPzMv xP/RaApqCa74sT5hMAzaX45XeXm5soPukRdrKKO9WU1AFTWibdo78qdBu4xAhlXkTvoc S3+gay3+P2N3KupCa+EyexIn1k7UtE2nUb7ayedNYgeK0/dEfiMsvzPvNpQd47JzLq8W Jn8yS5tIfVceNBgZeyZ0d9HciFRXOFmljbSWztfwE5xnesdQr8PWr+X8jOHGsz/6Eg2+ 3ETQ== X-Gm-Message-State: ALKqPwfz+mCMJEaw7mcUI64TtdZDx3hnNdnG07BOM6IHwooBuLfJVGFh 4CVMEw92dMSfOFpWMS5UtFQ= X-Google-Smtp-Source: AB8JxZp+AsEScPEvuC4gqxD3A1zAjGpwC0vCnKD1Ip5I3AKIFf0UyN/8YnOFHoMYsZcnzFW152ryug== X-Received: by 2002:a0c:9613:: with SMTP id 19-v6mr3740855qvx.211.1526163658560; Sat, 12 May 2018 15:20:58 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id l1-v6sm4965465qki.32.2018.05.12.15.20.57 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 May 2018 15:20:58 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id EB5D2180C66; Sat, 12 May 2018 19:20:55 -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 1/8] sctp: add sctp_packet_singleton Date: Sat, 12 May 2018 19:20:50 -0300 Message-Id: <3a5891776a3b203d92c22df4794b0828ac92274d.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 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 Sat May 12 22:20:58 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: 912472 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="FbJu/o7C"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40k1dL5rrFz9s28 for ; Sun, 13 May 2018 08:21:10 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751379AbeELWVE (ORCPT ); Sat, 12 May 2018 18:21:04 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:33573 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751110AbeELWVC (ORCPT ); Sat, 12 May 2018 18:21:02 -0400 Received: by mail-qt0-f194.google.com with SMTP id e8-v6so11694723qth.0; Sat, 12 May 2018 15:21: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=sFOD0cQFU2cnz5cZR1JwX9xAY4oRei+bCn2rR2n1I7U=; b=FbJu/o7Cdzc3escR49qKlRgVEqKYOIsDn9eFNFqWrxdSzWLBcuJULRh4PdqQ9TPGMI oAG/K6LC0QyOoRc3B/B/gweTh1uLwt84DNER+6oPrjiI92L0kVtY2pdo4fg8nAmbZBzt nJitjNCa7D0+iXf8b79pxuKkEc0qoFCe93LcEVwMmTB07nJbHwL+jb5pAD6wTq9XNGp2 pTeJd7FGgpI9bnsvFoI25moEogm5zQ85Zfc7YlBofw9Lrg8U1jC0sODmMmHTPl52TEdh kTwJG6FkzIXNvj3nqmFFNznKmMIR22SqnzIgkGxlDpjSmQLMrX4VbxuSd13PQdqg2DYw 8lRA== 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=CjKQdbgF2xz6AjpNzOQ40FyxrbvjXR5SJpMTGiHH8JLPb6dJzgRPzDZ5ONfP3c71oZ W5/+B1ohhexpmx6v6Os9rGn58fnKlxcgnrFff7+vbYz9rx7oAWOFRn/qcmepBtqCk1eI tjGRb9iO+xudGqHBU67NyBz2Z4LMei+OSbDlxngTUnjnXAb3b8gQzuKEvnAm0vMmu/7a o9NmnDddgkrM6CxZNkGQXEt3NkTnYa+Jx5MSuvw4Wqfz+nwQKwAtLXgzRv/Gc9x9U23G WgG29F4P8k866P0yF+3xhVN1OALL1hqgaPuUFaCuIFdU7HpFer/F7RQB2LU8BSVqHVM1 r1iw== X-Gm-Message-State: ALKqPwefgP7M4/nh5N/urhVCDZz1XfsGX1ur2zGaCFVWuD5jde6iZAFK FMoS+BdcFZJsKSatIogRBP0BdT0f X-Google-Smtp-Source: AB8JxZqRudOYUF9wlEb+WFrADI4SAOslbOFQt06lcUok4gpo1tlBiN7FhJTgoZKKPGLkJ8TpIc8iDA== X-Received: by 2002:aed:3a46:: with SMTP id n64-v6mr3619399qte.118.1526163661747; Sat, 12 May 2018 15:21:01 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id n128-v6sm3920063qkf.42.2018.05.12.15.21.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 May 2018 15:21:01 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id F2A4C180C66; Sat, 12 May 2018 19:20: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 v2 2/8] sctp: factor out sctp_outq_select_transport Date: Sat, 12 May 2018 19:20:58 -0300 Message-Id: <4b7935c08dea4610292965ad1c002843c9f98831.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 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 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; From patchwork Sat May 12 22:21:04 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: 912474 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="iB4mq4zD"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40k1dS3J1Cz9s1w for ; Sun, 13 May 2018 08:21:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751816AbeELWVL (ORCPT ); Sat, 12 May 2018 18:21:11 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:34321 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751110AbeELWVI (ORCPT ); Sat, 12 May 2018 18:21:08 -0400 Received: by mail-qt0-f194.google.com with SMTP id m5-v6so11702019qti.1; Sat, 12 May 2018 15:21:07 -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=ZOYqMlKXBHntbkPw0WRMHtHTQt4KFPs+S4ZocWHGa0A=; b=iB4mq4zDJAQ2SKOXcI3G5+nehant4G/1BhdERPVy35AUq6HJEX/jXmqPj0RBaudHwy eYkZRHYXqDXLLF+2EO0H8s8BuyNW7t+cICYDVT8Q/Av0U1WpP09/n8Ys72smCFDrobPi PoryMRlA1NMaKOXvh8UiwaNzsgaT6J5NN9MIwSmB1tF7lMzIs/jtyCDA338wk39ZqWZU 1o2bOz1VaBKK2B+VwQ3q56eD6ZWDKz/fkRGZdGyPdNw+7bVVfOddYkOK+O1U+rqluFnm CEJ3+2A0D0zqTMEJWQptiuLG7SnGE5994fkQMwZU5T8ux5Qdxm9+YXuh8uaRgY8MlL6e Q6Wg== 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=ZOYqMlKXBHntbkPw0WRMHtHTQt4KFPs+S4ZocWHGa0A=; b=s7namqt2hblektMyBtjneRjP7cfn04bNAwOs0AJwQuGZCHyHFRALFX5lnlt4yqti3w AZQxJ6NuPv4xn46DyE3GFgrKrj2Dxxs39S9v/y5YgXnUEx0QjcsSJCMg3bwLwYLKp2RW fG7c8UVZyx5pUT3HRiY6nrBzXR88082xJKNhlrEV1oxEqWLwpzkv3Hqp9o9mRE32PZq3 JvWE2hcRa3BvmF3XCuxazH2uiHYyrGEzC23/Hu+oHgV+TP4f3pmvjZuBCBnej5QUtnDx Q4nmoJa251OLkcyrEwVRtYyrm2Ft/Fn/PbDVCmbF1BX7Gbfrkvcgzvc7y+ftPPvMwkTT N2OQ== X-Gm-Message-State: ALKqPwcPqv7+Yd6orgAu6RDo1ifMw19e+CVPI2A2t/H35UV51w++p8oc bsMThEybZk1WFiXmp9UmAIQ= X-Google-Smtp-Source: AB8JxZqvA0DW2zyUoAzWHrac2EYB//JuEhJnI77FE3nrGTC5laViI9h9oeV1NLIBpM3h5WBqMnuHRA== X-Received: by 2002:a0c:fac2:: with SMTP id p2-v6mr3724182qvo.59.1526163667358; Sat, 12 May 2018 15:21:07 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id q67-v6sm5077386qki.97.2018.05.12.15.21.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 May 2018 15:21:06 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 9CA69180C66; Sat, 12 May 2018 19:21:04 -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 4/8] sctp: move outq data rtx code out of sctp_outq_flush Date: Sat, 12 May 2018 19:21:04 -0300 Message-Id: <5ca419bb19f4c6a821ba2b159f7624af6a472215.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 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 800202c68cb89f1086ee7d3a4493dc752c8bf6ac..6d7ee372a9d6b8e68a759277830d5334ec992d47 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 Sat May 12 22:21: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: 912475 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="rCynpwXt"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40k1dT3TN5z9s28 for ; Sun, 13 May 2018 08:21:17 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751868AbeELWVN (ORCPT ); Sat, 12 May 2018 18:21:13 -0400 Received: from mail-qk0-f193.google.com ([209.85.220.193]:46120 "EHLO mail-qk0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751664AbeELWVL (ORCPT ); Sat, 12 May 2018 18:21:11 -0400 Received: by mail-qk0-f193.google.com with SMTP id s70-v6so7195553qks.13; Sat, 12 May 2018 15:21:10 -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=0gvBas3a0Lbkyy5tj8P28aTiV5FSQ3oa5eCyTtbFsuY=; b=rCynpwXtkz3MpHLoVxPd4Dl+HVDygBcyDpJFS57SchEwwsv4ZEP1sKDaAtBKLquW/O gepC1aHUWOLRcpnGFbDH+D8zOOxRo54Ac6DP0+SoCQ5ddjXjHcUoEtf7vgvrYbEgT7n6 E1iXAzBGl68sOPfx6l/41NPZV9gdQ9ItBQoof26LRu7CW85JZmKCtydUwZzU73zfVFgz 3fbiRl6X9Hy8TINwcW/toAQGwrVCyEOteoR+BVr6Te717lBy5kH4ytPp9VxlBIi63khP rVJdBP54i+qTu4Da2a5h28gDX0HhV9dyG0xlrzPsh1b51q9CAJcLaTcLnxmSyIY4Jqo1 ZfSA== 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=0gvBas3a0Lbkyy5tj8P28aTiV5FSQ3oa5eCyTtbFsuY=; b=uX1Em3PY+XJrqzh8Aa/QnJxnfN7nlWfvk3AKkVijqczamDyHhIbSf+9La9+OhmZ5zf kvsgkmXlOXgy8/yRws39ONJaw4N/he3kWrTJIAGmZKF3Aj/VmW743Mg7sEmjAhkf1TxU Jeeqy+Gi9Sh1jkRfKrXOavwXaWQnzk8T9a/KBXpWLR2ISnda4y5qsbRQllXbXMeE3OpJ ysmiwxoHMrlEb/xw62l4D9jv3wH0ahcHfT2znqL/PF51HxD/MSGCeUXbXyTyZpXU1Oda nK3gV23g9B+ZSuEcl1nA+tGlFx1YYTEaRZiqw3Y3yuY9f4LG+enEZWp8G/VJSH0L9OYO xQZg== X-Gm-Message-State: ALKqPweygV/51mRkZGwr5a4PnxKZaXYIkH6cLhZ4jPQ86Il3uOIzRbnb YX2tB1oMjVRRqsMdYf4ot00= X-Google-Smtp-Source: AB8JxZoi6OwrH3TNAoo7F39TghX7OGJwf1zck2OjJNbZiQRsNv2Cg8w2fgK5+7a/KxXxwLtnhgt6eA== X-Received: by 2002:a37:9684:: with SMTP id y126-v6mr3038908qkd.297.1526163670141; Sat, 12 May 2018 15:21:10 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id e5-v6sm4442927qkf.35.2018.05.12.15.21.09 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 May 2018 15:21:09 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 649CD1811B3; Sat, 12 May 2018 19:21:07 -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 5/8] sctp: move flushing of data chunks out of sctp_outq_flush Date: Sat, 12 May 2018 19:21:06 -0300 Message-Id: <5ebf53c4ad96f127de242de572cc635f3fc969f4.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 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 | 148 ++++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 73 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 6d7ee372a9d6b8e68a759277830d5334ec992d47..7522188107792643f3bb5f00e5c254b00e91ef12 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) { @@ -1101,10 +1073,11 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) * current cwnd). */ if (!list_empty(&q->retransmit)) { - if (!sctp_outq_flush_rtx(q, &transport, &transport_list, + if (!sctp_outq_flush_rtx(q, _transport, transport_list, 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)) + if (sctp_outq_select_transport(chunk, asoc, _transport, + 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 Sat May 12 22:21:09 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: 912476 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="LDAJnavC"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40k1dX3dCkz9s1w for ; Sun, 13 May 2018 08:21:20 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751887AbeELWVR (ORCPT ); Sat, 12 May 2018 18:21:17 -0400 Received: from mail-qk0-f196.google.com ([209.85.220.196]:37568 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751664AbeELWVP (ORCPT ); Sat, 12 May 2018 18:21:15 -0400 Received: by mail-qk0-f196.google.com with SMTP id 11-v6so7214385qkk.4; Sat, 12 May 2018 15:21:14 -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=TXhH84ragmh6NOJAtm2yD8XFyzgzDbgMG3TVISR42k0=; b=LDAJnavCjxUEUG4A6fgNgK/zce6P7RcNjTKWTK0f9N4cj9yNfVuNBeE5sAqYA+wJPt 8EoFTSA6Parc+DsOywu3iInJSxCEAZPzUnANqXfqzxJlk2gIGX50HhMLzjWxTsZLL4J4 9bLhzHtis+EURMbds7hBB8YCsYPVFuNqJoZg9F7YZnahjymARV3K/YQczp7NHaEu8dTg Mm/eAf1kOIePayiBqAFJYCf8cynAp1CmlFuoy3XIb2ZO5D4Hvir7Tl8V9Wes3ISiDU5V oY2pxrT6aCjixWKAdBQQaZ9nTCeWFxzwJjDEVS0B5BGbKyKmaH+gUH/j2NuZ7XRONP9c ho7g== 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=TXhH84ragmh6NOJAtm2yD8XFyzgzDbgMG3TVISR42k0=; b=e2IWISpuQ+T5ANxp/9d4XWX+F5+demVnpEGOYtSB9NjPsDgS3SMz91lqcTdlTgWzrF nGbBsPZpqaF9EgjhSb5+s90f/XaLL4SN3jtcV2kpEwzyVViAONLiwZIeNsit/Qrl3y8G LTJJcfDsc8A6OLacgcXPzbscZeuYmL0gFrnp9JScuof4fecAVaP5EYbnZpl2n2zraAaF 9G2NwVJ7KwyvUaHadaQc41rf5cK10lr5snMM13+r0NqQ8yQvD4jKtzo3ymO0yPHJSHz5 5hBlvcodGgK2g6uWpC+uHM+eTW9fx4e7VC6FYlxB7yjc6NKoyLjF8OkDoJRAXNWi7Lv4 WMhg== X-Gm-Message-State: ALKqPwdYE8kzZN0VuqbQZlJZGHAKDQ9dVDHWu2U9fmizsDjLG79HPwNg rGaajyxFNsoyf1U6EYcPmEI= X-Google-Smtp-Source: AB8JxZqLYPDcd6YXQIm3vZ+2Y6QCCfdsTmWkpqO8fjWrrPD5/r6gmz9D/iQpBeBaTrKyt3WgEk8n2A== X-Received: by 2002:a37:175e:: with SMTP id i91-v6mr3009263qkh.308.1526163674307; Sat, 12 May 2018 15:21:14 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id g16-v6sm4361595qtp.9.2018.05.12.15.21.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 May 2018 15:21:13 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 650A4180C66; Sat, 12 May 2018 19:21:10 -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 6/8] sctp: move transport flush code out of sctp_outq_flush Date: Sat, 12 May 2018 19:21:09 -0300 Message-Id: <1e313957329f2ea6b397c7fb0fdea79e7eb65ef1.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 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 7522188107792643f3bb5f00e5c254b00e91ef12..3b738fdb08b9c596e6d4d4b18bef645187e0da4a 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 Sat May 12 22:21:12 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: 912478 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="LDPA7Zdy"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40k1dh6tpGz9s1w for ; Sun, 13 May 2018 08:21:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751906AbeELWVW (ORCPT ); Sat, 12 May 2018 18:21:22 -0400 Received: from mail-qk0-f196.google.com ([209.85.220.196]:38532 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751664AbeELWVR (ORCPT ); Sat, 12 May 2018 18:21:17 -0400 Received: by mail-qk0-f196.google.com with SMTP id b39-v6so7212276qkb.5; Sat, 12 May 2018 15:21:17 -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=cjDWheVmrr09lBdJkuUgjowHLlevmTuM2H4Rpao7hwM=; b=LDPA7ZdyiZDWgctfZn6Mt+zmMk0PqMTA+S+5IRUYLLEozFwtGgeJyaNH/6OgomkWJ5 RRS5EZINZbifCyhmVkKQgYnjTnbsJcg1RSQOYs2EtV/l9WF18SAR9ibjHtcCdjJwp92Z wB3Mevwlc5gbusHoVFf9NvsBsisFawZdx+uiHmEOVk98+Q7qaoDlnnYYN/p/c1N+Ozj0 MW1gC1SoItAY2xhxZ2Ny3ExVZbGGQsUpjfshGvDzI08578Gv+LykgaKGL23uFRfYFRxZ fWfkNK3Bjs/srjROZL0/j5oUz6GAPKC6gLhCISNCeKOfWyuLRkR3W6RwrsRT07K+bgCp J/Kw== 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=cjDWheVmrr09lBdJkuUgjowHLlevmTuM2H4Rpao7hwM=; b=X/0JjEg8Co0G4l7Sobj4v9saO9KcJzdzbW/yF2gzqlWO7yDBej6WL3cXyQ5sWhrzVQ UdfWrkgIg/zpJ4Jmp1to+orQlpoc5xTlcuMala98c5FRYBdM3mnHww7pkotsb9sRnmwS z5Qp/H77KUE0n4Aacbee48gbvYCESM35LFhjqnN9XzUVMyfinqMGB9Am9z7FHMST2cqm TgC149Z+Jgi8p4KutDXzVvIXj/d6wkDpTk2v14D+K5tsVcrAWZ5Yg/cMa7Qk1ih7oBNs MNb3NIL/LixvnAC8VJ0+972ETO6Z2TVXyW66YUzoD534SvYzaxv03QKWc/Bs17NQM9L3 varA== X-Gm-Message-State: ALKqPwdj9VpjMIQFlhzib6PPEmADZOGJu6rIPX09nlr9shQmWlaRWgHV UhzLilpnP66E3d/D+j0r3lM= X-Google-Smtp-Source: AB8JxZqpqikF3rN1Hig6Bp7ulBLh4r/Hx4gK2/Wls33ixtONu9QruSEz5ixvPVb9pwOPErcGZ6NRcQ== X-Received: by 2002:a37:129b:: with SMTP id 27-v6mr3104551qks.96.1526163676884; Sat, 12 May 2018 15:21:16 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id s69-v6sm3942638qka.61.2018.05.12.15.21.16 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 12 May 2018 15:21:16 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id 769A71811B3; Sat, 12 May 2018 19:21:13 -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 7/8] sctp: make use of gfp on retransmissions Date: Sat, 12 May 2018 19:21:12 -0300 Message-Id: <7f569955f4d33ad9c3fe797d8f650c35a602eae6.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 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 3b738fdb08b9c596e6d4d4b18bef645187e0da4a..8173dd26f5878cbf67dd7e162ac5e6b18d9a3332 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 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; } }