mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 15:12:13 +02:00
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 <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a3007446e5
commit
182691d099
|
|
@ -307,85 +307,27 @@ static inline __u16 sctp_data_size(struct sctp_chunk *chunk)
|
|||
}
|
||||
|
||||
/* Compare two TSNs */
|
||||
#define TSN_lt(a,b) \
|
||||
(typecheck(__u32, a) && \
|
||||
typecheck(__u32, b) && \
|
||||
((__s32)((a) - (b)) < 0))
|
||||
|
||||
/* RFC 1982 - Serial Number Arithmetic
|
||||
*
|
||||
* 2. Comparison
|
||||
* Then, s1 is said to be equal to s2 if and only if i1 is equal to i2,
|
||||
* in all other cases, s1 is not equal to s2.
|
||||
*
|
||||
* s1 is said to be less than s2 if, and only if, s1 is not equal to s2,
|
||||
* and
|
||||
*
|
||||
* (i1 < i2 and i2 - i1 < 2^(SERIAL_BITS - 1)) or
|
||||
* (i1 > i2 and i1 - i2 > 2^(SERIAL_BITS - 1))
|
||||
*
|
||||
* s1 is said to be greater than s2 if, and only if, s1 is not equal to
|
||||
* s2, and
|
||||
*
|
||||
* (i1 < i2 and i2 - i1 > 2^(SERIAL_BITS - 1)) or
|
||||
* (i1 > i2 and i1 - i2 < 2^(SERIAL_BITS - 1))
|
||||
*/
|
||||
|
||||
/*
|
||||
* RFC 2960
|
||||
* 1.6 Serial Number Arithmetic
|
||||
*
|
||||
* Comparisons and arithmetic on TSNs in this document SHOULD use Serial
|
||||
* Number Arithmetic as defined in [RFC1982] where SERIAL_BITS = 32.
|
||||
*/
|
||||
|
||||
enum {
|
||||
TSN_SIGN_BIT = (1<<31)
|
||||
};
|
||||
|
||||
static inline int TSN_lt(__u32 s, __u32 t)
|
||||
{
|
||||
return ((s) - (t)) & TSN_SIGN_BIT;
|
||||
}
|
||||
|
||||
static inline int TSN_lte(__u32 s, __u32 t)
|
||||
{
|
||||
return ((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT);
|
||||
}
|
||||
#define TSN_lte(a,b) \
|
||||
(typecheck(__u32, a) && \
|
||||
typecheck(__u32, b) && \
|
||||
((__s32)((a) - (b)) <= 0))
|
||||
|
||||
/* Compare two SSNs */
|
||||
#define SSN_lt(a,b) \
|
||||
(typecheck(__u16, a) && \
|
||||
typecheck(__u16, b) && \
|
||||
((__s16)((a) - (b)) < 0))
|
||||
|
||||
/*
|
||||
* RFC 2960
|
||||
* 1.6 Serial Number Arithmetic
|
||||
*
|
||||
* Comparisons and arithmetic on Stream Sequence Numbers in this document
|
||||
* SHOULD use Serial Number Arithmetic as defined in [RFC1982] where
|
||||
* SERIAL_BITS = 16.
|
||||
*/
|
||||
enum {
|
||||
SSN_SIGN_BIT = (1<<15)
|
||||
};
|
||||
|
||||
static inline int SSN_lt(__u16 s, __u16 t)
|
||||
{
|
||||
return ((s) - (t)) & SSN_SIGN_BIT;
|
||||
}
|
||||
|
||||
static inline int SSN_lte(__u16 s, __u16 t)
|
||||
{
|
||||
return ((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT);
|
||||
}
|
||||
|
||||
/*
|
||||
* ADDIP 3.1.1
|
||||
* The valid range of Serial Number is from 0 to 4294967295 (2**32 - 1). Serial
|
||||
* Numbers wrap back to 0 after reaching 4294967295.
|
||||
*/
|
||||
enum {
|
||||
ADDIP_SERIAL_SIGN_BIT = (1<<31)
|
||||
};
|
||||
|
||||
static inline int ADDIP_SERIAL_gte(__u32 s, __u32 t)
|
||||
{
|
||||
return ((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT);
|
||||
}
|
||||
/* ADDIP 3.1.1 */
|
||||
#define ADDIP_SERIAL_gte(a,b) \
|
||||
(typecheck(__u32, a) && \
|
||||
typecheck(__u32, b) && \
|
||||
((__s32)((b) - (a)) <= 0))
|
||||
|
||||
/* Check VTAG of the packet matches the sender's own tag. */
|
||||
static inline int
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user