aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/sctp
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 /include/net/sctp
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 'include/net/sctp')
-rw-r--r--include/net/sctp/constants.h4
-rw-r--r--include/net/sctp/structs.h1
-rw-r--r--include/net/sctp/tsnmap.h39
3 files changed, 12 insertions, 32 deletions
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index c32ddf0279c8..b05b0557211f 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -261,7 +261,9 @@ enum { SCTP_ARBITRARY_COOKIE_ECHO_LEN = 200 };
261 * must be less than 65535 (2^16 - 1), or we will have overflow 261 * must be less than 65535 (2^16 - 1), or we will have overflow
262 * problems creating SACK's. 262 * problems creating SACK's.
263 */ 263 */
264#define SCTP_TSN_MAP_SIZE 2048 264#define SCTP_TSN_MAP_INITIAL BITS_PER_LONG
265#define SCTP_TSN_MAP_INCREMENT SCTP_TSN_MAP_INITIAL
266#define SCTP_TSN_MAP_SIZE 4096
265#define SCTP_TSN_MAX_GAP 65535 267#define SCTP_TSN_MAX_GAP 65535
266 268
267/* We will not record more than this many duplicate TSNs between two 269/* We will not record more than this many duplicate TSNs between two
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 94c62e4ddea9..9661d7b765f0 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1545,7 +1545,6 @@ struct sctp_association {
1545 * in tsn_map--we get it by calling sctp_tsnmap_get_ctsn(). 1545 * in tsn_map--we get it by calling sctp_tsnmap_get_ctsn().
1546 */ 1546 */
1547 struct sctp_tsnmap tsn_map; 1547 struct sctp_tsnmap tsn_map;
1548 __u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)];
1549 1548
1550 /* Ack State : This flag indicates if the next received 1549 /* Ack State : This flag indicates if the next received
1551 * : packet is to be responded to with a 1550 * : packet is to be responded to with a
diff --git a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h
index 099211bf998d..6dabbee8bbd3 100644
--- a/include/net/sctp/tsnmap.h
+++ b/include/net/sctp/tsnmap.h
@@ -60,18 +60,7 @@ struct sctp_tsnmap {
60 * It points at one of the two buffers with which we will 60 * It points at one of the two buffers with which we will
61 * ping-pong between. 61 * ping-pong between.
62 */ 62 */
63 __u8 *tsn_map; 63 unsigned long *tsn_map;
64
65 /* This marks the tsn which overflows the tsn_map, when the
66 * cumulative ack point reaches this point we know we can switch
67 * maps (tsn_map and overflow_map swap).
68 */
69 __u32 overflow_tsn;
70
71 /* This is the overflow array for tsn_map.
72 * It points at one of the other ping-pong buffers.
73 */
74 __u8 *overflow_map;
75 64
76 /* This is the TSN at tsn_map[0]. */ 65 /* This is the TSN at tsn_map[0]. */
77 __u32 base_tsn; 66 __u32 base_tsn;
@@ -89,15 +78,15 @@ struct sctp_tsnmap {
89 */ 78 */
90 __u32 cumulative_tsn_ack_point; 79 __u32 cumulative_tsn_ack_point;
91 80
81 /* This is the highest TSN we've marked. */
82 __u32 max_tsn_seen;
83
92 /* This is the minimum number of TSNs we can track. This corresponds 84 /* This is the minimum number of TSNs we can track. This corresponds
93 * to the size of tsn_map. Note: the overflow_map allows us to 85 * to the size of tsn_map. Note: the overflow_map allows us to
94 * potentially track more than this quantity. 86 * potentially track more than this quantity.
95 */ 87 */
96 __u16 len; 88 __u16 len;
97 89
98 /* This is the highest TSN we've marked. */
99 __u32 max_tsn_seen;
100
101 /* Data chunks pending receipt. used by SCTP_STATUS sockopt */ 90 /* Data chunks pending receipt. used by SCTP_STATUS sockopt */
102 __u16 pending_data; 91 __u16 pending_data;
103 92
@@ -110,24 +99,17 @@ struct sctp_tsnmap {
110 99
111 /* Record gap ack block information here. */ 100 /* Record gap ack block information here. */
112 struct sctp_gap_ack_block gabs[SCTP_MAX_GABS]; 101 struct sctp_gap_ack_block gabs[SCTP_MAX_GABS];
113
114 int malloced;
115
116 __u8 raw_map[0];
117}; 102};
118 103
119struct sctp_tsnmap_iter { 104struct sctp_tsnmap_iter {
120 __u32 start; 105 __u32 start;
121}; 106};
122 107
123/* This macro assists in creation of external storage for variable length
124 * internal buffers. We double allocate so the overflow map works.
125 */
126#define sctp_tsnmap_storage_size(count) (sizeof(__u8) * (count) * 2)
127
128/* Initialize a block of memory as a tsnmap. */ 108/* Initialize a block of memory as a tsnmap. */
129struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len, 109struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len,
130 __u32 initial_tsn); 110 __u32 initial_tsn, gfp_t gfp);
111
112void sctp_tsnmap_free(struct sctp_tsnmap *map);
131 113
132/* Test the tracking state of this TSN. 114/* Test the tracking state of this TSN.
133 * Returns: 115 * Returns:
@@ -138,7 +120,7 @@ struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len,
138int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn); 120int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn);
139 121
140/* Mark this TSN as seen. */ 122/* Mark this TSN as seen. */
141void sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn); 123int sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn);
142 124
143/* Mark this TSN and all lower as seen. */ 125/* Mark this TSN and all lower as seen. */
144void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn); 126void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn);
@@ -183,10 +165,7 @@ static inline struct sctp_gap_ack_block *sctp_tsnmap_get_gabs(struct sctp_tsnmap
183/* Is there a gap in the TSN map? */ 165/* Is there a gap in the TSN map? */
184static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map) 166static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map)
185{ 167{
186 int has_gap; 168 return (map->cumulative_tsn_ack_point != map->max_tsn_seen);
187
188 has_gap = (map->cumulative_tsn_ack_point != map->max_tsn_seen);
189 return has_gap;
190} 169}
191 170
192/* Mark a duplicate TSN. Note: limit the storage of duplicate TSN 171/* Mark a duplicate TSN. Note: limit the storage of duplicate TSN