Skip to content

Commit

Permalink
net/sctp: Make wrappers for accessing in/out streams
Browse files Browse the repository at this point in the history
This patch introduces wrappers for accessing in/out streams indirectly.
This will enable to replace physically contiguous memory arrays
of streams with flexible arrays (or maybe any other appropriate
mechanism) which do memory allocation on a per-page basis.

Signed-off-by: Oleg Babin <obabin@virtuozzo.com>
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
finist0 authored and davem330 committed Aug 11, 2018
1 parent b70f1f3 commit 05364ca
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 81 deletions.
35 changes: 25 additions & 10 deletions include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,37 +398,35 @@ 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) \
((stream)->type[sid].ssn)
(sctp_stream_##type((stream), (sid))->ssn)

/* Return the next SSN number for this stream. */
#define sctp_ssn_next(stream, type, sid) \
((stream)->type[sid].ssn++)
(sctp_stream_##type((stream), (sid))->ssn++)

/* Skip over this ssn and all below. */
#define sctp_ssn_skip(stream, type, sid, ssn) \
((stream)->type[sid].ssn = ssn + 1)
(sctp_stream_##type((stream), (sid))->ssn = ssn + 1)

/* What is the current MID number for this stream? */
#define sctp_mid_peek(stream, type, sid) \
((stream)->type[sid].mid)
(sctp_stream_##type((stream), (sid))->mid)

/* Return the next MID number for this stream. */
#define sctp_mid_next(stream, type, sid) \
((stream)->type[sid].mid++)
(sctp_stream_##type((stream), (sid))->mid++)

/* Skip over this mid and all below. */
#define sctp_mid_skip(stream, type, sid, mid) \
((stream)->type[sid].mid = mid + 1)

#define sctp_stream_in(asoc, sid) (&(asoc)->stream.in[sid])
(sctp_stream_##type((stream), (sid))->mid = mid + 1)

/* What is the current MID_uo number for this stream? */
#define sctp_mid_uo_peek(stream, type, sid) \
((stream)->type[sid].mid_uo)
(sctp_stream_##type((stream), (sid))->mid_uo)

/* Return the next MID_uo number for this stream. */
#define sctp_mid_uo_next(stream, type, sid) \
((stream)->type[sid].mid_uo++)
(sctp_stream_##type((stream), (sid))->mid_uo++)

/*
* Pointers to address related SCTP functions.
Expand Down Expand Up @@ -1463,6 +1461,23 @@ struct sctp_stream {
struct sctp_stream_interleave *si;
};

static inline struct sctp_stream_out *sctp_stream_out(
const struct sctp_stream *stream,
__u16 sid)
{
return ((struct sctp_stream_out *)(stream->out)) + sid;
}

static inline struct sctp_stream_in *sctp_stream_in(
const struct sctp_stream *stream,
__u16 sid)
{
return ((struct sctp_stream_in *)(stream->in)) + sid;
}

#define SCTP_SO(s, i) sctp_stream_out((s), (i))
#define SCTP_SI(s, i) sctp_stream_in((s), (i))

#define SCTP_STREAM_CLOSED 0x00
#define SCTP_STREAM_OPEN 0x01

Expand Down
6 changes: 4 additions & 2 deletions net/sctp/chunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,8 @@ 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];
SCTP_SO(&chunk->asoc->stream,
chunk->sinfo.sinfo_stream);

if (chunk->sent_count) {
chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++;
Expand All @@ -339,7 +340,8 @@ 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];
SCTP_SO(&chunk->asoc->stream,
chunk->sinfo.sinfo_stream);

chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
Expand Down
11 changes: 6 additions & 5 deletions net/sctp/outqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static inline void sctp_outq_head_data(struct sctp_outq *q,
q->out_qlen += ch->skb->len;

stream = sctp_chunk_stream_no(ch);
oute = q->asoc->stream.out[stream].ext;
oute = SCTP_SO(&q->asoc->stream, stream)->ext;
list_add(&ch->stream_list, &oute->outq);
}

Expand All @@ -101,7 +101,7 @@ static inline void sctp_outq_tail_data(struct sctp_outq *q,
q->out_qlen += ch->skb->len;

stream = sctp_chunk_stream_no(ch);
oute = q->asoc->stream.out[stream].ext;
oute = SCTP_SO(&q->asoc->stream, stream)->ext;
list_add_tail(&ch->stream_list, &oute->outq);
}

Expand Down Expand Up @@ -372,7 +372,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 = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
asoc->sent_cnt_removable--;
asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
Expand Down Expand Up @@ -416,7 +416,7 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) {
struct sctp_stream_out *streamout =
&asoc->stream.out[chk->sinfo.sinfo_stream];
SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);

streamout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
}
Expand Down Expand Up @@ -1082,6 +1082,7 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx,
/* Finally, transmit new packets. */
while ((chunk = sctp_outq_dequeue_data(ctx->q)) != NULL) {
__u32 sid = ntohs(chunk->subh.data_hdr->stream);
__u8 stream_state = SCTP_SO(&ctx->asoc->stream, sid)->state;

/* Has this chunk expired? */
if (sctp_chunk_abandoned(chunk)) {
Expand All @@ -1091,7 +1092,7 @@ static void sctp_outq_flush_data(struct sctp_flush_ctx *ctx,
continue;
}

if (ctx->asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) {
if (stream_state == SCTP_STREAM_CLOSED) {
sctp_outq_head_data(ctx->q, chunk);
break;
}
Expand Down
4 changes: 2 additions & 2 deletions net/sctp/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
goto err;
}

if (unlikely(!asoc->stream.out[sinfo->sinfo_stream].ext)) {
if (unlikely(!SCTP_SO(&asoc->stream, sinfo->sinfo_stream)->ext)) {
err = sctp_stream_init_ext(&asoc->stream, sinfo->sinfo_stream);
if (err)
goto err;
Expand Down Expand Up @@ -7154,7 +7154,7 @@ static int sctp_getsockopt_pr_streamstatus(struct sock *sk, int len,
if (!asoc || params.sprstat_sid >= asoc->stream.outcnt)
goto out;

streamoute = asoc->stream.out[params.sprstat_sid].ext;
streamoute = SCTP_SO(&asoc->stream, params.sprstat_sid)->ext;
if (!streamoute) {
/* Not allocated yet, means all stats are 0 */
params.sprstat_abandoned_unsent = 0;
Expand Down
65 changes: 34 additions & 31 deletions net/sctp/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt,

stream->outcnt = outcnt;
for (i = 0; i < stream->outcnt; i++)
stream->out[i].state = SCTP_STREAM_OPEN;
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;

sched->init(stream);

Expand Down Expand Up @@ -193,7 +193,7 @@ int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid)
soute = kzalloc(sizeof(*soute), GFP_KERNEL);
if (!soute)
return -ENOMEM;
stream->out[sid].ext = soute;
SCTP_SO(stream, sid)->ext = soute;

return sctp_sched_init_sid(stream, sid, GFP_KERNEL);
}
Expand All @@ -205,7 +205,7 @@ void sctp_stream_free(struct sctp_stream *stream)

sched->free(stream);
for (i = 0; i < stream->outcnt; i++)
kfree(stream->out[i].ext);
kfree(SCTP_SO(stream, i)->ext);
kfree(stream->out);
kfree(stream->in);
}
Expand All @@ -215,12 +215,12 @@ void sctp_stream_clear(struct sctp_stream *stream)
int i;

for (i = 0; i < stream->outcnt; i++) {
stream->out[i].mid = 0;
stream->out[i].mid_uo = 0;
SCTP_SO(stream, i)->mid = 0;
SCTP_SO(stream, i)->mid_uo = 0;
}

for (i = 0; i < stream->incnt; i++)
stream->in[i].mid = 0;
SCTP_SI(stream, i)->mid = 0;
}

void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new)
Expand Down Expand Up @@ -273,8 +273,8 @@ static bool sctp_stream_outq_is_empty(struct sctp_stream *stream,
for (i = 0; i < str_nums; i++) {
__u16 sid = ntohs(str_list[i]);

if (stream->out[sid].ext &&
!list_empty(&stream->out[sid].ext->outq))
if (SCTP_SO(stream, sid)->ext &&
!list_empty(&SCTP_SO(stream, sid)->ext->outq))
return false;
}

Expand Down Expand Up @@ -361,11 +361,11 @@ int sctp_send_reset_streams(struct sctp_association *asoc,
if (out) {
if (str_nums)
for (i = 0; i < str_nums; i++)
stream->out[str_list[i]].state =
SCTP_SO(stream, str_list[i])->state =
SCTP_STREAM_CLOSED;
else
for (i = 0; i < stream->outcnt; i++)
stream->out[i].state = SCTP_STREAM_CLOSED;
SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
}

asoc->strreset_chunk = chunk;
Expand All @@ -380,11 +380,11 @@ int sctp_send_reset_streams(struct sctp_association *asoc,

if (str_nums)
for (i = 0; i < str_nums; i++)
stream->out[str_list[i]].state =
SCTP_SO(stream, str_list[i])->state =
SCTP_STREAM_OPEN;
else
for (i = 0; i < stream->outcnt; i++)
stream->out[i].state = SCTP_STREAM_OPEN;
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;

goto out;
}
Expand Down Expand Up @@ -418,7 +418,7 @@ int sctp_send_reset_assoc(struct sctp_association *asoc)

/* Block further xmit of data until this request is completed */
for (i = 0; i < stream->outcnt; i++)
stream->out[i].state = SCTP_STREAM_CLOSED;
SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;

asoc->strreset_chunk = chunk;
sctp_chunk_hold(asoc->strreset_chunk);
Expand All @@ -429,7 +429,7 @@ int sctp_send_reset_assoc(struct sctp_association *asoc)
asoc->strreset_chunk = NULL;

for (i = 0; i < stream->outcnt; i++)
stream->out[i].state = SCTP_STREAM_OPEN;
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;

return retval;
}
Expand Down Expand Up @@ -609,10 +609,10 @@ struct sctp_chunk *sctp_process_strreset_outreq(
}

for (i = 0; i < nums; i++)
stream->in[ntohs(str_p[i])].mid = 0;
SCTP_SI(stream, ntohs(str_p[i]))->mid = 0;
} else {
for (i = 0; i < stream->incnt; i++)
stream->in[i].mid = 0;
SCTP_SI(stream, i)->mid = 0;
}

result = SCTP_STRRESET_PERFORMED;
Expand Down Expand Up @@ -683,11 +683,11 @@ struct sctp_chunk *sctp_process_strreset_inreq(

if (nums)
for (i = 0; i < nums; i++)
stream->out[ntohs(str_p[i])].state =
SCTP_SO(stream, ntohs(str_p[i]))->state =
SCTP_STREAM_CLOSED;
else
for (i = 0; i < stream->outcnt; i++)
stream->out[i].state = SCTP_STREAM_CLOSED;
SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;

asoc->strreset_chunk = chunk;
asoc->strreset_outstanding = 1;
Expand Down Expand Up @@ -786,11 +786,11 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
* incoming and outgoing streams.
*/
for (i = 0; i < stream->outcnt; i++) {
stream->out[i].mid = 0;
stream->out[i].mid_uo = 0;
SCTP_SO(stream, i)->mid = 0;
SCTP_SO(stream, i)->mid_uo = 0;
}
for (i = 0; i < stream->incnt; i++)
stream->in[i].mid = 0;
SCTP_SI(stream, i)->mid = 0;

result = SCTP_STRRESET_PERFORMED;

Expand Down Expand Up @@ -979,23 +979,26 @@ struct sctp_chunk *sctp_process_strreset_resp(
sizeof(__u16);

if (result == SCTP_STRRESET_PERFORMED) {
struct sctp_stream_out *sout;
if (nums) {
for (i = 0; i < nums; i++) {
stream->out[ntohs(str_p[i])].mid = 0;
stream->out[ntohs(str_p[i])].mid_uo = 0;
sout = SCTP_SO(stream, ntohs(str_p[i]));
sout->mid = 0;
sout->mid_uo = 0;
}
} else {
for (i = 0; i < stream->outcnt; i++) {
stream->out[i].mid = 0;
stream->out[i].mid_uo = 0;
sout = SCTP_SO(stream, i);
sout->mid = 0;
sout->mid_uo = 0;
}
}

flags = SCTP_STREAM_RESET_OUTGOING_SSN;
}

for (i = 0; i < stream->outcnt; i++)
stream->out[i].state = SCTP_STREAM_OPEN;
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;

*evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
nums, str_p, GFP_ATOMIC);
Expand Down Expand Up @@ -1050,15 +1053,15 @@ struct sctp_chunk *sctp_process_strreset_resp(
asoc->adv_peer_ack_point = asoc->ctsn_ack_point;

for (i = 0; i < stream->outcnt; i++) {
stream->out[i].mid = 0;
stream->out[i].mid_uo = 0;
SCTP_SO(stream, i)->mid = 0;
SCTP_SO(stream, i)->mid_uo = 0;
}
for (i = 0; i < stream->incnt; i++)
stream->in[i].mid = 0;
SCTP_SI(stream, i)->mid = 0;
}

for (i = 0; i < stream->outcnt; i++)
stream->out[i].state = SCTP_STREAM_OPEN;
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;

*evp = sctp_ulpevent_make_assoc_reset_event(asoc, flags,
stsn, rtsn, GFP_ATOMIC);
Expand All @@ -1072,7 +1075,7 @@ struct sctp_chunk *sctp_process_strreset_resp(

if (result == SCTP_STRRESET_PERFORMED)
for (i = number; i < stream->outcnt; i++)
stream->out[i].state = SCTP_STREAM_OPEN;
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
else
stream->outcnt = number;

Expand Down
Loading

0 comments on commit 05364ca

Please sign in to comment.