laforge has submitted this change. ( https://gerrit.osmocom.org/c/upf-benchmark/+/39576?usp=email )
Change subject: osmo-upf-load-gen: Introduce hashtable to look up session by CP SEID ......................................................................
osmo-upf-load-gen: Introduce hashtable to look up session by CP SEID
When adding tens of thousands of tunend sessions, osmo-upf-load-gen used 100% CPU and 90% of it was spent in pfcp_tool_session_find().
Change-Id: Icab511fa1c136c75403e7469f63d91004e75dab4 --- M include/osmocom/upfloadgen/pfcp_tool.h M src/osmo-upf-load-gen/pfcp_tool.c 2 files changed, 8 insertions(+), 1 deletion(-)
Approvals: laforge: Looks good to me, approved osmith: Looks good to me, but someone else must approve Jenkins Builder: Verified
diff --git a/include/osmocom/upfloadgen/pfcp_tool.h b/include/osmocom/upfloadgen/pfcp_tool.h index 28be674..26cd639 100644 --- a/include/osmocom/upfloadgen/pfcp_tool.h +++ b/include/osmocom/upfloadgen/pfcp_tool.h @@ -25,6 +25,7 @@ #pragma once
#include <osmocom/core/linuxlist.h> +#include <osmocom/core/hashtable.h> #include <osmocom/core/tdef.h> #include <osmocom/core/socket.h> #include <osmocom/core/sockaddr_str.h> @@ -63,7 +64,10 @@
uint64_t next_seid_state;
+ /* llist of struct pfcp_tool_session->entry */ struct llist_head sessions; + /* hashtable of (struct pfcp_tool_session) with key cp_seid */ + DECLARE_HASHTABLE(sessions_by_cp_seid, 10); };
struct pfcp_tool_gtp_tun_ep { @@ -90,6 +94,7 @@
struct pfcp_tool_session { struct llist_head entry; + struct hlist_node node_by_cp_seid; /* item in (struct pfcp_tool_peer)->sessions_by_cp_seid */
struct pfcp_tool_peer *peer; uint64_t cp_seid; diff --git a/src/osmo-upf-load-gen/pfcp_tool.c b/src/osmo-upf-load-gen/pfcp_tool.c index f07acf0..38dc2cd 100644 --- a/src/osmo-upf-load-gen/pfcp_tool.c +++ b/src/osmo-upf-load-gen/pfcp_tool.c @@ -91,6 +91,7 @@ peer->remote_addr = *remote_addr; peer->next_seid_state = 0x1234567; INIT_LLIST_HEAD(&peer->sessions); + hash_init(peer->sessions_by_cp_seid); llist_add(&peer->entry, &g_pfcp_tool->peers); return peer; } @@ -98,7 +99,7 @@ struct pfcp_tool_session *pfcp_tool_session_find(struct pfcp_tool_peer *peer, uint64_t cp_seid) { struct pfcp_tool_session *session; - llist_for_each_entry(session, &peer->sessions, entry) { + hash_for_each_possible(peer->sessions_by_cp_seid, session, node_by_cp_seid, cp_seid) { if (session->cp_seid == cp_seid) return session; } @@ -119,6 +120,7 @@ .kind = kind, }; llist_add(&session->entry, &peer->sessions); + hash_add(peer->sessions_by_cp_seid, &session->node_by_cp_seid, cp_seid); return session; }