|
|
19e5f4 |
From 26c4f15080663a12006abf8539ebf28bb223e6d9 Mon Sep 17 00:00:00 2001
|
|
|
19e5f4 |
From: Phil Sutter <psutter@redhat.com>
|
|
|
19e5f4 |
Date: Mon, 7 Dec 2020 18:29:15 +0100
|
|
|
19e5f4 |
Subject: [PATCH] json: echo: Speedup seqnum_to_json()
|
|
|
19e5f4 |
|
|
|
19e5f4 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1900565
|
|
|
19e5f4 |
Upstream Status: nftables commit 389a0e1edc89a
|
|
|
19e5f4 |
|
|
|
19e5f4 |
commit 389a0e1edc89a4048a272e569d3349b1d43bc567
|
|
|
19e5f4 |
Author: Phil Sutter <phil@nwl.cc>
|
|
|
19e5f4 |
Date: Fri Nov 20 20:01:59 2020 +0100
|
|
|
19e5f4 |
|
|
|
19e5f4 |
json: echo: Speedup seqnum_to_json()
|
|
|
19e5f4 |
|
|
|
19e5f4 |
Derek Dai reports:
|
|
|
19e5f4 |
"If there are a lot of command in JSON node, seqnum_to_json() will slow
|
|
|
19e5f4 |
down application (eg: firewalld) dramatically since it iterate whole
|
|
|
19e5f4 |
command list every time."
|
|
|
19e5f4 |
|
|
|
19e5f4 |
He sent a patch implementing a lookup table, but we can do better: Speed
|
|
|
19e5f4 |
this up by introducing a hash table to store the struct json_cmd_assoc
|
|
|
19e5f4 |
objects in, taking their netlink sequence number as key.
|
|
|
19e5f4 |
|
|
|
19e5f4 |
Quickly tested restoring a ruleset containing about 19k rules:
|
|
|
19e5f4 |
|
|
|
19e5f4 |
| # time ./before/nft -jeaf large_ruleset.json >/dev/null
|
|
|
19e5f4 |
| 4.85user 0.47system 0:05.48elapsed 97%CPU (0avgtext+0avgdata 69732maxresident)k
|
|
|
19e5f4 |
| 0inputs+0outputs (15major+16937minor)pagefaults 0swaps
|
|
|
19e5f4 |
|
|
|
19e5f4 |
| # time ./after/nft -jeaf large_ruleset.json >/dev/null
|
|
|
19e5f4 |
| 0.18user 0.44system 0:00.70elapsed 89%CPU (0avgtext+0avgdata 68484maxresident)k
|
|
|
19e5f4 |
| 0inputs+0outputs (15major+16645minor)pagefaults 0swaps
|
|
|
19e5f4 |
|
|
|
19e5f4 |
Bugzilla: https://bugzilla.netfilter.org/show_bug.cgi?id=1479
|
|
|
19e5f4 |
Reported-by: Derek Dai <daiderek@gmail.com>
|
|
|
19e5f4 |
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
19e5f4 |
---
|
|
|
19e5f4 |
src/parser_json.c | 28 ++++++++++++++++++----------
|
|
|
19e5f4 |
1 file changed, 18 insertions(+), 10 deletions(-)
|
|
|
19e5f4 |
|
|
|
19e5f4 |
diff --git a/src/parser_json.c b/src/parser_json.c
|
|
|
19e5f4 |
index ddc694f..107dc38 100644
|
|
|
19e5f4 |
--- a/src/parser_json.c
|
|
|
19e5f4 |
+++ b/src/parser_json.c
|
|
|
19e5f4 |
@@ -3646,42 +3646,50 @@ static int json_verify_metainfo(struct json_ctx *ctx, json_t *root)
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
|
|
|
19e5f4 |
struct json_cmd_assoc {
|
|
|
19e5f4 |
- struct json_cmd_assoc *next;
|
|
|
19e5f4 |
+ struct hlist_node hnode;
|
|
|
19e5f4 |
const struct cmd *cmd;
|
|
|
19e5f4 |
json_t *json;
|
|
|
19e5f4 |
};
|
|
|
19e5f4 |
|
|
|
19e5f4 |
-static struct json_cmd_assoc *json_cmd_list = NULL;
|
|
|
19e5f4 |
+#define CMD_ASSOC_HSIZE 512
|
|
|
19e5f4 |
+static struct hlist_head json_cmd_assoc_hash[CMD_ASSOC_HSIZE];
|
|
|
19e5f4 |
|
|
|
19e5f4 |
static void json_cmd_assoc_free(void)
|
|
|
19e5f4 |
{
|
|
|
19e5f4 |
struct json_cmd_assoc *cur;
|
|
|
19e5f4 |
+ struct hlist_node *pos, *n;
|
|
|
19e5f4 |
+ int i;
|
|
|
19e5f4 |
|
|
|
19e5f4 |
- while (json_cmd_list) {
|
|
|
19e5f4 |
- cur = json_cmd_list;
|
|
|
19e5f4 |
- json_cmd_list = cur->next;
|
|
|
19e5f4 |
- free(cur);
|
|
|
19e5f4 |
+ for (i = 0; i < CMD_ASSOC_HSIZE; i++) {
|
|
|
19e5f4 |
+ hlist_for_each_entry_safe(cur, pos, n,
|
|
|
19e5f4 |
+ &json_cmd_assoc_hash[i], hnode)
|
|
|
19e5f4 |
+ free(cur);
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
|
|
|
19e5f4 |
static void json_cmd_assoc_add(json_t *json, const struct cmd *cmd)
|
|
|
19e5f4 |
{
|
|
|
19e5f4 |
struct json_cmd_assoc *new = xzalloc(sizeof *new);
|
|
|
19e5f4 |
+ int key = cmd->seqnum % CMD_ASSOC_HSIZE;
|
|
|
19e5f4 |
|
|
|
19e5f4 |
- new->next = json_cmd_list;
|
|
|
19e5f4 |
new->json = json;
|
|
|
19e5f4 |
new->cmd = cmd;
|
|
|
19e5f4 |
- json_cmd_list = new;
|
|
|
19e5f4 |
+
|
|
|
19e5f4 |
+ hlist_add_head(&new->hnode, &json_cmd_assoc_hash[key]);
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
|
|
|
19e5f4 |
static json_t *seqnum_to_json(const uint32_t seqnum)
|
|
|
19e5f4 |
{
|
|
|
19e5f4 |
- const struct json_cmd_assoc *cur;
|
|
|
19e5f4 |
+ int key = seqnum % CMD_ASSOC_HSIZE;
|
|
|
19e5f4 |
+ struct json_cmd_assoc *cur;
|
|
|
19e5f4 |
+ struct hlist_node *n;
|
|
|
19e5f4 |
|
|
|
19e5f4 |
- for (cur = json_cmd_list; cur; cur = cur->next) {
|
|
|
19e5f4 |
+
|
|
|
19e5f4 |
+ hlist_for_each_entry(cur, n, &json_cmd_assoc_hash[key], hnode) {
|
|
|
19e5f4 |
if (cur->cmd->seqnum == seqnum)
|
|
|
19e5f4 |
return cur->json;
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
+
|
|
|
19e5f4 |
return NULL;
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
|
|
|
19e5f4 |
--
|
|
|
bfbb76 |
2.31.1
|
|
|
19e5f4 |
|