xref: /OK3568_Linux_fs/kernel/net/sctp/tsnmap.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /* SCTP kernel implementation
3*4882a593Smuzhiyun  * (C) Copyright IBM Corp. 2001, 2004
4*4882a593Smuzhiyun  * Copyright (c) 1999-2000 Cisco, Inc.
5*4882a593Smuzhiyun  * Copyright (c) 1999-2001 Motorola, Inc.
6*4882a593Smuzhiyun  * Copyright (c) 2001 Intel Corp.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * This file is part of the SCTP kernel implementation
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * These functions manipulate sctp tsn mapping array.
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * Please send any bug reports or fixes you make to the
13*4882a593Smuzhiyun  * email address(es):
14*4882a593Smuzhiyun  *    lksctp developers <linux-sctp@vger.kernel.org>
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * Written or modified by:
17*4882a593Smuzhiyun  *    La Monte H.P. Yarroll <piggy@acm.org>
18*4882a593Smuzhiyun  *    Jon Grimm             <jgrimm@us.ibm.com>
19*4882a593Smuzhiyun  *    Karl Knutson          <karl@athena.chicago.il.us>
20*4882a593Smuzhiyun  *    Sridhar Samudrala     <sri@us.ibm.com>
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include <linux/slab.h>
24*4882a593Smuzhiyun #include <linux/types.h>
25*4882a593Smuzhiyun #include <linux/bitmap.h>
26*4882a593Smuzhiyun #include <net/sctp/sctp.h>
27*4882a593Smuzhiyun #include <net/sctp/sm.h>
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun static void sctp_tsnmap_update(struct sctp_tsnmap *map);
30*4882a593Smuzhiyun static void sctp_tsnmap_find_gap_ack(unsigned long *map, __u16 off,
31*4882a593Smuzhiyun 				     __u16 len, __u16 *start, __u16 *end);
32*4882a593Smuzhiyun static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 size);
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /* Initialize a block of memory as a tsnmap.  */
sctp_tsnmap_init(struct sctp_tsnmap * map,__u16 len,__u32 initial_tsn,gfp_t gfp)35*4882a593Smuzhiyun struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
36*4882a593Smuzhiyun 				     __u32 initial_tsn, gfp_t gfp)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun 	if (!map->tsn_map) {
39*4882a593Smuzhiyun 		map->tsn_map = kzalloc(len>>3, gfp);
40*4882a593Smuzhiyun 		if (map->tsn_map == NULL)
41*4882a593Smuzhiyun 			return NULL;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 		map->len = len;
44*4882a593Smuzhiyun 	} else {
45*4882a593Smuzhiyun 		bitmap_zero(map->tsn_map, map->len);
46*4882a593Smuzhiyun 	}
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	/* Keep track of TSNs represented by tsn_map.  */
49*4882a593Smuzhiyun 	map->base_tsn = initial_tsn;
50*4882a593Smuzhiyun 	map->cumulative_tsn_ack_point = initial_tsn - 1;
51*4882a593Smuzhiyun 	map->max_tsn_seen = map->cumulative_tsn_ack_point;
52*4882a593Smuzhiyun 	map->num_dup_tsns = 0;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	return map;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
sctp_tsnmap_free(struct sctp_tsnmap * map)57*4882a593Smuzhiyun void sctp_tsnmap_free(struct sctp_tsnmap *map)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun 	map->len = 0;
60*4882a593Smuzhiyun 	kfree(map->tsn_map);
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /* Test the tracking state of this TSN.
64*4882a593Smuzhiyun  * Returns:
65*4882a593Smuzhiyun  *   0 if the TSN has not yet been seen
66*4882a593Smuzhiyun  *  >0 if the TSN has been seen (duplicate)
67*4882a593Smuzhiyun  *  <0 if the TSN is invalid (too large to track)
68*4882a593Smuzhiyun  */
sctp_tsnmap_check(const struct sctp_tsnmap * map,__u32 tsn)69*4882a593Smuzhiyun int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	u32 gap;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	/* Check to see if this is an old TSN */
74*4882a593Smuzhiyun 	if (TSN_lte(tsn, map->cumulative_tsn_ack_point))
75*4882a593Smuzhiyun 		return 1;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	/* Verify that we can hold this TSN and that it will not
78*4882a593Smuzhiyun 	 * overlfow our map
79*4882a593Smuzhiyun 	 */
80*4882a593Smuzhiyun 	if (!TSN_lt(tsn, map->base_tsn + SCTP_TSN_MAP_SIZE))
81*4882a593Smuzhiyun 		return -1;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	/* Calculate the index into the mapping arrays.  */
84*4882a593Smuzhiyun 	gap = tsn - map->base_tsn;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	/* Check to see if TSN has already been recorded.  */
87*4882a593Smuzhiyun 	if (gap < map->len && test_bit(gap, map->tsn_map))
88*4882a593Smuzhiyun 		return 1;
89*4882a593Smuzhiyun 	else
90*4882a593Smuzhiyun 		return 0;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun /* Mark this TSN as seen.  */
sctp_tsnmap_mark(struct sctp_tsnmap * map,__u32 tsn,struct sctp_transport * trans)95*4882a593Smuzhiyun int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn,
96*4882a593Smuzhiyun 		     struct sctp_transport *trans)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	u16 gap;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	if (TSN_lt(tsn, map->base_tsn))
101*4882a593Smuzhiyun 		return 0;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	gap = tsn - map->base_tsn;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	if (gap >= map->len && !sctp_tsnmap_grow(map, gap + 1))
106*4882a593Smuzhiyun 		return -ENOMEM;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	if (!sctp_tsnmap_has_gap(map) && gap == 0) {
109*4882a593Smuzhiyun 		/* In this case the map has no gaps and the tsn we are
110*4882a593Smuzhiyun 		 * recording is the next expected tsn.  We don't touch
111*4882a593Smuzhiyun 		 * the map but simply bump the values.
112*4882a593Smuzhiyun 		 */
113*4882a593Smuzhiyun 		map->max_tsn_seen++;
114*4882a593Smuzhiyun 		map->cumulative_tsn_ack_point++;
115*4882a593Smuzhiyun 		if (trans)
116*4882a593Smuzhiyun 			trans->sack_generation =
117*4882a593Smuzhiyun 				trans->asoc->peer.sack_generation;
118*4882a593Smuzhiyun 		map->base_tsn++;
119*4882a593Smuzhiyun 	} else {
120*4882a593Smuzhiyun 		/* Either we already have a gap, or about to record a gap, so
121*4882a593Smuzhiyun 		 * have work to do.
122*4882a593Smuzhiyun 		 *
123*4882a593Smuzhiyun 		 * Bump the max.
124*4882a593Smuzhiyun 		 */
125*4882a593Smuzhiyun 		if (TSN_lt(map->max_tsn_seen, tsn))
126*4882a593Smuzhiyun 			map->max_tsn_seen = tsn;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 		/* Mark the TSN as received.  */
129*4882a593Smuzhiyun 		set_bit(gap, map->tsn_map);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 		/* Go fixup any internal TSN mapping variables including
132*4882a593Smuzhiyun 		 * cumulative_tsn_ack_point.
133*4882a593Smuzhiyun 		 */
134*4882a593Smuzhiyun 		sctp_tsnmap_update(map);
135*4882a593Smuzhiyun 	}
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	return 0;
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun /* Initialize a Gap Ack Block iterator from memory being provided.  */
sctp_tsnmap_iter_init(const struct sctp_tsnmap * map,struct sctp_tsnmap_iter * iter)142*4882a593Smuzhiyun static void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
143*4882a593Smuzhiyun 				  struct sctp_tsnmap_iter *iter)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	/* Only start looking one past the Cumulative TSN Ack Point.  */
146*4882a593Smuzhiyun 	iter->start = map->cumulative_tsn_ack_point + 1;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun /* Get the next Gap Ack Blocks. Returns 0 if there was not another block
150*4882a593Smuzhiyun  * to get.
151*4882a593Smuzhiyun  */
sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap * map,struct sctp_tsnmap_iter * iter,__u16 * start,__u16 * end)152*4882a593Smuzhiyun static int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
153*4882a593Smuzhiyun 				    struct sctp_tsnmap_iter *iter,
154*4882a593Smuzhiyun 				    __u16 *start, __u16 *end)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun 	int ended = 0;
157*4882a593Smuzhiyun 	__u16 start_ = 0, end_ = 0, offset;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	/* If there are no more gap acks possible, get out fast.  */
160*4882a593Smuzhiyun 	if (TSN_lte(map->max_tsn_seen, iter->start))
161*4882a593Smuzhiyun 		return 0;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	offset = iter->start - map->base_tsn;
164*4882a593Smuzhiyun 	sctp_tsnmap_find_gap_ack(map->tsn_map, offset, map->len,
165*4882a593Smuzhiyun 				 &start_, &end_);
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	/* The Gap Ack Block happens to end at the end of the map. */
168*4882a593Smuzhiyun 	if (start_ && !end_)
169*4882a593Smuzhiyun 		end_ = map->len - 1;
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	/* If we found a Gap Ack Block, return the start and end and
172*4882a593Smuzhiyun 	 * bump the iterator forward.
173*4882a593Smuzhiyun 	 */
174*4882a593Smuzhiyun 	if (end_) {
175*4882a593Smuzhiyun 		/* Fix up the start and end based on the
176*4882a593Smuzhiyun 		 * Cumulative TSN Ack which is always 1 behind base.
177*4882a593Smuzhiyun 		 */
178*4882a593Smuzhiyun 		*start = start_ + 1;
179*4882a593Smuzhiyun 		*end = end_ + 1;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 		/* Move the iterator forward.  */
182*4882a593Smuzhiyun 		iter->start = map->cumulative_tsn_ack_point + *end + 1;
183*4882a593Smuzhiyun 		ended = 1;
184*4882a593Smuzhiyun 	}
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	return ended;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun /* Mark this and any lower TSN as seen.  */
sctp_tsnmap_skip(struct sctp_tsnmap * map,__u32 tsn)190*4882a593Smuzhiyun void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun 	u32 gap;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	if (TSN_lt(tsn, map->base_tsn))
195*4882a593Smuzhiyun 		return;
196*4882a593Smuzhiyun 	if (!TSN_lt(tsn, map->base_tsn + SCTP_TSN_MAP_SIZE))
197*4882a593Smuzhiyun 		return;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	/* Bump the max.  */
200*4882a593Smuzhiyun 	if (TSN_lt(map->max_tsn_seen, tsn))
201*4882a593Smuzhiyun 		map->max_tsn_seen = tsn;
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	gap = tsn - map->base_tsn + 1;
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	map->base_tsn += gap;
206*4882a593Smuzhiyun 	map->cumulative_tsn_ack_point += gap;
207*4882a593Smuzhiyun 	if (gap >= map->len) {
208*4882a593Smuzhiyun 		/* If our gap is larger then the map size, just
209*4882a593Smuzhiyun 		 * zero out the map.
210*4882a593Smuzhiyun 		 */
211*4882a593Smuzhiyun 		bitmap_zero(map->tsn_map, map->len);
212*4882a593Smuzhiyun 	} else {
213*4882a593Smuzhiyun 		/* If the gap is smaller than the map size,
214*4882a593Smuzhiyun 		 * shift the map by 'gap' bits and update further.
215*4882a593Smuzhiyun 		 */
216*4882a593Smuzhiyun 		bitmap_shift_right(map->tsn_map, map->tsn_map, gap, map->len);
217*4882a593Smuzhiyun 		sctp_tsnmap_update(map);
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun /********************************************************************
222*4882a593Smuzhiyun  * 2nd Level Abstractions
223*4882a593Smuzhiyun  ********************************************************************/
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun /* This private helper function updates the tsnmap buffers and
226*4882a593Smuzhiyun  * the Cumulative TSN Ack Point.
227*4882a593Smuzhiyun  */
sctp_tsnmap_update(struct sctp_tsnmap * map)228*4882a593Smuzhiyun static void sctp_tsnmap_update(struct sctp_tsnmap *map)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	u16 len;
231*4882a593Smuzhiyun 	unsigned long zero_bit;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	len = map->max_tsn_seen - map->cumulative_tsn_ack_point;
235*4882a593Smuzhiyun 	zero_bit = find_first_zero_bit(map->tsn_map, len);
236*4882a593Smuzhiyun 	if (!zero_bit)
237*4882a593Smuzhiyun 		return;		/* The first 0-bit is bit 0.  nothing to do */
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	map->base_tsn += zero_bit;
240*4882a593Smuzhiyun 	map->cumulative_tsn_ack_point += zero_bit;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	bitmap_shift_right(map->tsn_map, map->tsn_map, zero_bit, map->len);
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun /* How many data chunks  are we missing from our peer?
246*4882a593Smuzhiyun  */
sctp_tsnmap_pending(struct sctp_tsnmap * map)247*4882a593Smuzhiyun __u16 sctp_tsnmap_pending(struct sctp_tsnmap *map)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun 	__u32 cum_tsn = map->cumulative_tsn_ack_point;
250*4882a593Smuzhiyun 	__u32 max_tsn = map->max_tsn_seen;
251*4882a593Smuzhiyun 	__u32 base_tsn = map->base_tsn;
252*4882a593Smuzhiyun 	__u16 pending_data;
253*4882a593Smuzhiyun 	u32 gap;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	pending_data = max_tsn - cum_tsn;
256*4882a593Smuzhiyun 	gap = max_tsn - base_tsn;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	if (gap == 0 || gap >= map->len)
259*4882a593Smuzhiyun 		goto out;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	pending_data -= bitmap_weight(map->tsn_map, gap + 1);
262*4882a593Smuzhiyun out:
263*4882a593Smuzhiyun 	return pending_data;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun /* This is a private helper for finding Gap Ack Blocks.  It searches a
267*4882a593Smuzhiyun  * single array for the start and end of a Gap Ack Block.
268*4882a593Smuzhiyun  *
269*4882a593Smuzhiyun  * The flags "started" and "ended" tell is if we found the beginning
270*4882a593Smuzhiyun  * or (respectively) the end of a Gap Ack Block.
271*4882a593Smuzhiyun  */
sctp_tsnmap_find_gap_ack(unsigned long * map,__u16 off,__u16 len,__u16 * start,__u16 * end)272*4882a593Smuzhiyun static void sctp_tsnmap_find_gap_ack(unsigned long *map, __u16 off,
273*4882a593Smuzhiyun 				     __u16 len, __u16 *start, __u16 *end)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun 	int i = off;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	/* Look through the entire array, but break out
278*4882a593Smuzhiyun 	 * early if we have found the end of the Gap Ack Block.
279*4882a593Smuzhiyun 	 */
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	/* Also, stop looking past the maximum TSN seen. */
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	/* Look for the start. */
284*4882a593Smuzhiyun 	i = find_next_bit(map, len, off);
285*4882a593Smuzhiyun 	if (i < len)
286*4882a593Smuzhiyun 		*start = i;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	/* Look for the end.  */
289*4882a593Smuzhiyun 	if (*start) {
290*4882a593Smuzhiyun 		/* We have found the start, let's find the
291*4882a593Smuzhiyun 		 * end.  If we find the end, break out.
292*4882a593Smuzhiyun 		 */
293*4882a593Smuzhiyun 		i = find_next_zero_bit(map, len, i);
294*4882a593Smuzhiyun 		if (i < len)
295*4882a593Smuzhiyun 			*end = i - 1;
296*4882a593Smuzhiyun 	}
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun /* Renege that we have seen a TSN.  */
sctp_tsnmap_renege(struct sctp_tsnmap * map,__u32 tsn)300*4882a593Smuzhiyun void sctp_tsnmap_renege(struct sctp_tsnmap *map, __u32 tsn)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	u32 gap;
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	if (TSN_lt(tsn, map->base_tsn))
305*4882a593Smuzhiyun 		return;
306*4882a593Smuzhiyun 	/* Assert: TSN is in range.  */
307*4882a593Smuzhiyun 	if (!TSN_lt(tsn, map->base_tsn + map->len))
308*4882a593Smuzhiyun 		return;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	gap = tsn - map->base_tsn;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	/* Pretend we never saw the TSN.  */
313*4882a593Smuzhiyun 	clear_bit(gap, map->tsn_map);
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun /* How many gap ack blocks do we have recorded? */
sctp_tsnmap_num_gabs(struct sctp_tsnmap * map,struct sctp_gap_ack_block * gabs)317*4882a593Smuzhiyun __u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map,
318*4882a593Smuzhiyun 			   struct sctp_gap_ack_block *gabs)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun 	struct sctp_tsnmap_iter iter;
321*4882a593Smuzhiyun 	int ngaps = 0;
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	/* Refresh the gap ack information. */
324*4882a593Smuzhiyun 	if (sctp_tsnmap_has_gap(map)) {
325*4882a593Smuzhiyun 		__u16 start = 0, end = 0;
326*4882a593Smuzhiyun 		sctp_tsnmap_iter_init(map, &iter);
327*4882a593Smuzhiyun 		while (sctp_tsnmap_next_gap_ack(map, &iter,
328*4882a593Smuzhiyun 						&start,
329*4882a593Smuzhiyun 						&end)) {
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 			gabs[ngaps].start = htons(start);
332*4882a593Smuzhiyun 			gabs[ngaps].end = htons(end);
333*4882a593Smuzhiyun 			ngaps++;
334*4882a593Smuzhiyun 			if (ngaps >= SCTP_MAX_GABS)
335*4882a593Smuzhiyun 				break;
336*4882a593Smuzhiyun 		}
337*4882a593Smuzhiyun 	}
338*4882a593Smuzhiyun 	return ngaps;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun 
sctp_tsnmap_grow(struct sctp_tsnmap * map,u16 size)341*4882a593Smuzhiyun static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 size)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun 	unsigned long *new;
344*4882a593Smuzhiyun 	unsigned long inc;
345*4882a593Smuzhiyun 	u16  len;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	if (size > SCTP_TSN_MAP_SIZE)
348*4882a593Smuzhiyun 		return 0;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	inc = ALIGN((size - map->len), BITS_PER_LONG) + SCTP_TSN_MAP_INCREMENT;
351*4882a593Smuzhiyun 	len = min_t(u16, map->len + inc, SCTP_TSN_MAP_SIZE);
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	new = kzalloc(len>>3, GFP_ATOMIC);
354*4882a593Smuzhiyun 	if (!new)
355*4882a593Smuzhiyun 		return 0;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	bitmap_copy(new, map->tsn_map,
358*4882a593Smuzhiyun 		map->max_tsn_seen - map->cumulative_tsn_ack_point);
359*4882a593Smuzhiyun 	kfree(map->tsn_map);
360*4882a593Smuzhiyun 	map->tsn_map = new;
361*4882a593Smuzhiyun 	map->len = len;
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	return 1;
364*4882a593Smuzhiyun }
365