pespin has uploaded this change for review.

View Change

Introduce hashtable to look up session in endpoint by UP SEID

This is used every time a new PFCP session was being allocated.
It allows looking up if a given UP SEID exists in any of the peers.
Before this patch, iterating over tens/hundreds of UP peers on every
session creation took 38% of a full CPU.

Change-Id: I617b405e59a3435a1c4912bf4161bc9e036754b4
---
M include/osmocom/upf/up_endpoint.h
M include/osmocom/upf/up_session.h
M src/osmo-upf/up_endpoint.c
M src/osmo-upf/up_session.c
4 files changed, 14 insertions(+), 4 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-upf refs/changes/78/39578/1
diff --git a/include/osmocom/upf/up_endpoint.h b/include/osmocom/upf/up_endpoint.h
index ac240cd..2aed25a 100644
--- a/include/osmocom/upf/up_endpoint.h
+++ b/include/osmocom/upf/up_endpoint.h
@@ -24,6 +24,7 @@
#pragma once

#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/hashtable.h>

struct osmo_pfcp_msg;
struct osmo_pfcp_endpoint;
@@ -37,6 +38,10 @@

/* list of struct up_peer. */
struct llist_head peers;
+ /* hashtable of (struct up_session) with key up_seid.
+ * Allows quick access to sessions (and its endpoint as backpointer)
+ * with a given up_seid. */
+ DECLARE_HASHTABLE(sessions_by_up_seid, 10);

uint64_t next_up_seid_state;
};
diff --git a/include/osmocom/upf/up_session.h b/include/osmocom/upf/up_session.h
index 3dc7bb1..a20ae06 100644
--- a/include/osmocom/upf/up_session.h
+++ b/include/osmocom/upf/up_session.h
@@ -45,6 +45,9 @@
struct hlist_node node_by_up_seid;
struct hlist_node node_by_cp_seid;

+ /* item in up_endpoint->peers_by_up_seid: */
+ struct hlist_node ep_node_by_up_seid;
+
struct osmo_fsm_inst *fi;
/* backpointer */
struct up_peer *up_peer;
diff --git a/src/osmo-upf/up_endpoint.c b/src/osmo-upf/up_endpoint.c
index 34351a6..f400bdc 100644
--- a/src/osmo-upf/up_endpoint.c
+++ b/src/osmo-upf/up_endpoint.c
@@ -239,6 +239,7 @@
struct up_endpoint *up_ep;
up_ep = talloc_zero(ctx, struct up_endpoint);
INIT_LLIST_HEAD(&up_ep->peers);
+ hash_init(up_ep->sessions_by_up_seid);

cfg = (struct osmo_pfcp_endpoint_cfg){
.local_addr = *local_addr,
@@ -263,10 +264,9 @@

static struct up_session *up_endpoint_find_session(struct up_endpoint *ep, uint64_t up_seid)
{
- struct up_peer *peer;
- llist_for_each_entry(peer, &ep->peers, entry) {
- struct up_session *session = up_session_find_by_up_seid(peer, up_seid);
- if (session)
+ struct up_session *session;
+ hash_for_each_possible(ep->sessions_by_up_seid, session, ep_node_by_up_seid, up_seid) {
+ if (session->up_seid == up_seid)
return session;
}
return NULL;
diff --git a/src/osmo-upf/up_session.c b/src/osmo-upf/up_session.c
index 97c9367..a9bc7c3 100644
--- a/src/osmo-upf/up_session.c
+++ b/src/osmo-upf/up_session.c
@@ -885,6 +885,7 @@

up_session_clear_pdr_far(session);

+ hash_del(&session->ep_node_by_up_seid);
hash_del(&session->node_by_up_seid);
hash_del(&session->node_by_cp_seid);
}
@@ -1022,6 +1023,7 @@

hash_add(peer->sessions_by_up_seid, &session->node_by_up_seid, session->up_seid);
hash_add(peer->sessions_by_cp_seid, &session->node_by_cp_seid, session->cp_f_seid.seid);
+ hash_add(peer->up_endpoint->sessions_by_up_seid, &session->ep_node_by_up_seid, session->up_seid);
return session;
}


To view, visit change 39578. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-upf
Gerrit-Branch: master
Gerrit-Change-Id: I617b405e59a3435a1c4912bf4161bc9e036754b4
Gerrit-Change-Number: 39578
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>