Skip to content

Commit 182691d

Browse files
marceloleitnerdavem330
authored andcommitted
sctp: improve how SSN, TSN and ASCONF serial are compared
Make it similar to time_before() macros: - easier to understand - make use of typecheck() to avoid working on unexpected variable types (made the issue on previous patch visible) - for _[lg]te versions, slighly faster, as the compiler used to generate a sequence of cmp/je/cmp/js instructions and now it's sub/test/jle (for _lte): Before, for sctp_outq_sack: if (primary->cacc.changeover_active) { 1f01: 80 b9 84 02 00 00 00 cmpb $0x0,0x284(%rcx) 1f08: 74 6e je 1f78 <sctp_outq_sack+0xe8> u8 clear_cycling = 0; if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) { 1f0a: 8b 81 80 02 00 00 mov 0x280(%rcx),%eax return ((s) - (t)) & TSN_SIGN_BIT; } static inline int TSN_lte(__u32 s, __u32 t) { return ((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT); 1f10: 8b 7d bc mov -0x44(%rbp),%edi 1f13: 39 c7 cmp %eax,%edi 1f15: 74 25 je 1f3c <sctp_outq_sack+0xac> 1f17: 39 f8 cmp %edi,%eax 1f19: 78 21 js 1f3c <sctp_outq_sack+0xac> primary->cacc.changeover_active = 0; After: if (primary->cacc.changeover_active) { 1ee7: 80 b9 84 02 00 00 00 cmpb $0x0,0x284(%rcx) 1eee: 74 73 je 1f63 <sctp_outq_sack+0xf3> u8 clear_cycling = 0; if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) { 1ef0: 8b 81 80 02 00 00 mov 0x280(%rcx),%eax 1ef6: 2b 45 b4 sub -0x4c(%rbp),%eax 1ef9: 85 c0 test %eax,%eax 1efb: 7e 26 jle 1f23 <sctp_outq_sack+0xb3> primary->cacc.changeover_active = 0; *_lt() generated pretty much the same code. Tested with gcc (GCC) 6.1.1 20160621. This patch also removes SSN_lte as it is not used and cleanups some comments. Signed-off-by: Marcelo Ricardo Leitner <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a300744 commit 182691d

File tree

1 file changed

+18
-76
lines changed
  • include/net/sctp

1 file changed

+18
-76
lines changed

include/net/sctp/sm.h

Lines changed: 18 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -307,85 +307,27 @@ static inline __u16 sctp_data_size(struct sctp_chunk *chunk)
307307
}
308308

309309
/* Compare two TSNs */
310+
#define TSN_lt(a,b) \
311+
(typecheck(__u32, a) && \
312+
typecheck(__u32, b) && \
313+
((__s32)((a) - (b)) < 0))
310314

311-
/* RFC 1982 - Serial Number Arithmetic
312-
*
313-
* 2. Comparison
314-
* Then, s1 is said to be equal to s2 if and only if i1 is equal to i2,
315-
* in all other cases, s1 is not equal to s2.
316-
*
317-
* s1 is said to be less than s2 if, and only if, s1 is not equal to s2,
318-
* and
319-
*
320-
* (i1 < i2 and i2 - i1 < 2^(SERIAL_BITS - 1)) or
321-
* (i1 > i2 and i1 - i2 > 2^(SERIAL_BITS - 1))
322-
*
323-
* s1 is said to be greater than s2 if, and only if, s1 is not equal to
324-
* s2, and
325-
*
326-
* (i1 < i2 and i2 - i1 > 2^(SERIAL_BITS - 1)) or
327-
* (i1 > i2 and i1 - i2 < 2^(SERIAL_BITS - 1))
328-
*/
329-
330-
/*
331-
* RFC 2960
332-
* 1.6 Serial Number Arithmetic
333-
*
334-
* Comparisons and arithmetic on TSNs in this document SHOULD use Serial
335-
* Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32.
336-
*/
337-
338-
enum {
339-
TSN_SIGN_BIT = (1<<31)
340-
};
341-
342-
static inline int TSN_lt(__u32 s, __u32 t)
343-
{
344-
return ((s) - (t)) & TSN_SIGN_BIT;
345-
}
346-
347-
static inline int TSN_lte(__u32 s, __u32 t)
348-
{
349-
return ((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT);
350-
}
315+
#define TSN_lte(a,b) \
316+
(typecheck(__u32, a) && \
317+
typecheck(__u32, b) && \
318+
((__s32)((a) - (b)) <= 0))
351319

352320
/* Compare two SSNs */
353-
354-
/*
355-
* RFC 2960
356-
* 1.6 Serial Number Arithmetic
357-
*
358-
* Comparisons and arithmetic on Stream Sequence Numbers in this document
359-
* SHOULD use Serial Number Arithmetic as defined in [RFC1982] where
360-
* SERIAL_BITS = 16.
361-
*/
362-
enum {
363-
SSN_SIGN_BIT = (1<<15)
364-
};
365-
366-
static inline int SSN_lt(__u16 s, __u16 t)
367-
{
368-
return ((s) - (t)) & SSN_SIGN_BIT;
369-
}
370-
371-
static inline int SSN_lte(__u16 s, __u16 t)
372-
{
373-
return ((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT);
374-
}
375-
376-
/*
377-
* ADDIP 3.1.1
378-
* The valid range of Serial Number is from 0 to 4294967295 (2**32 - 1). Serial
379-
* Numbers wrap back to 0 after reaching 4294967295.
380-
*/
381-
enum {
382-
ADDIP_SERIAL_SIGN_BIT = (1<<31)
383-
};
384-
385-
static inline int ADDIP_SERIAL_gte(__u32 s, __u32 t)
386-
{
387-
return ((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT);
388-
}
321+
#define SSN_lt(a,b) \
322+
(typecheck(__u16, a) && \
323+
typecheck(__u16, b) && \
324+
((__s16)((a) - (b)) < 0))
325+
326+
/* ADDIP 3.1.1 */
327+
#define ADDIP_SERIAL_gte(a,b) \
328+
(typecheck(__u32, a) && \
329+
typecheck(__u32, b) && \
330+
((__s32)((b) - (a)) <= 0))
389331

390332
/* Check VTAG of the packet matches the sender's own tag. */
391333
static inline int

0 commit comments

Comments
 (0)