sctp: remove the unnecessary state check in sctp_outq_tail
authorXin Long <lucien.xin@gmail.com>
Tue, 13 Sep 2016 18:04:18 +0000 (02:04 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 19 Sep 2016 02:02:32 +0000 (22:02 -0400)
Data Chunks are only sent by sctp_primitive_SEND, in which sctp checks
the asoc's state through statetable before calling sctp_outq_tail. So
there's no need to check the asoc's state again in sctp_outq_tail.

Besides, sctp_do_sm is protected by lock_sock, even if sending msg is
interrupted by timer events, the event's processes still need to acquire
lock_sock first. It means no others CMDs can be enqueue into side effect
list before CMD_SEND_MSG to change asoc->state, so it's safe to remove it.

This patch is to remove redundant asoc->state check from sctp_outq_tail.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sctp/outqueue.c

index 72e54a4..da2418b 100644 (file)
@@ -299,50 +299,25 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk, gfp_t gfp)
         * immediately.
         */
        if (sctp_chunk_is_data(chunk)) {
-               /* Is it OK to queue data chunks?  */
-               /* From 9. Termination of Association
-                *
-                * When either endpoint performs a shutdown, the
-                * association on each peer will stop accepting new
-                * data from its user and only deliver data in queue
-                * at the time of sending or receiving the SHUTDOWN
-                * chunk.
-                */
-               switch (q->asoc->state) {
-               case SCTP_STATE_CLOSED:
-               case SCTP_STATE_SHUTDOWN_PENDING:
-               case SCTP_STATE_SHUTDOWN_SENT:
-               case SCTP_STATE_SHUTDOWN_RECEIVED:
-               case SCTP_STATE_SHUTDOWN_ACK_SENT:
-                       /* Cannot send after transport endpoint shutdown */
-                       error = -ESHUTDOWN;
-                       break;
-
-               default:
-                       pr_debug("%s: outqueueing: outq:%p, chunk:%p[%s])\n",
-                                __func__, q, chunk, chunk && chunk->chunk_hdr ?
-                                sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) :
-                                "illegal chunk");
-
-                       sctp_chunk_hold(chunk);
-                       sctp_outq_tail_data(q, chunk);
-                       if (chunk->asoc->prsctp_enable &&
-                           SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags))
-                               chunk->asoc->sent_cnt_removable++;
-                       if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
-                               SCTP_INC_STATS(net, SCTP_MIB_OUTUNORDERCHUNKS);
-                       else
-                               SCTP_INC_STATS(net, SCTP_MIB_OUTORDERCHUNKS);
-                       break;
-               }
+               pr_debug("%s: outqueueing: outq:%p, chunk:%p[%s])\n",
+                        __func__, q, chunk, chunk && chunk->chunk_hdr ?
+                        sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) :
+                        "illegal chunk");
+
+               sctp_chunk_hold(chunk);
+               sctp_outq_tail_data(q, chunk);
+               if (chunk->asoc->prsctp_enable &&
+                   SCTP_PR_PRIO_ENABLED(chunk->sinfo.sinfo_flags))
+                       chunk->asoc->sent_cnt_removable++;
+               if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+                       SCTP_INC_STATS(net, SCTP_MIB_OUTUNORDERCHUNKS);
+               else
+                       SCTP_INC_STATS(net, SCTP_MIB_OUTORDERCHUNKS);
        } else {
                list_add_tail(&chunk->list, &q->control_chunk_list);
                SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
        }
 
-       if (error < 0)
-               return error;
-
        if (!q->cork)
                error = sctp_outq_flush(q, 0, gfp);