aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/associola.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2008-10-08 17:18:39 -0400
committerDavid S. Miller <davem@davemloft.net>2008-10-08 17:18:39 -0400
commit8e1ee18c332e08bee9d8bd66e63cd564fbf17fc2 (patch)
tree8dace1db660d555eb6e020f301fdfe6cf6c05b80 /net/sctp/associola.c
parent3c689b7320ae6f20dba6a8b71806a6c6fd604ee8 (diff)
sctp: Rework the tsn map to use generic bitmap.
The tsn map currently use is 4K large and is stuck inside the sctp_association structure making memory references REALLY expensive. What we really need is at most 4K worth of bits so the biggest map we would have is 512 bytes. Also, the map is only really usefull when we have gaps to store and report. As such, starting with minimal map of say 32 TSNs (bits) should be enough for normal low-loss operations. We can grow the map by some multiple of 32 along with some extra room any time we receive the TSN which would put us outside of the map boundry. As we close gaps, we can shift the map to rebase it on the latest TSN we've seen. This saves 4088 bytes per association just in the map alone along savings from the now unnecessary structure members. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/associola.c')
-rw-r--r--net/sctp/associola.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index abd51cef2413..f4b23043b610 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -283,8 +283,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
283 if (!sctp_ulpq_init(&asoc->ulpq, asoc)) 283 if (!sctp_ulpq_init(&asoc->ulpq, asoc))
284 goto fail_init; 284 goto fail_init;
285 285
286 /* Set up the tsn tracking. */ 286 memset(&asoc->peer.tsn_map, 0, sizeof(struct sctp_tsnmap));
287 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 0);
288 287
289 asoc->need_ecne = 0; 288 asoc->need_ecne = 0;
290 289
@@ -402,6 +401,8 @@ void sctp_association_free(struct sctp_association *asoc)
402 /* Dispose of any pending chunks on the inqueue. */ 401 /* Dispose of any pending chunks on the inqueue. */
403 sctp_inq_free(&asoc->base.inqueue); 402 sctp_inq_free(&asoc->base.inqueue);
404 403
404 sctp_tsnmap_free(&asoc->peer.tsn_map);
405
405 /* Free ssnmap storage. */ 406 /* Free ssnmap storage. */
406 sctp_ssnmap_free(asoc->ssnmap); 407 sctp_ssnmap_free(asoc->ssnmap);
407 408
@@ -1122,8 +1123,8 @@ void sctp_assoc_update(struct sctp_association *asoc,
1122 asoc->peer.rwnd = new->peer.rwnd; 1123 asoc->peer.rwnd = new->peer.rwnd;
1123 asoc->peer.sack_needed = new->peer.sack_needed; 1124 asoc->peer.sack_needed = new->peer.sack_needed;
1124 asoc->peer.i = new->peer.i; 1125 asoc->peer.i = new->peer.i;
1125 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 1126 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
1126 asoc->peer.i.initial_tsn); 1127 asoc->peer.i.initial_tsn, GFP_ATOMIC);
1127 1128
1128 /* Remove any peer addresses not present in the new association. */ 1129 /* Remove any peer addresses not present in the new association. */
1129 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 1130 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {