summaryrefslogtreecommitdiff
path: root/net/sctp/ulpevent.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2008-10-08 14:18:39 -0700
committerDavid S. Miller <davem@davemloft.net>2008-10-08 14:18:39 -0700
commit8e1ee18c332e08bee9d8bd66e63cd564fbf17fc2 (patch)
tree8dace1db660d555eb6e020f301fdfe6cf6c05b80 /net/sctp/ulpevent.c
parent3c689b7320ae6f20dba6a8b71806a6c6fd604ee8 (diff)
downloadlinux-3.10-8e1ee18c332e08bee9d8bd66e63cd564fbf17fc2.tar.gz
linux-3.10-8e1ee18c332e08bee9d8bd66e63cd564fbf17fc2.tar.bz2
linux-3.10-8e1ee18c332e08bee9d8bd66e63cd564fbf17fc2.zip
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/ulpevent.c')
-rw-r--r--net/sctp/ulpevent.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index a1f654aea26..5f186ca550d 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -713,7 +713,9 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
/* Now that all memory allocations for this chunk succeeded, we
* can mark it as received so the tsn_map is updated correctly.
*/
- sctp_tsnmap_mark(&asoc->peer.tsn_map, ntohl(chunk->subh.data_hdr->tsn));
+ if (sctp_tsnmap_mark(&asoc->peer.tsn_map,
+ ntohl(chunk->subh.data_hdr->tsn)))
+ goto fail_mark;
/* First calculate the padding, so we don't inadvertently
* pass up the wrong length to the user.
@@ -755,8 +757,12 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
event->msg_flags |= chunk->chunk_hdr->flags;
event->iif = sctp_chunk_iif(chunk);
-fail:
return event;
+
+fail_mark:
+ kfree_skb(skb);
+fail:
+ return NULL;
}
/* Create a partial delivery related event.