From patchwork Mon May 14 17:35:18 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: 913157 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="soZB5K5U"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40l7C46rq9z9s0W for ; Tue, 15 May 2018 03:35:44 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753268AbeENRff (ORCPT ); Mon, 14 May 2018 13:35:35 -0400 Received: from mail-qt0-f196.google.com ([209.85.216.196]:41301 "EHLO mail-qt0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753067AbeENRfc (ORCPT ); Mon, 14 May 2018 13:35:32 -0400 Received: by mail-qt0-f196.google.com with SMTP id g13-v6so17194287qth.8; Mon, 14 May 2018 10:35:32 -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=z6Ed8ScgBjo/U9wVH8qEIkibAMIwz7J26jo91ZEe0DM=; b=soZB5K5UQHprdyjiRVnSK+0GfLRm+ny+YO6Wq1ysVnuek1h8taf1r3aJOL4hNk90Tx XNXunvfK9ZKN36z+6PD9T4DQmKAFu5RX/BWfkIqrvMNdhjpHCk6Qt3r6t6aqU/lXzcsK 6oq5SfqZ6t34TbTv+4aKrYq3aTcjkh4nLCCYx6M1jD37aDLOsBzloGH7BbCNWrCiWpEo +07sbf4k/TMlWIOlYYXu4yDCAEIovzeeSuVJJskXVAMfBfCJnwBLsk62QYX6tpKsJTNM LdbMO94jLR7WaVclzpfBkU8If1T0tMC7MPzNsPSet9X//jiMernHaCDhQkH0jIsC7nox 4zfw== 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=z6Ed8ScgBjo/U9wVH8qEIkibAMIwz7J26jo91ZEe0DM=; b=EPEaJc7lRyuEhr4Ooztxw7cLw2xYdVb+0qXTbP7YeKLv3GVelIdzBJ7KPf7soFo1+T ARKP6EZtEm6oplZUdZXqZjukoyuBT6p+m0Iew0YStj0GPFznEqtVPAxiMVKO8XMSbZSs jlHSf8hs/8AcD0cITyUB3vT2S1MmGeS/ZB7v+psJR4QHaGhe/Mr3lUwn+g8tRhXsINsG LW2kaESV8ezh6Lg46PGeg/qNsVYJJg8soiHrFO2cyWhXytsqfjHJwUfCNiH6FKBPCvlm nhtLngDfLwCagerGkOwdOZIhxPFY2f/0AR/3ZdMY7wGgj0Ka2tJ0VffSU0F49TUDuwnZ gljw== X-Gm-Message-State: ALKqPwd88Cenu93DPs4DJPLdu0HIbE+N9rK9RH8rN4RkMOjThMEdAag5 y3bbDYq4v2U/3LbmDBw2J9s= X-Google-Smtp-Source: AB8JxZrLcqzFEbwTyiiQt+L6r7HVWpnrGV+C4186jKSMSgZvZJp4EKM70J9X8tR+kQEGrDdW3rjgww== X-Received: by 2002:a0c:b06d:: with SMTP id l42-v6mr9837524qvc.125.1526319331322; Mon, 14 May 2018 10:35:31 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id r32-v6sm8507903qtr.55.2018.05.14.10.35.28 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 14 May 2018 10:35:29 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id B01221808CE; Mon, 14 May 2018 14:35:26 -0300 (-03) From: Marcelo Ricardo Leitner To: netdev@vger.kernel.org Cc: linux-sctp@vger.kernel.org, Neil Horman , Xin Long , Vlad Yasevich Subject: [PATCH net-next v3 1/3] sctp: add sctp_flush_ctx, a context struct on outq_flush routines Date: Mon, 14 May 2018 14:35:18 -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 With this struct we avoid passing lots of variables around and taking care of updating the current transport/packet. Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 182 +++++++++++++++++++++++++--------------------------- 1 file changed, 88 insertions(+), 94 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index e9c22b3db11cd702afc52f8233fb7f39d917698a..db94a2513dd874149aa77c4936f68537e97f8855 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -791,13 +791,22 @@ 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 to hold the context during sctp outq flush */ +struct sctp_flush_ctx { + struct sctp_outq *q; + /* Current transport being used. It's NOT the same as curr active one */ + struct sctp_transport *transport; + /* These transports have chunks to send. */ + struct list_head transport_list; + gfp_t gfp; +}; + +/* transport: current transport */ +static bool sctp_outq_select_transport(struct sctp_flush_ctx *ctx, + struct sctp_chunk *chunk) { struct sctp_transport *new_transport = chunk->transport; - struct sctp_transport *curr = *transport; + struct sctp_association *asoc = ctx->q->asoc; bool changed = false; if (!new_transport) { @@ -812,9 +821,9 @@ static bool sctp_outq_select_transport(struct sctp_chunk *chunk, * after processing ASCONFs, we may have new * transports created. */ - if (curr && sctp_cmp_addr_exact(&chunk->dest, - &curr->ipaddr)) - new_transport = curr; + if (ctx->transport && sctp_cmp_addr_exact(&chunk->dest, + &ctx->transport->ipaddr)) + new_transport = ctx->transport; else new_transport = sctp_assoc_lookup_paddr(asoc, &chunk->dest); @@ -857,37 +866,33 @@ static bool sctp_outq_select_transport(struct sctp_chunk *chunk, } /* Are we switching transports? Take care of transport locks. */ - if (new_transport != curr) { + if (new_transport != ctx->transport) { changed = true; - curr = new_transport; - *transport = curr; - if (list_empty(&curr->send_ready)) - list_add_tail(&curr->send_ready, transport_list); + ctx->transport = new_transport; + if (list_empty(&ctx->transport->send_ready)) + list_add_tail(&ctx->transport->send_ready, + &ctx->transport_list); - sctp_packet_config(&curr->packet, asoc->peer.i.init_tag, + sctp_packet_config(&ctx->transport->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); + sctp_transport_burst_limited(ctx->transport); } return changed; } -static void sctp_outq_flush_ctrl(struct sctp_outq *q, - struct sctp_transport **_transport, - struct list_head *transport_list, - gfp_t gfp) +static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) { - struct sctp_transport *transport = *_transport; - struct sctp_association *asoc = q->asoc; + struct sctp_association *asoc = ctx->q->asoc; struct sctp_packet *packet = NULL; struct sctp_chunk *chunk, *tmp; enum sctp_xmit status; int one_packet, error; - list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { + list_for_each_entry_safe(chunk, tmp, &ctx->q->control_chunk_list, list) { one_packet = 0; /* RFC 5061, 5.3 @@ -905,11 +910,8 @@ static void sctp_outq_flush_ctrl(struct sctp_outq *q, /* Pick the right transport to use. Should always be true for * the first chunk as we don't have a transport by then. */ - if (sctp_outq_select_transport(chunk, asoc, _transport, - transport_list)) { - transport = *_transport; - packet = &transport->packet; - } + if (sctp_outq_select_transport(ctx, chunk)) + packet = &ctx->transport->packet; switch (chunk->chunk_hdr->type) { /* @@ -921,7 +923,8 @@ static void sctp_outq_flush_ctrl(struct sctp_outq *q, case SCTP_CID_INIT: case SCTP_CID_INIT_ACK: case SCTP_CID_SHUTDOWN_COMPLETE: - error = sctp_packet_singleton(transport, chunk, gfp); + error = sctp_packet_singleton(ctx->transport, chunk, + ctx->gfp); if (error < 0) { asoc->base.sk->sk_err = -error; return; @@ -957,10 +960,10 @@ static void sctp_outq_flush_ctrl(struct sctp_outq *q, case SCTP_CID_I_FWD_TSN: case SCTP_CID_RECONF: status = sctp_packet_transmit_chunk(packet, chunk, - one_packet, gfp); + one_packet, ctx->gfp); if (status != SCTP_XMIT_OK) { /* put the chunk back */ - list_add(&chunk->list, &q->control_chunk_list); + list_add(&chunk->list, &ctx->q->control_chunk_list); break; } @@ -971,12 +974,12 @@ static void sctp_outq_flush_ctrl(struct sctp_outq *q, */ if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN || chunk->chunk_hdr->type == SCTP_CID_I_FWD_TSN) { - sctp_transport_reset_t3_rtx(transport); - transport->last_time_sent = jiffies; + sctp_transport_reset_t3_rtx(ctx->transport); + ctx->transport->last_time_sent = jiffies; } if (chunk == asoc->strreset_chunk) - sctp_transport_reset_reconf_timer(transport); + sctp_transport_reset_reconf_timer(ctx->transport); break; @@ -988,41 +991,38 @@ 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, gfp_t gfp) +static bool sctp_outq_flush_rtx(struct sctp_flush_ctx *ctx, + int rtx_timeout) { - struct sctp_transport *transport = *_transport; - struct sctp_packet *packet = transport ? &transport->packet : NULL; - struct sctp_association *asoc = q->asoc; + struct sctp_packet *packet = ctx->transport ? &ctx->transport->packet : + NULL; + struct sctp_association *asoc = ctx->q->asoc; int error, start_timer = 0; if (asoc->peer.retran_path->state == SCTP_UNCONFIRMED) return false; - if (transport != asoc->peer.retran_path) { + if (ctx->transport != asoc->peer.retran_path) { /* Switch transports & prepare the packet. */ - transport = asoc->peer.retran_path; - *_transport = transport; + ctx->transport = asoc->peer.retran_path; - if (list_empty(&transport->send_ready)) - list_add_tail(&transport->send_ready, - transport_list); + if (list_empty(&ctx->transport->send_ready)) + list_add_tail(&ctx->transport->send_ready, + &ctx->transport_list); - packet = &transport->packet; + packet = &ctx->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, - gfp); + error = __sctp_outq_flush_rtx(ctx->q, packet, rtx_timeout, &start_timer, + ctx->gfp); if (error < 0) asoc->base.sk->sk_err = -error; if (start_timer) { - sctp_transport_reset_t3_rtx(transport); - transport->last_time_sent = jiffies; + sctp_transport_reset_t3_rtx(ctx->transport); + ctx->transport->last_time_sent = jiffies; } /* This can happen on COOKIE-ECHO resend. Only @@ -1034,20 +1034,18 @@ static bool sctp_outq_flush_rtx(struct sctp_outq *q, /* Don't send new data if there is still data * waiting to retransmit. */ - if (!list_empty(&q->retransmit)) + if (!list_empty(&ctx->q->retransmit)) return false; return true; } -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) +static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, + int rtx_timeout) { - struct sctp_transport *transport = *_transport; - struct sctp_packet *packet = transport ? &transport->packet : NULL; - struct sctp_association *asoc = q->asoc; + struct sctp_packet *packet = ctx->transport ? &ctx->transport->packet : + NULL; + struct sctp_association *asoc = ctx->q->asoc; struct sctp_chunk *chunk; enum sctp_xmit status; @@ -1080,13 +1078,11 @@ static void sctp_outq_flush_data(struct sctp_outq *q, * 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)) + if (!list_empty(&ctx->q->retransmit)) { + if (!sctp_outq_flush_rtx(ctx, rtx_timeout)) return; /* We may have switched current transport */ - transport = *_transport; - packet = &transport->packet; + packet = &ctx->transport->packet; } /* Apply Max.Burst limitation to the current transport in @@ -1094,42 +1090,39 @@ static void sctp_outq_flush_data(struct sctp_outq *q, * rest it before we return, but we want to apply the limit * to the currently queued data. */ - if (transport) - sctp_transport_burst_limited(transport); + if (ctx->transport) + sctp_transport_burst_limited(ctx->transport); /* Finally, transmit new packets. */ - while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { + while ((chunk = sctp_outq_dequeue_data(ctx->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_sched_dequeue_done(ctx->q, chunk); sctp_chunk_fail(chunk, 0); sctp_chunk_free(chunk); continue; } if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { - sctp_outq_head_data(q, chunk); + sctp_outq_head_data(ctx->q, chunk); break; } - if (sctp_outq_select_transport(chunk, asoc, _transport, - transport_list)) { - transport = *_transport; - packet = &transport->packet; - } + if (sctp_outq_select_transport(ctx, chunk)) + packet = &ctx->transport->packet; 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 ? + __func__, ctx->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); + status = sctp_packet_transmit_chunk(packet, chunk, 0, ctx->gfp); if (status != SCTP_XMIT_OK) { /* We could not append this chunk, so put * the chunk back on the output queue. @@ -1138,7 +1131,7 @@ static void sctp_outq_flush_data(struct sctp_outq *q, __func__, ntohl(chunk->subh.data_hdr->tsn), status); - sctp_outq_head_data(q, chunk); + sctp_outq_head_data(ctx->q, chunk); break; } @@ -1156,13 +1149,13 @@ static void sctp_outq_flush_data(struct sctp_outq *q, /* Only now it's safe to consider this * chunk as sent, sched-wise. */ - sctp_sched_dequeue_done(q, chunk); + sctp_sched_dequeue_done(ctx->q, chunk); list_add_tail(&chunk->transmitted_list, - &transport->transmitted); + &ctx->transport->transmitted); - sctp_transport_reset_t3_rtx(transport); - transport->last_time_sent = jiffies; + sctp_transport_reset_t3_rtx(ctx->transport); + ctx->transport->last_time_sent = jiffies; /* Only let one DATA chunk get bundled with a * COOKIE-ECHO chunk. @@ -1172,22 +1165,20 @@ 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) +static void sctp_outq_flush_transports(struct sctp_flush_ctx *ctx) { struct list_head *ltransport; struct sctp_packet *packet; struct sctp_transport *t; int error = 0; - while ((ltransport = sctp_list_dequeue(transport_list)) != NULL) { + while ((ltransport = sctp_list_dequeue(&ctx->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); + error = sctp_packet_transmit(packet, ctx->gfp); if (error < 0) - q->asoc->base.sk->sk_err = -error; + ctx->q->asoc->base.sk->sk_err = -error; } /* Clear the burst limited state, if any */ @@ -1204,12 +1195,15 @@ static void sctp_outq_flush_transports(struct sctp_outq *q, * 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) { - /* Current transport being used. It's NOT the same as curr active one */ - struct sctp_transport *transport = NULL; - /* These transports have chunks to send. */ - LIST_HEAD(transport_list); + struct sctp_flush_ctx ctx = { + .q = q, + .transport = NULL, + .transport_list = LIST_HEAD_INIT(ctx.transport_list), + .gfp = gfp, + }; /* * 6.10 Bundling @@ -1221,16 +1215,16 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) * ... */ - sctp_outq_flush_ctrl(q, &transport, &transport_list, gfp); + sctp_outq_flush_ctrl(&ctx); if (q->asoc->src_out_of_asoc_ok) goto sctp_flush_out; - sctp_outq_flush_data(q, &transport, &transport_list, rtx_timeout, gfp); + sctp_outq_flush_data(&ctx, rtx_timeout); sctp_flush_out: - sctp_outq_flush_transports(q, &transport_list, gfp); + sctp_outq_flush_transports(&ctx); } /* Update unack_data based on the incoming SACK chunk */ From patchwork Mon May 14 17:35:19 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: 913156 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="AI1ZCwUK"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40l7Bz3vxzz9s0W for ; Tue, 15 May 2018 03:35:39 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753281AbeENRfh (ORCPT ); Mon, 14 May 2018 13:35:37 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:38615 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753060AbeENRfc (ORCPT ); Mon, 14 May 2018 13:35:32 -0400 Received: by mail-qt0-f195.google.com with SMTP id m9-v6so17210960qtb.5; Mon, 14 May 2018 10:35:31 -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=SrTaUK7ASDHYzZeGNvlyRJ5S25fpfJF9pujUbptmi6Q=; b=AI1ZCwUK8wmqrrXiXQiRolTwpsKFj4jna28Hsg/CkYzzAE4gwDFgDGxK3bIlJVqvrH wYQOz8D09KpLsB7u/zd52ciNrHpCED4K6biKK04VFavx9AYJ35wglD9Zh+fwPvkGNJMa xjBjoHl5ZbHw0aGxVxVS3N3mvkzreKs5loJ3KYG8nz8ll/8BbWgZcH3hZrYtEdorSfkJ Z5bJcchVisIwtg1iqieuk1hfulQFGbau7+PWV8pKNithFhHF9uSUu/Y5BicSTxRJEGAU O2dtplMoEpGtU+xcBh+konuKb2Xuoxu7YXvQvpn68+RTek+Xc9Kt4YRxKCjH3WjAAb91 pmfQ== 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=SrTaUK7ASDHYzZeGNvlyRJ5S25fpfJF9pujUbptmi6Q=; b=DflpC6u5OvmcKG3jfQentBKm2uRGqcKplhKcp3ZyU8LIsHJlvTEDt74pqNGtzE+a1o Slp06qNoRn1l5+vUfkpuLtEct7aiYkul1Bi9Thg0U+JL3SnDtWM90LYA0VTb5jOY0QdO Bi6JPRwmgZfp49/1pWI7jvxjdoNXBlxyAjEyj64pgjAFNuvOFoTvlXTstQngV3QLr7uM SCRVcSDtY+A2/VQTH+Tywy2P6N75tiR06SkOrMq4VHaNuqU3ie+jGJvOUboaaIrDCCPF FUbNGsFJ/Io+oLv10cK3F/T30qUmtXSB+jMma8O+ePXjxrgDS242J9OmdnqlVwWRq77c +N6g== X-Gm-Message-State: ALKqPweiHj8/O4XfcbLbGDa8tud1+s/iCrgQbqr30vS5s6TuF2ECT7pZ 9Enn4E3Ha/o8dI832r6JgU5PmDLu8+0= X-Google-Smtp-Source: AB8JxZpHWQc7riHYZNMoDZelZZSLrRYEau5yQsMyXMnEGZ520WugyHC7pwviAaneNPtJoervtvj65g== X-Received: by 2002:aed:3e67:: with SMTP id m36-v6mr10159513qtf.279.1526319330929; Mon, 14 May 2018 10:35:30 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id y41-v6sm8177906qty.84.2018.05.14.10.35.28 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 14 May 2018 10:35:29 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id BCD6E18140F; Mon, 14 May 2018 14:35:26 -0300 (-03) From: Marcelo Ricardo Leitner To: netdev@vger.kernel.org Cc: linux-sctp@vger.kernel.org, Neil Horman , Xin Long , Vlad Yasevich Subject: [PATCH net-next v3 2/3] sctp: add asoc and packet to sctp_flush_ctx Date: Mon, 14 May 2018 14:35:19 -0300 Message-Id: <95a7cce7dfa7741bc99d052f99c4ab7e40782502.1526319083.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 Pre-compute these so the compiler won't reload them (due to no-strict-aliasing). Changes since v2: - Do not replace a return with a break in sctp_outq_flush_data Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 97 ++++++++++++++++++++++++----------------------------- 1 file changed, 44 insertions(+), 53 deletions(-) -- 2.14.3 diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index db94a2513dd874149aa77c4936f68537e97f8855..68b7baea3feaacf6738a2346501b2ad673b67503 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -798,16 +798,17 @@ struct sctp_flush_ctx { struct sctp_transport *transport; /* These transports have chunks to send. */ struct list_head transport_list; + struct sctp_association *asoc; + /* Packet on the current transport above */ + struct sctp_packet *packet; gfp_t gfp; }; /* transport: current transport */ -static bool sctp_outq_select_transport(struct sctp_flush_ctx *ctx, +static void sctp_outq_select_transport(struct sctp_flush_ctx *ctx, struct sctp_chunk *chunk) { struct sctp_transport *new_transport = chunk->transport; - struct sctp_association *asoc = ctx->q->asoc; - bool changed = false; if (!new_transport) { if (!sctp_chunk_is_data(chunk)) { @@ -825,7 +826,7 @@ static bool sctp_outq_select_transport(struct sctp_flush_ctx *ctx, &ctx->transport->ipaddr)) new_transport = ctx->transport; else - new_transport = sctp_assoc_lookup_paddr(asoc, + new_transport = sctp_assoc_lookup_paddr(ctx->asoc, &chunk->dest); } @@ -833,7 +834,7 @@ static bool sctp_outq_select_transport(struct sctp_flush_ctx *ctx, * use the current active path. */ if (!new_transport) - new_transport = asoc->peer.active_path; + new_transport = ctx->asoc->peer.active_path; } else { __u8 type; @@ -858,7 +859,7 @@ static bool sctp_outq_select_transport(struct sctp_flush_ctx *ctx, if (type != SCTP_CID_HEARTBEAT && type != SCTP_CID_HEARTBEAT_ACK && type != SCTP_CID_ASCONF_ACK) - new_transport = asoc->peer.active_path; + new_transport = ctx->asoc->peer.active_path; break; default: break; @@ -867,27 +868,25 @@ static bool sctp_outq_select_transport(struct sctp_flush_ctx *ctx, /* Are we switching transports? Take care of transport locks. */ if (new_transport != ctx->transport) { - changed = true; ctx->transport = new_transport; + ctx->packet = &ctx->transport->packet; + if (list_empty(&ctx->transport->send_ready)) list_add_tail(&ctx->transport->send_ready, &ctx->transport_list); - sctp_packet_config(&ctx->transport->packet, asoc->peer.i.init_tag, - asoc->peer.ecn_capable); + sctp_packet_config(ctx->packet, + ctx->asoc->peer.i.init_tag, + ctx->asoc->peer.ecn_capable); /* We've switched transports, so apply the * Burst limit to the new transport. */ sctp_transport_burst_limited(ctx->transport); } - - return changed; } static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) { - struct sctp_association *asoc = ctx->q->asoc; - struct sctp_packet *packet = NULL; struct sctp_chunk *chunk, *tmp; enum sctp_xmit status; int one_packet, error; @@ -901,7 +900,7 @@ static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) * NOT use the new IP address as a source for ANY SCTP * packet except on carrying an ASCONF Chunk. */ - if (asoc->src_out_of_asoc_ok && + if (ctx->asoc->src_out_of_asoc_ok && chunk->chunk_hdr->type != SCTP_CID_ASCONF) continue; @@ -910,8 +909,7 @@ static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) /* Pick the right transport to use. Should always be true for * the first chunk as we don't have a transport by then. */ - if (sctp_outq_select_transport(ctx, chunk)) - packet = &ctx->transport->packet; + sctp_outq_select_transport(ctx, chunk); switch (chunk->chunk_hdr->type) { /* @@ -926,14 +924,14 @@ static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) error = sctp_packet_singleton(ctx->transport, chunk, ctx->gfp); if (error < 0) { - asoc->base.sk->sk_err = -error; + ctx->asoc->base.sk->sk_err = -error; return; } break; case SCTP_CID_ABORT: if (sctp_test_T_bit(chunk)) - packet->vtag = asoc->c.my_vtag; + ctx->packet->vtag = ctx->asoc->c.my_vtag; /* fallthru */ /* The following chunks are "response" chunks, i.e. @@ -959,7 +957,7 @@ static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) case SCTP_CID_FWD_TSN: case SCTP_CID_I_FWD_TSN: case SCTP_CID_RECONF: - status = sctp_packet_transmit_chunk(packet, chunk, + status = sctp_packet_transmit_chunk(ctx->packet, chunk, one_packet, ctx->gfp); if (status != SCTP_XMIT_OK) { /* put the chunk back */ @@ -967,7 +965,7 @@ static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) break; } - asoc->stats.octrlchunks++; + ctx->asoc->stats.octrlchunks++; /* PR-SCTP C5) If a FORWARD TSN is sent, the * sender MUST assure that at least one T3-rtx * timer is running. @@ -978,7 +976,7 @@ static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) ctx->transport->last_time_sent = jiffies; } - if (chunk == asoc->strreset_chunk) + if (chunk == ctx->asoc->strreset_chunk) sctp_transport_reset_reconf_timer(ctx->transport); break; @@ -994,31 +992,28 @@ static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) static bool sctp_outq_flush_rtx(struct sctp_flush_ctx *ctx, int rtx_timeout) { - struct sctp_packet *packet = ctx->transport ? &ctx->transport->packet : - NULL; - struct sctp_association *asoc = ctx->q->asoc; int error, start_timer = 0; - if (asoc->peer.retran_path->state == SCTP_UNCONFIRMED) + if (ctx->asoc->peer.retran_path->state == SCTP_UNCONFIRMED) return false; - if (ctx->transport != asoc->peer.retran_path) { + if (ctx->transport != ctx->asoc->peer.retran_path) { /* Switch transports & prepare the packet. */ - ctx->transport = asoc->peer.retran_path; + ctx->transport = ctx->asoc->peer.retran_path; + ctx->packet = &ctx->transport->packet; if (list_empty(&ctx->transport->send_ready)) list_add_tail(&ctx->transport->send_ready, &ctx->transport_list); - packet = &ctx->transport->packet; - sctp_packet_config(packet, asoc->peer.i.init_tag, - asoc->peer.ecn_capable); + sctp_packet_config(ctx->packet, ctx->asoc->peer.i.init_tag, + ctx->asoc->peer.ecn_capable); } - error = __sctp_outq_flush_rtx(ctx->q, packet, rtx_timeout, &start_timer, - ctx->gfp); + error = __sctp_outq_flush_rtx(ctx->q, ctx->packet, rtx_timeout, + &start_timer, ctx->gfp); if (error < 0) - asoc->base.sk->sk_err = -error; + ctx->asoc->base.sk->sk_err = -error; if (start_timer) { sctp_transport_reset_t3_rtx(ctx->transport); @@ -1028,7 +1023,7 @@ static bool sctp_outq_flush_rtx(struct sctp_flush_ctx *ctx, /* This can happen on COOKIE-ECHO resend. Only * one chunk can get bundled with a COOKIE-ECHO. */ - if (packet->has_cookie_echo) + if (ctx->packet->has_cookie_echo) return false; /* Don't send new data if there is still data @@ -1043,19 +1038,16 @@ static bool sctp_outq_flush_rtx(struct sctp_flush_ctx *ctx, static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, int rtx_timeout) { - struct sctp_packet *packet = ctx->transport ? &ctx->transport->packet : - NULL; - struct sctp_association *asoc = ctx->q->asoc; struct sctp_chunk *chunk; enum sctp_xmit status; /* Is it OK to send data chunks? */ - switch (asoc->state) { + switch (ctx->asoc->state) { case SCTP_STATE_COOKIE_ECHOED: /* Only allow bundling when this packet has a COOKIE-ECHO * chunk. */ - if (!packet || !packet->has_cookie_echo) + if (!ctx->packet || !ctx->packet->has_cookie_echo) return; /* fallthru */ @@ -1078,12 +1070,9 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, * are marked for retransmission (limited by the * current cwnd). */ - if (!list_empty(&ctx->q->retransmit)) { - if (!sctp_outq_flush_rtx(ctx, rtx_timeout)) - return; - /* We may have switched current transport */ - packet = &ctx->transport->packet; - } + if (!list_empty(&ctx->q->retransmit) && + !sctp_outq_flush_rtx(ctx, rtx_timeout)) + return; /* Apply Max.Burst limitation to the current transport in * case it will be used for new data. We are going to @@ -1105,13 +1094,12 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, continue; } - if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { + if (ctx->asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { sctp_outq_head_data(ctx->q, chunk); break; } - if (sctp_outq_select_transport(ctx, chunk)) - packet = &ctx->transport->packet; + sctp_outq_select_transport(ctx, chunk); pr_debug("%s: outq:%p, chunk:%p[%s], tx-tsn:0x%x skb->head:%p " "skb->users:%d\n", @@ -1122,7 +1110,8 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, refcount_read(&chunk->skb->users) : -1); /* Add the chunk to the packet. */ - status = sctp_packet_transmit_chunk(packet, chunk, 0, ctx->gfp); + status = sctp_packet_transmit_chunk(ctx->packet, chunk, 0, + ctx->gfp); if (status != SCTP_XMIT_OK) { /* We could not append this chunk, so put * the chunk back on the output queue. @@ -1139,12 +1128,12 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, * The sender MAY set the I-bit in the DATA * chunk header. */ - if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) + if (ctx->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++; + ctx->asoc->stats.ouodchunks++; else - asoc->stats.oodchunks++; + ctx->asoc->stats.oodchunks++; /* Only now it's safe to consider this * chunk as sent, sched-wise. @@ -1160,7 +1149,7 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, /* Only let one DATA chunk get bundled with a * COOKIE-ECHO chunk. */ - if (packet->has_cookie_echo) + if (ctx->packet->has_cookie_echo) break; } } @@ -1202,6 +1191,8 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) .q = q, .transport = NULL, .transport_list = LIST_HEAD_INIT(ctx.transport_list), + .asoc = q->asoc, + .packet = NULL, .gfp = gfp, }; From patchwork Mon May 14 17:35:20 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: 913155 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="MrYgODEp"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40l7Bw6PC2z9s0W for ; Tue, 15 May 2018 03:35:36 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753231AbeENRfc (ORCPT ); Mon, 14 May 2018 13:35:32 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:40083 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753129AbeENRfa (ORCPT ); Mon, 14 May 2018 13:35:30 -0400 Received: by mail-qt0-f194.google.com with SMTP id h2-v6so17213455qtp.7; Mon, 14 May 2018 10:35:30 -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=bS/kw7njMdTGka5tmMtfvocWZsfzRMf0KkT4GwV0buc=; b=MrYgODEprOthn6ZdfuPLMqydK4g5zp75O94rzMzJmQKoBTgxGspYxclKRZKnKDeriQ pNUC/VAbPfj1HGzIpTFFxxCuFlhE6JnoWltx9U8L84goP/42rdkdKOcVBmlBlPOwW/WI M64IrkkxpY9xVDnA9a3lYWWYvpWieBSFj4H2+FaIi+HblxdoWj0L4ng0oNK8EEC3rna+ 7/9FkXiOh03dAbYM+J5YmaLiytf43lEoCRtp5XzoBRXvoM9BrQC+TBf6lRitIEFRU4W9 x6DzCGYBIJ60sONa21H/087XNiqJ5glz19HhSg2fuChIEiDGJO7/RMYWT1uCcwJnoKNQ n8kA== 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=bS/kw7njMdTGka5tmMtfvocWZsfzRMf0KkT4GwV0buc=; b=g/UTfrgzumNMhCRU7Zdi/T9smPibFJq495mLDVLolkP5kmFscIjAFJbmoeuWDuOa01 4GNkdbgTpxgElyurhTRA+48zYqbLEPXH8uQLjrX8u808Gg+L9Gt5HZm3Z/GjvN8oMyJ9 LXYQsln4DHZZj3aNrvuDApl4fyUisjsPCZfBAk2zc5VpJVMsTQ34zOYh6w5SNLQ3rWeH ucxXpGWStyyUQfohhSqLWUhn194oiqZFY5aInHo045EaMdYqlRgfgWlAkyf57EjFFmbc m+MK+BJZHmBUrAzih6scadpzTJPFmBokXlu1twWiFmslHb0gOWEdMwdZsA5yPeg4GAF6 sdKg== X-Gm-Message-State: ALKqPwdKOKwDQO8b2hSk8hHK60AVs7vU7kHxikPtgQ39vPdZeD0xFQej fKB8MchY/yN1ulYMVsDpZ2c= X-Google-Smtp-Source: AB8JxZr/xd8LkQXp4B87jy10AEBAoXlfVhLpC0fomuc5dmdcpXyVvbrCW0nSQCB6GpR8AzesGDO1JA== X-Received: by 2002:aed:3c0f:: with SMTP id t15-v6mr9785711qte.398.1526319329445; Mon, 14 May 2018 10:35:29 -0700 (PDT) Received: from localhost.localdomain ([45.4.239.227]) by smtp.gmail.com with ESMTPSA id s11-v6sm8295259qtk.39.2018.05.14.10.35.28 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 14 May 2018 10:35:28 -0700 (PDT) Received: by localhost.localdomain (Postfix, from userid 1000) id C69E118147E; Mon, 14 May 2018 14:35:26 -0300 (-03) From: Marcelo Ricardo Leitner To: netdev@vger.kernel.org Cc: linux-sctp@vger.kernel.org, Neil Horman , Xin Long , Vlad Yasevich Subject: [PATCH net-next v3 3/3] sctp: checkpatch fixups Date: Mon, 14 May 2018 14:35:20 -0300 Message-Id: <1532d28423d0c2322f66e5d15de709ef2f574bc8.1526319083.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 A collection of fixups from previous patches, left for later to not introduce unnecessary changes while moving code around. Signed-off-by: Marcelo Ricardo Leitner --- net/sctp/outqueue.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 68b7baea3feaacf6738a2346501b2ad673b67503..d68aa33485a94e87858fed9b655f00a1b9748998 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -812,8 +812,7 @@ static void sctp_outq_select_transport(struct sctp_flush_ctx *ctx, if (!new_transport) { if (!sctp_chunk_is_data(chunk)) { - /* - * If we have a prior transport pointer, see if + /* 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 @@ -912,8 +911,7 @@ static void sctp_outq_flush_ctrl(struct sctp_flush_ctx *ctx) sctp_outq_select_transport(ctx, chunk); switch (chunk->chunk_hdr->type) { - /* - * 6.10 Bundling + /* 6.10 Bundling * ... * An endpoint MUST NOT bundle INIT, INIT ACK or SHUTDOWN * COMPLETE with any other chunks. [Send them immediately.] @@ -1061,8 +1059,7 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, return; } - /* - * RFC 2960 6.1 Transmission of DATA Chunks + /* 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 @@ -1101,8 +1098,7 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx, sctp_outq_select_transport(ctx, chunk); - pr_debug("%s: outq:%p, chunk:%p[%s], tx-tsn:0x%x skb->head:%p " - "skb->users:%d\n", + pr_debug("%s: outq:%p, chunk:%p[%s], tx-tsn:0x%x skb->head:%p skb->users:%d\n", __func__, ctx->q, chunk, chunk && chunk->chunk_hdr ? sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) : "illegal chunk", ntohl(chunk->subh.data_hdr->tsn), @@ -1175,8 +1171,7 @@ static void sctp_outq_flush_transports(struct sctp_flush_ctx *ctx) } } -/* - * Try to flush an outqueue. +/* Try to flush an outqueue. * * Description: Send everything in q which we legally can, subject to * congestion limitations. @@ -1196,8 +1191,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) .gfp = gfp, }; - /* - * 6.10 Bundling + /* 6.10 Bundling * ... * When bundling control chunks with DATA chunks, an * endpoint MUST place control chunks first in the outbound @@ -1768,7 +1762,7 @@ static int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn) if (TSN_lte(tsn, ctsn)) goto pass; - /* 3.3.4 Selective Acknowledgement (SACK) (3): + /* 3.3.4 Selective Acknowledgment (SACK) (3): * * Gap Ack Blocks: * These fields contain the Gap Ack Blocks. They are repeated