Commit e169285f authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

netfilter: nf_tables: do not store nft_ctx in transaction objects

nft_ctx is huge and most of the information stored within isn't used
at all.

Remove nft_ctx member from the base transaction structure and store
only what is needed.

After this change, relevant struct sizes are:

struct nft_trans_chain { /* size: 120 (-32), cachelines: 2, members: 10 */
struct nft_trans_elem { /* size: 72 (-40), cachelines: 2, members: 4 */
struct nft_trans_flowtable { /* size: 80 (-48), cachelines: 2, members: 5 */
struct nft_trans_obj { /* size: 72 (-40), cachelines: 2, members: 4 */
struct nft_trans_rule { /* size: 80 (-32), cachelines: 2, members: 6 */
struct nft_trans_set { /* size: 96 (-24), cachelines: 2, members: 8 */
struct nft_trans_table { /* size: 56 (-40), cachelines: 1, members: 2 */

struct nft_trans_elem can now be allocated from kmalloc-96 instead of
kmalloc-128 slab.
A further reduction by 8 bytes would even allow for kmalloc-64.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 0be90875
...@@ -1611,18 +1611,26 @@ static inline int nft_set_elem_is_dead(const struct nft_set_ext *ext) ...@@ -1611,18 +1611,26 @@ static inline int nft_set_elem_is_dead(const struct nft_set_ext *ext)
* struct nft_trans - nf_tables object update in transaction * struct nft_trans - nf_tables object update in transaction
* *
* @list: used internally * @list: used internally
* @net: struct net
* @table: struct nft_table the object resides in
* @msg_type: message type * @msg_type: message type
* @put_net: ctx->net needs to be put * @seq: netlink sequence number
* @ctx: transaction context * @flags: modifiers to new request
* @report: notify via unicast netlink message
* @put_net: net needs to be put
* *
* This is the information common to all objects in the transaction, * This is the information common to all objects in the transaction,
* this must always be the first member of derived sub-types. * this must always be the first member of derived sub-types.
*/ */
struct nft_trans { struct nft_trans {
struct list_head list; struct list_head list;
struct net *net;
struct nft_table *table;
int msg_type; int msg_type;
bool put_net; u32 seq;
struct nft_ctx ctx; u16 flags;
u8 report:1;
u8 put_net:1;
}; };
/** /**
...@@ -1794,6 +1802,33 @@ struct nft_trans_gc { ...@@ -1794,6 +1802,33 @@ struct nft_trans_gc {
struct rcu_head rcu; struct rcu_head rcu;
}; };
static inline void nft_ctx_update(struct nft_ctx *ctx,
const struct nft_trans *trans)
{
switch (trans->msg_type) {
case NFT_MSG_NEWRULE:
case NFT_MSG_DELRULE:
case NFT_MSG_DESTROYRULE:
ctx->chain = nft_trans_rule_chain(trans);
break;
case NFT_MSG_NEWCHAIN:
case NFT_MSG_DELCHAIN:
case NFT_MSG_DESTROYCHAIN:
ctx->chain = nft_trans_chain(trans);
break;
default:
ctx->chain = NULL;
break;
}
ctx->net = trans->net;
ctx->table = trans->table;
ctx->family = trans->table->family;
ctx->report = trans->report;
ctx->flags = trans->flags;
ctx->seq = trans->seq;
}
struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set, struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
unsigned int gc_seq, gfp_t gfp); unsigned int gc_seq, gfp_t gfp);
void nft_trans_gc_destroy(struct nft_trans_gc *trans); void nft_trans_gc_destroy(struct nft_trans_gc *trans);
......
This diff is collapsed.
...@@ -513,7 +513,7 @@ static void nft_flow_rule_offload_abort(struct net *net, ...@@ -513,7 +513,7 @@ static void nft_flow_rule_offload_abort(struct net *net,
int err = 0; int err = 0;
list_for_each_entry_continue_reverse(trans, &nft_net->commit_list, list) { list_for_each_entry_continue_reverse(trans, &nft_net->commit_list, list) {
if (trans->ctx.family != NFPROTO_NETDEV) if (trans->table->family != NFPROTO_NETDEV)
continue; continue;
switch (trans->msg_type) { switch (trans->msg_type) {
...@@ -564,7 +564,7 @@ int nft_flow_rule_offload_commit(struct net *net) ...@@ -564,7 +564,7 @@ int nft_flow_rule_offload_commit(struct net *net)
u8 policy; u8 policy;
list_for_each_entry(trans, &nft_net->commit_list, list) { list_for_each_entry(trans, &nft_net->commit_list, list) {
if (trans->ctx.family != NFPROTO_NETDEV) if (trans->table->family != NFPROTO_NETDEV)
continue; continue;
switch (trans->msg_type) { switch (trans->msg_type) {
...@@ -589,8 +589,8 @@ int nft_flow_rule_offload_commit(struct net *net) ...@@ -589,8 +589,8 @@ int nft_flow_rule_offload_commit(struct net *net)
if (!(nft_trans_rule_chain(trans)->flags & NFT_CHAIN_HW_OFFLOAD)) if (!(nft_trans_rule_chain(trans)->flags & NFT_CHAIN_HW_OFFLOAD))
continue; continue;
if (trans->ctx.flags & NLM_F_REPLACE || if (trans->flags & NLM_F_REPLACE ||
!(trans->ctx.flags & NLM_F_APPEND)) { !(trans->flags & NLM_F_APPEND)) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment