Commit 058e6e0e authored by Xin Long's avatar Xin Long Committed by David S. Miller

sctp: improve the code for pmtu probe send and recv update

This patch does 3 things:

  - make sctp_transport_pl_send() and sctp_transport_pl_recv()
    return bool type to decide if more probe is needed to send.

  - pr_debug() only when probe is really needed to send.

  - count pl.raise_count in sctp_transport_pl_send() instead of
    sctp_transport_pl_recv(), and it's only incremented for the
    1st probe for the same size.

These are preparations for the next patch to make probes happen
only when there's packet loss in Search Complete state.
Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 795e3d2e
...@@ -1024,8 +1024,8 @@ bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu); ...@@ -1024,8 +1024,8 @@ bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu);
void sctp_transport_immediate_rtx(struct sctp_transport *); void sctp_transport_immediate_rtx(struct sctp_transport *);
void sctp_transport_dst_release(struct sctp_transport *t); void sctp_transport_dst_release(struct sctp_transport *t);
void sctp_transport_dst_confirm(struct sctp_transport *t); void sctp_transport_dst_confirm(struct sctp_transport *t);
void sctp_transport_pl_send(struct sctp_transport *t); bool sctp_transport_pl_send(struct sctp_transport *t);
void sctp_transport_pl_recv(struct sctp_transport *t); bool sctp_transport_pl_recv(struct sctp_transport *t);
/* This is the structure we use to queue packets as they come into /* This is the structure we use to queue packets as they come into
......
...@@ -1109,12 +1109,12 @@ enum sctp_disposition sctp_sf_send_probe(struct net *net, ...@@ -1109,12 +1109,12 @@ enum sctp_disposition sctp_sf_send_probe(struct net *net,
if (!sctp_transport_pl_enabled(transport)) if (!sctp_transport_pl_enabled(transport))
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
sctp_transport_pl_send(transport); if (sctp_transport_pl_send(transport)) {
reply = sctp_make_heartbeat(asoc, transport, transport->pl.probe_size); reply = sctp_make_heartbeat(asoc, transport, transport->pl.probe_size);
if (!reply) if (!reply)
return SCTP_DISPOSITION_NOMEM; return SCTP_DISPOSITION_NOMEM;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
}
sctp_add_cmd_sf(commands, SCTP_CMD_PROBE_TIMER_UPDATE, sctp_add_cmd_sf(commands, SCTP_CMD_PROBE_TIMER_UPDATE,
SCTP_TRANSPORT(transport)); SCTP_TRANSPORT(transport));
...@@ -1274,8 +1274,7 @@ enum sctp_disposition sctp_sf_backbeat_8_3(struct net *net, ...@@ -1274,8 +1274,7 @@ enum sctp_disposition sctp_sf_backbeat_8_3(struct net *net,
!sctp_transport_pl_enabled(link)) !sctp_transport_pl_enabled(link))
return SCTP_DISPOSITION_DISCARD; return SCTP_DISPOSITION_DISCARD;
sctp_transport_pl_recv(link); if (sctp_transport_pl_recv(link))
if (link->pl.state == SCTP_PL_COMPLETE)
return SCTP_DISPOSITION_CONSUME; return SCTP_DISPOSITION_CONSUME;
return sctp_sf_send_probe(net, ep, asoc, type, link, commands); return sctp_sf_send_probe(net, ep, asoc, type, link, commands);
......
...@@ -258,16 +258,12 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk) ...@@ -258,16 +258,12 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
sctp_transport_pl_update(transport); sctp_transport_pl_update(transport);
} }
void sctp_transport_pl_send(struct sctp_transport *t) bool sctp_transport_pl_send(struct sctp_transport *t)
{ {
pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, high: %d\n", if (t->pl.probe_count < SCTP_MAX_PROBES)
__func__, t, t->pl.state, t->pl.pmtu, t->pl.probe_size, t->pl.probe_high); goto out;
if (t->pl.probe_count < SCTP_MAX_PROBES) {
t->pl.probe_count++;
return;
}
t->pl.probe_count = 0;
if (t->pl.state == SCTP_PL_BASE) { if (t->pl.state == SCTP_PL_BASE) {
if (t->pl.probe_size == SCTP_BASE_PLPMTU) { /* BASE_PLPMTU Confirmation Failed */ if (t->pl.probe_size == SCTP_BASE_PLPMTU) { /* BASE_PLPMTU Confirmation Failed */
t->pl.state = SCTP_PL_ERROR; /* Base -> Error */ t->pl.state = SCTP_PL_ERROR; /* Base -> Error */
...@@ -299,10 +295,20 @@ void sctp_transport_pl_send(struct sctp_transport *t) ...@@ -299,10 +295,20 @@ void sctp_transport_pl_send(struct sctp_transport *t)
sctp_assoc_sync_pmtu(t->asoc); sctp_assoc_sync_pmtu(t->asoc);
} }
} }
t->pl.probe_count = 1;
out:
if (t->pl.state == SCTP_PL_COMPLETE && t->pl.raise_count < 30 &&
!t->pl.probe_count)
t->pl.raise_count++;
pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, high: %d\n",
__func__, t, t->pl.state, t->pl.pmtu, t->pl.probe_size, t->pl.probe_high);
t->pl.probe_count++;
return true;
} }
void sctp_transport_pl_recv(struct sctp_transport *t) bool sctp_transport_pl_recv(struct sctp_transport *t)
{ {
pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, high: %d\n", pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, high: %d\n",
__func__, t, t->pl.state, t->pl.pmtu, t->pl.probe_size, t->pl.probe_high); __func__, t, t->pl.state, t->pl.pmtu, t->pl.probe_size, t->pl.probe_high);
...@@ -323,7 +329,7 @@ void sctp_transport_pl_recv(struct sctp_transport *t) ...@@ -323,7 +329,7 @@ void sctp_transport_pl_recv(struct sctp_transport *t)
if (!t->pl.probe_high) { if (!t->pl.probe_high) {
t->pl.probe_size = min(t->pl.probe_size + SCTP_PL_BIG_STEP, t->pl.probe_size = min(t->pl.probe_size + SCTP_PL_BIG_STEP,
SCTP_MAX_PLPMTU); SCTP_MAX_PLPMTU);
return; return false;
} }
t->pl.probe_size += SCTP_PL_MIN_STEP; t->pl.probe_size += SCTP_PL_MIN_STEP;
if (t->pl.probe_size >= t->pl.probe_high) { if (t->pl.probe_size >= t->pl.probe_high) {
...@@ -335,14 +341,13 @@ void sctp_transport_pl_recv(struct sctp_transport *t) ...@@ -335,14 +341,13 @@ void sctp_transport_pl_recv(struct sctp_transport *t)
t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t); t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
sctp_assoc_sync_pmtu(t->asoc); sctp_assoc_sync_pmtu(t->asoc);
} }
} else if (t->pl.state == SCTP_PL_COMPLETE) { } else if (t->pl.state == SCTP_PL_COMPLETE && t->pl.raise_count == 30) {
t->pl.raise_count++;
if (t->pl.raise_count == 30) {
/* Raise probe_size again after 30 * interval in Search Complete */ /* Raise probe_size again after 30 * interval in Search Complete */
t->pl.state = SCTP_PL_SEARCH; /* Search Complete -> Search */ t->pl.state = SCTP_PL_SEARCH; /* Search Complete -> Search */
t->pl.probe_size += SCTP_PL_MIN_STEP; t->pl.probe_size += SCTP_PL_MIN_STEP;
} }
}
return t->pl.state == SCTP_PL_COMPLETE;
} }
static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu) static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment