diff options
| author | David S. Miller <davem@davemloft.net> | 2014-07-09 01:39:09 +0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-07-09 01:39:09 +0400 |
| commit | 90fb5679e568b11b89e02b87f7f4fe00c7589ce0 (patch) | |
| tree | 8f30dc91827100ae42c0a90edc9cb00bb0fa56b4 /include | |
| parent | 63ae88949bc7f6b56438d430c55060d9eda981af (diff) | |
| parent | d1a3fe26e97c0f17579c39f8a446c50f7cc3154a (diff) | |
| download | linux-90fb5679e568b11b89e02b87f7f4fe00c7589ce0.tar.xz | |
Merge branch 'sctp_command_queue'
David Laight says:
====================
net: sctp: Optimisations to sctp command queue code
These 3 patches optimise the code that processes sctp's command queue.
(A list of 'tasks' to be performed after the rest of the chunk processing.)
1) Inline all the functions from command.c
2) Remove the memset() calls used to zero a word-sized union.
3) Use pointers instead of array indexes.
The combined changes reduce the code size (amd64) by a few kb.
I'm not 100% convinced that the zeroing done in patch 2 is needed at all.
On BE systems it is likely to generate more code than on LE ones.
In fact it might be best to change the union to only contain 'long' sized
items.
Changes for v2:
- Add some missing initialisers in patch 2/3 and delete them in 3/3.
- Modify the commit message for 2/3 to point out that the union
shouldn't need to be zeroed, but the patches aren't intended to
change the behaviour even if the code is buggy.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/sctp/command.h | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index 4b7cd695e431..f22538e68245 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h @@ -118,6 +118,7 @@ typedef enum { #define SCTP_MAX_NUM_COMMANDS 14 typedef union { + void *zero_all; /* Set to NULL to clear the entire union */ __s32 i32; __u32 u32; __be32 be32; @@ -154,7 +155,7 @@ typedef union { static inline sctp_arg_t \ SCTP_## name (type arg) \ { sctp_arg_t retval;\ - memset(&retval, 0, sizeof(sctp_arg_t));\ + retval.zero_all = NULL;\ retval.elt = arg;\ return retval;\ } @@ -191,7 +192,7 @@ static inline sctp_arg_t SCTP_NOFORCE(void) static inline sctp_arg_t SCTP_NULL(void) { sctp_arg_t retval; - memset(&retval, 0, sizeof(sctp_arg_t)); + retval.zero_all = NULL; return retval; } @@ -202,27 +203,49 @@ typedef struct { typedef struct { sctp_cmd_t cmds[SCTP_MAX_NUM_COMMANDS]; - __u8 next_free_slot; - __u8 next_cmd; + sctp_cmd_t *last_used_slot; + sctp_cmd_t *next_cmd; } sctp_cmd_seq_t; /* Initialize a block of memory as a command sequence. * Return 0 if the initialization fails. */ -int sctp_init_cmd_seq(sctp_cmd_seq_t *seq); +static inline int sctp_init_cmd_seq(sctp_cmd_seq_t *seq) +{ + /* cmds[] is filled backwards to simplify the overflow BUG() check */ + seq->last_used_slot = seq->cmds + SCTP_MAX_NUM_COMMANDS; + seq->next_cmd = seq->last_used_slot; + return 1; /* We always succeed. */ +} + /* Add a command to an sctp_cmd_seq_t. * * Use the SCTP_* constructors defined by SCTP_ARG_CONSTRUCTOR() above * to wrap data which goes in the obj argument. */ -void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj); +static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, + sctp_arg_t obj) +{ + sctp_cmd_t *cmd = seq->last_used_slot - 1; + + BUG_ON(cmd < seq->cmds); + + cmd->verb = verb; + cmd->obj = obj; + seq->last_used_slot = cmd; +} /* Return the next command structure in an sctp_cmd_seq. * Return NULL at the end of the sequence. */ -sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq); +static inline sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq) +{ + if (seq->next_cmd <= seq->last_used_slot) + return NULL; -#endif /* __net_sctp_command_h__ */ + return --seq->next_cmd; +} +#endif /* __net_sctp_command_h__ */ |
