diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2008-10-08 17:18:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-08 17:18:39 -0400 |
commit | 8e1ee18c332e08bee9d8bd66e63cd564fbf17fc2 (patch) | |
tree | 8dace1db660d555eb6e020f301fdfe6cf6c05b80 /net/sctp/associola.c | |
parent | 3c689b7320ae6f20dba6a8b71806a6c6fd604ee8 (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.c | 9 |
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) { |