pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-upf/+/39451?usp=email )

Change subject: Introduce hashtable to lookup session by F-TEID
......................................................................

Introduce hashtable to lookup session by F-TEID

This is a hot path when creating new sessions. Previous code would take
ages specially when UPF already had thousands of sessions created and a
new TEID to allocate was being looked up.

Related: SYS#6398
Change-Id: I90ecbb07b242c1de2298261019f24aa5f5810fda
---
M include/osmocom/upf/up_session.h
M include/osmocom/upf/upf.h
M src/osmo-upf/up_session.c
M src/osmo-upf/upf.c
4 files changed, 17 insertions(+), 23 deletions(-)

Approvals:
  fixeria: Looks good to me, but someone else must approve
  laforge: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved
  Jenkins Builder: Verified




diff --git a/include/osmocom/upf/up_session.h b/include/osmocom/upf/up_session.h
index c424df9..3dc7bb1 100644
--- a/include/osmocom/upf/up_session.h
+++ b/include/osmocom/upf/up_session.h
@@ -69,7 +69,6 @@
 struct up_session *up_session_find_or_add(struct up_peer *peer, const struct 
osmo_pfcp_ie_f_seid *cp_f_seid);
 struct up_session *up_session_find_by_up_seid(struct up_peer *peer, uint64_t 
up_seid);
 struct up_session *up_session_find_by_cp_f_seid(struct up_peer *peer, const 
struct osmo_pfcp_ie_f_seid *cp_f_seid);
-struct up_session *up_session_find_by_local_teid(struct up_peer *peer, 
uint32_t teid);

 void up_session_set_msg_ctx(struct up_session *session, struct osmo_pfcp_msg 
*m);

@@ -83,7 +82,8 @@
 char *up_session_to_str_c(void *ctx, struct up_session *session);

 struct pdr {
-       struct llist_head entry;
+       struct llist_head entry; /* item in session->pdrs */
+       struct hlist_node node_by_local_f_teid; /* item in 
g_upf->gtp.pdrs_by_local_f_teid */
        struct up_session *session;

        struct osmo_pfcp_ie_create_pdr desc;
diff --git a/include/osmocom/upf/upf.h b/include/osmocom/upf/upf.h
index d558600..0e5406f 100644
--- a/include/osmocom/upf/upf.h
+++ b/include/osmocom/upf/upf.h
@@ -28,6 +28,7 @@
 #include <osmocom/core/socket.h>
 #include <osmocom/core/select.h>
 #include <osmocom/core/linuxlist.h>
+#include <osmocom/core/hashtable.h>

 struct osmo_tdef;
 struct ctrl_handle;
@@ -118,6 +119,8 @@

        struct {
                uint32_t next_local_teid_state;
+               /* hashtable of (struct pdr)->node_by_local_f_teid: */
+               DECLARE_HASHTABLE(pdrs_by_local_f_teid, 10);
                uint16_t next_echo_seq_nr;
        } gtp;

diff --git a/src/osmo-upf/up_session.c b/src/osmo-upf/up_session.c
index 198bf88..359d116 100644
--- a/src/osmo-upf/up_session.c
+++ b/src/osmo-upf/up_session.c
@@ -379,6 +379,8 @@

 static void pdr_del(struct pdr *pdr)
 {
+       if (!hlist_unhashed(&pdr->node_by_local_f_teid))
+               hash_del(&pdr->node_by_local_f_teid);
        llist_del(&pdr->entry);
        talloc_free(pdr);
 }
@@ -411,6 +413,7 @@
                .session = session,
                .desc = *create_pdr,
        };
+       INIT_HLIST_NODE(&pdr->node_by_local_f_teid);
        llist_add_tail(&pdr->entry, &session->pdrs);

        if (pdr->desc.far_id_present) {
@@ -482,6 +485,7 @@
                        .local_f_teid_present = true,
                        .local_f_teid = *pdr->local_f_teid,
                };
+               hash_add(g_upf->gtp.pdrs_by_local_f_teid, 
&pdr->node_by_local_f_teid, pdr->local_f_teid->fixed.teid);
        } else {
                created_pdr[*created_pdr_count] = (struct 
osmo_pfcp_ie_created_pdr){
                        .pdr_id = pdr->desc.pdr_id,
@@ -1054,22 +1058,6 @@
        return NULL;
 }

-struct up_session *up_session_find_by_local_teid(struct up_peer *peer, 
uint32_t teid)
-{
-       struct up_session *session;
-       int bkt;
-       hash_for_each(peer->sessions_by_up_seid, bkt, session, node_by_up_seid) 
{
-               struct pdr *pdr;
-               llist_for_each_entry(pdr, &session->pdrs, entry) {
-                       if (!pdr->local_f_teid)
-                               continue;
-                       if (pdr->local_f_teid->fixed.teid == teid)
-                               return session;
-               }
-       }
-       return NULL;
-}
-
 static bool action_is_forw(const struct osmo_pfcp_ie_apply_action *aa)
 {
        return osmo_pfcp_bits_get(aa->bits, OSMO_PFCP_APPLY_ACTION_FORW)
diff --git a/src/osmo-upf/upf.c b/src/osmo-upf/upf.c
index a4cb79b..c82227d 100644
--- a/src/osmo-upf/upf.c
+++ b/src/osmo-upf/upf.c
@@ -78,6 +78,7 @@
        INIT_LLIST_HEAD(&g_upf->tunend.vty_cfg.devs);
        INIT_LLIST_HEAD(&g_upf->tunend.devs);
        INIT_LLIST_HEAD(&g_upf->netinst);
+       hash_init(g_upf->gtp.pdrs_by_local_f_teid);
 }

 int upf_pfcp_init(void)
@@ -135,11 +136,13 @@

 static bool upf_is_local_teid_in_use(uint32_t teid)
 {
-       struct up_peer *peer;
-       llist_for_each_entry(peer, &g_upf->pfcp.ep->peers, entry) {
-               struct up_session *session = 
up_session_find_by_local_teid(peer, teid);
-               if (session)
-                       return true;
+       struct pdr *pdr;
+       hash_for_each_possible(g_upf->gtp.pdrs_by_local_f_teid, pdr, 
node_by_local_f_teid, teid) {
+               if (!pdr->local_f_teid)
+                       continue;
+               if (pdr->local_f_teid->fixed.teid != teid)
+                       continue;
+               return true;
        }
        return false;
 }

--
To view, visit https://gerrit.osmocom.org/c/osmo-upf/+/39451?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: osmo-upf
Gerrit-Branch: master
Gerrit-Change-Id: I90ecbb07b242c1de2298261019f24aa5f5810fda
Gerrit-Change-Number: 39451
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>

Reply via email to