pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-upf/+/39568?usp=email )
Change subject: Introduce hashtable to look up gtp_tundev by local TEID ......................................................................
Introduce hashtable to look up gtp_tundev by local TEID
Use this hashtable while looking up for tunend based on <access.local.teid, access.remote.teid, access.remote.addr>. This kind of look up is used every time a session is added or removed, which means potentially thousands of tunend sessions were being iterated linerarly every time.
For simplification (easier/quicker hashtable key generation), reduce the whole key presented above to a more general one based on "access.local.teid". This is usually enough since we are anyways allocating local TEIDs globally per tunnel without caring about remote address.
Change-Id: Ib12ecc8ce87175071c52c0ed2217a29d901f0f05 --- M include/osmocom/upf/upf_gtp.h M src/osmo-upf/upf_gtp.c 2 files changed, 10 insertions(+), 2 deletions(-)
Approvals: fixeria: Looks good to me, approved laforge: Looks good to me, but someone else must approve osmith: Looks good to me, but someone else must approve Jenkins Builder: Verified
diff --git a/include/osmocom/upf/upf_gtp.h b/include/osmocom/upf/upf_gtp.h index b4cd3df..1162861 100644 --- a/include/osmocom/upf/upf_gtp.h +++ b/include/osmocom/upf/upf_gtp.h @@ -24,6 +24,7 @@ #pragma once
#include <osmocom/core/linuxlist.h> +#include <osmocom/core/hashtable.h> #include <osmocom/core/select.h> #include <osmocom/core/logging.h>
@@ -55,6 +56,8 @@
/* list of struct upf_gtp_tunend */ struct llist_head tunnels; + /* hashtable of (struct upf_gtp_tunen) with key desc.access.local.teid */ + DECLARE_HASHTABLE(tunnels_by_local_f_teid, 10); };
/* Description of a GTP encapsulation / decapsulation. diff --git a/src/osmo-upf/upf_gtp.c b/src/osmo-upf/upf_gtp.c index 528937b..4cbebcd 100644 --- a/src/osmo-upf/upf_gtp.c +++ b/src/osmo-upf/upf_gtp.c @@ -134,6 +134,7 @@ .gtpv1.ofd.fd = -1, }; INIT_LLIST_HEAD(&dev->tunnels); + hash_init(dev->tunnels_by_local_f_teid);
osmo_sockaddr_str_from_str(&addr_conv, local_addr, PORT_GTP0_U);
@@ -318,7 +319,8 @@ }
struct upf_gtp_tunend { - struct llist_head entry; + struct llist_head entry; /* item in (struct upf_gtp_dev)->tunnels */ + struct hlist_node node_by_local_f_teid; /* item in g_upf->gtp.pdrs_by_local_f_teid */
struct upf_gtp_dev *dev; struct upf_tunend desc; @@ -349,6 +351,7 @@ { if (tun->active) upf_gtp_tunend_deactivate(tun); + hash_del(&tun->node_by_local_f_teid); llist_del(&tun->entry); return 0; } @@ -369,6 +372,7 @@ .dev = dev, .desc = *desc, }; + hash_add(dev->tunnels_by_local_f_teid, &tun->node_by_local_f_teid, tun->desc.access.local.teid); llist_add(&tun->entry, &dev->tunnels); talloc_set_destructor(tun, upf_gtp_tunend_destruct); return tun; @@ -425,7 +429,8 @@ { struct upf_gtp_tunend *tun; tunend_validate(tunend); - llist_for_each_entry(tun, &dev->tunnels, entry) { + + hash_for_each_possible(dev->tunnels_by_local_f_teid, tun, node_by_local_f_teid, tunend->access.local.teid) { if (upf_gtp_tunend_cmp(tunend, &tun->desc)) continue; return tun;