session: improve use of session handles

First step towards moving to an 8 byte struct instead of u64.

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Idd0b95520ab7158e175b9af1702fc09c0613a4bb
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index 41a11b7..b89052f 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -159,8 +159,8 @@
   svm_fifo_t *ct_tx_fifo;
   vcl_session_msg_t *accept_evts_fifo;
 
-  u64 vpp_handle;
-  u64 parent_handle;
+  session_handle_t vpp_handle;
+  session_handle_t parent_handle;
   u32 listener_index;		/**< index of parent listener (if any) */
   int n_accepted_sessions;	/**< sessions accepted by this listener */
   vppcom_epoll_t vep;
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index a0bbae1..58f6ac0 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -1266,7 +1266,7 @@
 	session->vpp_handle);
   vcl_evt (VCL_EVT_UNBIND, session);
 
-  session->vpp_handle = ~0;
+  session->vpp_handle = SESSION_INVALID_HANDLE;
   session->session_state = VCL_STATE_DISCONNECT;
 
   return VPPCOM_OK;
@@ -1471,7 +1471,7 @@
 
   session->session_type = proto;
   session->session_state = VCL_STATE_CLOSED;
-  session->vpp_handle = ~0;
+  session->vpp_handle = SESSION_INVALID_HANDLE;
   session->is_dgram = vcl_proto_is_dgram (proto);
   session->vpp_error = SESSION_E_NONE;
 
@@ -2818,7 +2818,7 @@
   vep_session->vep.vep_sh = ~0;
   vep_session->vep.next_sh = ~0;
   vep_session->vep.prev_sh = ~0;
-  vep_session->vpp_handle = ~0;
+  vep_session->vpp_handle = SESSION_INVALID_HANDLE;
 
   vcl_evt (VCL_EVT_EPOLL_CREATE, vep_session, vep_session->session_index);
   VDBG (0, "Created vep_idx %u", vep_session->session_index);
diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h
index 4eee17e..f175e4a 100644
--- a/src/vnet/session/application_interface.h
+++ b/src/vnet/session/application_interface.h
@@ -126,7 +126,7 @@
   /*
    * Results
    */
-  u64 handle;
+  session_handle_t handle;
 } vnet_listen_args_t;
 
 typedef struct _vnet_unlisten_args_t
@@ -134,7 +134,7 @@
   union
   {
     char *uri;
-    u64 handle;			/**< Session handle */
+    session_handle_t handle; /**< Session handle */
   };
   u32 app_index;		/**< Owning application index */
   u32 wrk_map_index;		/**< App's local pool worker index */
@@ -356,7 +356,7 @@
 typedef struct session_bound_msg_
 {
   u32 context;
-  u64 handle;
+  session_handle_t handle;
   i32 retval;
   u8 lcl_is_ip4;
   u8 lcl_ip[16];
@@ -379,15 +379,15 @@
 typedef struct session_unlisten_reply_msg_
 {
   u32 context;
-  u64 handle;
+  session_handle_t handle;
   i32 retval;
 } __clib_packed session_unlisten_reply_msg_t;
 
 typedef struct session_accepted_msg_
 {
   u32 context;
-  u64 listener_handle;
-  u64 handle;
+  session_handle_t listener_handle;
+  session_handle_t handle;
   uword server_rx_fifo;
   uword server_tx_fifo;
   u64 segment_handle;
@@ -404,7 +404,7 @@
 {
   u32 context;
   i32 retval;
-  u64 handle;
+  session_handle_t handle;
 } __clib_packed session_accepted_reply_msg_t;
 
 typedef struct session_connect_msg_
@@ -444,7 +444,7 @@
 {
   u32 context;
   i32 retval;
-  u64 handle;
+  session_handle_t handle;
   uword server_rx_fifo;
   uword server_tx_fifo;
   u64 segment_handle;
@@ -474,33 +474,33 @@
 {
   u32 client_index;
   u32 context;
-  u64 handle;
+  session_handle_t handle;
 } __clib_packed session_disconnected_msg_t;
 
 typedef struct session_disconnected_reply_msg_
 {
   u32 context;
   i32 retval;
-  u64 handle;
+  session_handle_t handle;
 } __clib_packed session_disconnected_reply_msg_t;
 
 typedef struct session_reset_msg_
 {
   u32 client_index;
   u32 context;
-  u64 handle;
+  session_handle_t handle;
 } __clib_packed session_reset_msg_t;
 
 typedef struct session_reset_reply_msg_
 {
   u32 context;
   i32 retval;
-  u64 handle;
+  session_handle_t handle;
 } __clib_packed session_reset_reply_msg_t;
 
 typedef struct session_req_worker_update_msg_
 {
-  u64 session_handle;
+  session_handle_t session_handle;
 } __clib_packed session_req_worker_update_msg_t;
 
 /* NOTE: using u16 for wrk indices because message needs to fit in 18B */
@@ -509,12 +509,12 @@
   u32 client_index;
   u16 wrk_index;
   u16 req_wrk_index;
-  u64 handle;
+  session_handle_t handle;
 } __clib_packed session_worker_update_msg_t;
 
 typedef struct session_worker_update_reply_msg_
 {
-  u64 handle;
+  session_handle_t handle;
   uword rx_fifo;
   uword tx_fifo;
   u64 segment_handle;
diff --git a/src/vnet/session/application_worker.c b/src/vnet/session/application_worker.c
index c2d0d3b..befdb7c 100644
--- a/src/vnet/session/application_worker.c
+++ b/src/vnet/session/application_worker.c
@@ -58,10 +58,10 @@
 app_worker_free (app_worker_t * app_wrk)
 {
   application_t *app = application_get (app_wrk->app_index);
+  session_handle_t handle, *handles = 0, *sh;
   vnet_unlisten_args_t _a, *a = &_a;
-  u64 handle, *handles = 0, *sm_indices = 0;
   segment_manager_t *sm;
-  session_handle_t *sh;
+  u64 *sm_indices = 0;
   session_t *ls;
   u32 sm_index;
   int i;
@@ -853,7 +853,7 @@
 format_app_worker_listener (u8 * s, va_list * args)
 {
   app_worker_t *app_wrk = va_arg (*args, app_worker_t *);
-  u64 handle = va_arg (*args, u64);
+  session_handle_t handle = va_arg (*args, u64);
   u32 sm_index = va_arg (*args, u32);
   int verbose = va_arg (*args, int);
   session_t *listener;
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index 78158d5..f3337dd 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -392,44 +392,37 @@
 }
 
 always_inline session_t *
-session_get_from_handle (session_handle_t handle)
+session_get_from_handle (session_handle_tu_t handle)
 {
   session_main_t *smm = &session_main;
-  u32 session_index, thread_index;
-  session_parse_handle (handle, &session_index, &thread_index);
-  return pool_elt_at_index (smm->wrk[thread_index].sessions, session_index);
+  return pool_elt_at_index (smm->wrk[handle.thread_index].sessions,
+			    handle.session_index);
 }
 
 always_inline session_t *
-session_get_from_handle_if_valid (session_handle_t handle)
+session_get_from_handle_if_valid (session_handle_tu_t handle)
 {
-  u32 session_index, thread_index;
-  session_parse_handle (handle, &session_index, &thread_index);
-  return session_get_if_valid (session_index, thread_index);
+  return session_get_if_valid (handle.session_index, handle.thread_index);
 }
 
-u64 session_segment_handle (session_t * s);
-
 /**
  * Get session from handle and avoid pool validation if no same thread
  *
  * Peekers are fine because pool grows with barrier (see @ref session_alloc)
  */
 always_inline session_t *
-session_get_from_handle_safe (u64 handle)
+session_get_from_handle_safe (session_handle_tu_t handle)
 {
-  u32 thread_index = session_thread_from_handle (handle);
-  session_worker_t *wrk = &session_main.wrk[thread_index];
+  session_worker_t *wrk = &session_main.wrk[handle.thread_index];
 
-  if (thread_index == vlib_get_thread_index ())
+  if (handle.thread_index == vlib_get_thread_index ())
     {
-      return pool_elt_at_index (wrk->sessions,
-				session_index_from_handle (handle));
+      return pool_elt_at_index (wrk->sessions, handle.session_index);
     }
   else
     {
       /* Don't use pool_elt_at index to avoid pool bitmap reallocs */
-      return wrk->sessions + session_index_from_handle (handle);
+      return wrk->sessions + handle.session_index;
     }
 }
 
@@ -478,6 +471,7 @@
 			   u8 is_lcl);
 int session_transport_attribute (session_t *s, u8 is_get,
 				 transport_endpt_attr_t *attr);
+u64 session_segment_handle (session_t *s);
 
 u8 *format_session (u8 * s, va_list * args);
 uword unformat_session (unformat_input_t * input, va_list * args);
@@ -654,8 +648,8 @@
  * Listen sessions
  */
 
-always_inline u64
-listen_session_get_handle (session_t * s)
+always_inline session_handle_t
+listen_session_get_handle (session_t *s)
 {
   ASSERT (s->session_state == SESSION_STATE_LISTENING ||
 	  session_get_transport_proto (s) == TRANSPORT_PROTO_QUIC);
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index 0b9a5b4..0ec158f 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -491,15 +491,13 @@
   app_worker_t *app_wrk;
   session_t *s;
   application_t *app;
-  u32 index, thread_index;
 
   mp = (session_reset_reply_msg_t *) data;
   app = application_lookup (mp->context);
   if (!app)
     return;
 
-  session_parse_handle (mp->handle, &index, &thread_index);
-  s = session_get_if_valid (index, thread_index);
+  s = session_get_from_handle_if_valid (mp->handle);
 
   /* No session or not the right session */
   if (!s || s->session_state < SESSION_STATE_TRANSPORT_CLOSING)
diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h
index 8ec972d..ce115b2 100644
--- a/src/vnet/session/session_types.h
+++ b/src/vnet/session/session_types.h
@@ -25,6 +25,19 @@
 #define SESSION_CTRL_MSG_TX_MAX_SIZE 160
 #define SESSION_NODE_FRAME_SIZE 128
 
+typedef u8 session_type_t;
+typedef u64 session_handle_t;
+
+typedef union session_handle_tu_
+{
+  session_handle_t handle;
+  struct
+  {
+    u32 session_index;
+    u32 thread_index;
+  };
+} __attribute__ ((__transparent_union__)) session_handle_tu_t;
+
 #define foreach_session_endpoint_fields				\
   foreach_transport_endpoint_cfg_fields				\
   _(u8, transport_proto)					\
@@ -125,9 +138,6 @@
   return ip_is_zero (&sep->ip, sep->is_ip4);
 }
 
-typedef u8 session_type_t;
-typedef u64 session_handle_t;
-
 typedef enum
 {
   SESSION_CLEANUP_TRANSPORT,
@@ -198,21 +208,28 @@
   svm_fifo_t *rx_fifo;
   svm_fifo_t *tx_fifo;
 
+  union
+  {
+    session_handle_t handle;
+    struct
+    {
+      /** Index in thread pool where session was allocated */
+      u32 session_index;
+
+      /** Index of the thread that allocated the session */
+      u32 thread_index;
+    };
+  };
+
   /** Type built from transport and network protocol types */
   session_type_t session_type;
 
   /** State in session layer state machine. See @ref session_state_t */
   volatile u8 session_state;
 
-  /** Index in thread pool where session was allocated */
-  u32 session_index;
-
   /** Index of the app worker that owns the session */
   u32 app_wrk_index;
 
-  /** Index of the thread that allocated the session */
-  u8 thread_index;
-
   /** Session flags. See @ref session_flags_t */
   u32 flags;
 
@@ -299,45 +316,35 @@
 always_inline session_handle_t
 session_handle (session_t * s)
 {
-  return ((u64) s->thread_index << 32) | (u64) s->session_index;
+  return s->handle;
 }
 
 always_inline u32
-session_index_from_handle (session_handle_t handle)
+session_index_from_handle (session_handle_tu_t handle)
 {
-  return handle & 0xFFFFFFFF;
+  return handle.session_index;
 }
 
 always_inline u32
-session_thread_from_handle (session_handle_t handle)
+session_thread_from_handle (session_handle_tu_t handle)
 {
-  return handle >> 32;
+  return handle.thread_index;
 }
 
 always_inline void
-session_parse_handle (session_handle_t handle, u32 * index,
-		      u32 * thread_index)
+session_parse_handle (session_handle_tu_t handle, u32 *index,
+		      u32 *thread_index)
 {
-  *index = session_index_from_handle (handle);
-  *thread_index = session_thread_from_handle (handle);
+  *index = handle.session_index;
+  *thread_index = handle.thread_index;
 }
 
 static inline session_handle_t
 session_make_handle (u32 session_index, u32 data)
 {
-  return (((u64) data << 32) | (u64) session_index);
-}
-
-always_inline u32
-session_handle_index (session_handle_t ho_handle)
-{
-  return (ho_handle & 0xffffffff);
-}
-
-always_inline u32
-session_handle_data (session_handle_t ho_handle)
-{
-  return (ho_handle >> 32);
+  return ((session_handle_tu_t){ .session_index = session_index,
+				 .thread_index = data })
+    .handle;
 }
 
 typedef enum