Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cee360ab authored by Xin Long's avatar Xin Long Committed by David S. Miller
Browse files

sctp: define the member stream as an object instead of pointer in asoc



As Marcelo's suggestion, stream is a fixed size member of asoc and would
not grow with more streams. To avoid an allocation for it, this patch is
to define it as an object instead of pointer and update the places using
it, also create sctp_stream_update() called in sctp_assoc_update() to
migrate the stream info from one stream to another.

Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6e7da286
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -381,6 +381,7 @@ int sctp_stream_new(struct sctp_association *asoc, gfp_t gfp);
int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp);
void sctp_stream_free(struct sctp_stream *stream);
void sctp_stream_clear(struct sctp_stream *stream);
void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new);

/* What is the current SSN number for this stream? */
#define sctp_ssn_peek(stream, type, sid) \
@@ -1750,7 +1751,7 @@ struct sctp_association {
	__u32 default_rcv_context;

	/* Stream arrays */
	struct sctp_stream *stream;
	struct sctp_stream stream;

	/* All outbound chunks go through this structure.  */
	struct sctp_outq outqueue;
+5 −8
Original line number Diff line number Diff line
@@ -291,7 +291,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
	return asoc;

stream_free:
	sctp_stream_free(asoc->stream);
	sctp_stream_free(&asoc->stream);
fail_init:
	sock_put(asoc->base.sk);
	sctp_endpoint_put(asoc->ep);
@@ -365,7 +365,7 @@ void sctp_association_free(struct sctp_association *asoc)
	sctp_tsnmap_free(&asoc->peer.tsn_map);

	/* Free stream information. */
	sctp_stream_free(asoc->stream);
	sctp_stream_free(&asoc->stream);

	if (asoc->strreset_chunk)
		sctp_chunk_free(asoc->strreset_chunk);
@@ -1151,7 +1151,7 @@ void sctp_assoc_update(struct sctp_association *asoc,
		/* Reinitialize SSN for both local streams
		 * and peer's streams.
		 */
		sctp_stream_clear(asoc->stream);
		sctp_stream_clear(&asoc->stream);

		/* Flush the ULP reassembly and ordered queue.
		 * Any data there will now be stale and will
@@ -1177,11 +1177,8 @@ void sctp_assoc_update(struct sctp_association *asoc,
		asoc->ctsn_ack_point = asoc->next_tsn - 1;
		asoc->adv_peer_ack_point = asoc->ctsn_ack_point;

		if (sctp_state(asoc, COOKIE_WAIT)) {
			sctp_stream_free(asoc->stream);
			asoc->stream = new->stream;
			new->stream = NULL;
		}
		if (sctp_state(asoc, COOKIE_WAIT))
			sctp_stream_update(&asoc->stream, &new->stream);

		if (!asoc->assoc_id) {
			/* get a new association id since we don't have one
+2 −2
Original line number Diff line number Diff line
@@ -307,7 +307,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
	    time_after(jiffies, chunk->msg->expires_at)) {
		struct sctp_stream_out *streamout =
			&chunk->asoc->stream->out[chunk->sinfo.sinfo_stream];
			&chunk->asoc->stream.out[chunk->sinfo.sinfo_stream];

		if (chunk->sent_count) {
			chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++;
@@ -320,7 +320,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
	} else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
		   chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
		struct sctp_stream_out *streamout =
			&chunk->asoc->stream->out[chunk->sinfo.sinfo_stream];
			&chunk->asoc->stream.out[chunk->sinfo.sinfo_stream];

		chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
		streamout->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
+5 −5
Original line number Diff line number Diff line
@@ -363,7 +363,7 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
		sctp_insert_list(&asoc->outqueue.abandoned,
				 &chk->transmitted_list);

		streamout = &asoc->stream->out[chk->sinfo.sinfo_stream];
		streamout = &asoc->stream.out[chk->sinfo.sinfo_stream];
		asoc->sent_cnt_removable--;
		asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
		streamout->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
@@ -400,9 +400,9 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
		q->out_qlen -= chk->skb->len;
		asoc->sent_cnt_removable--;
		asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
		if (chk->sinfo.sinfo_stream < asoc->stream->outcnt) {
		if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) {
			struct sctp_stream_out *streamout =
				&asoc->stream->out[chk->sinfo.sinfo_stream];
				&asoc->stream.out[chk->sinfo.sinfo_stream];

			streamout->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
		}
@@ -1036,7 +1036,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
			/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
			 * stream identifier.
			 */
			if (chunk->sinfo.sinfo_stream >= asoc->stream->outcnt) {
			if (chunk->sinfo.sinfo_stream >= asoc->stream.outcnt) {

				/* Mark as failed send. */
				sctp_chunk_fail(chunk, SCTP_ERROR_INV_STRM);
@@ -1054,7 +1054,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
				continue;
			}

			if (asoc->stream->out[sid].state == SCTP_STREAM_CLOSED) {
			if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) {
				sctp_outq_head_data(q, chunk);
				goto sctp_flush_out;
			}
+2 −2
Original line number Diff line number Diff line
@@ -361,8 +361,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
	sctp_seq_dump_remote_addrs(seq, assoc);
	seq_printf(seq, "\t%8lu %5d %5d %4d %4d %4d %8d "
		   "%8d %8d %8d %8d",
		assoc->hbinterval, assoc->stream->incnt,
		assoc->stream->outcnt, assoc->max_retrans,
		assoc->hbinterval, assoc->stream.incnt,
		assoc->stream.outcnt, assoc->max_retrans,
		assoc->init_retries, assoc->shutdown_retries,
		assoc->rtx_data_chunks,
		atomic_read(&sk->sk_wmem_alloc),
Loading