hsa: fix echo client workers initialization

We were creating an additional worker not backed by any VPP threads,
leading off-by-1 access in the session main workers vector.
Also uses vec_elt_at_index() when accessing session main workers vector
elements to catch those errors more easily.

Type: fix

Change-Id: I6059116b7b64ae6b26ad83c1fcf55df8522868ad
Signed-off-by: Benoît Ganne <bganne@cisco.com>
diff --git a/src/plugins/hs_apps/echo_client.c b/src/plugins/hs_apps/echo_client.c
index 14d47be..9881cf4 100644
--- a/src/plugins/hs_apps/echo_client.c
+++ b/src/plugins/hs_apps/echo_client.c
@@ -373,7 +373,6 @@
 ec_init (vlib_main_t *vm)
 {
   ec_main_t *ecm = &ec_main;
-  vlib_thread_main_t *vtm = vlib_get_thread_main ();
   ec_worker_t *wrk;
   u32 num_threads;
   int i;
@@ -414,8 +413,8 @@
   for (i = 0; i < vec_len (ecm->connect_test_data); i++)
     ecm->connect_test_data[i] = i & 0xff;
 
-  num_threads = 1 /* main thread */ + vtm->n_threads;
-  vec_validate (ecm->wrk, num_threads);
+  num_threads = 1 /* main thread */ + vlib_num_workers ();
+  vec_validate (ecm->wrk, num_threads - 1);
   vec_foreach (wrk, ecm->wrk)
     {
       vec_validate (wrk->rx_buf, vec_len (ecm->connect_test_data) - 1);
@@ -431,8 +430,8 @@
   vlib_worker_thread_barrier_release (vm);
 
   /* Turn on the builtin client input nodes */
-  for (i = 0; i < vtm->n_vlib_mains; i++)
-    vlib_node_set_state (vlib_get_main_by_index (i), echo_clients_node.index,
+  foreach_vlib_main ()
+    vlib_node_set_state (this_vlib_main, echo_clients_node.index,
 			 VLIB_NODE_STATE_POLLING);
 
   return 0;
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index b8cc1c3..ab92295 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -709,7 +709,7 @@
 always_inline session_worker_t *
 session_main_get_worker (u32 thread_index)
 {
-  return &session_main.wrk[thread_index];
+  return vec_elt_at_index (session_main.wrk, thread_index);
 }
 
 static inline session_worker_t *
@@ -717,13 +717,13 @@
 {
   if (thread_index > vec_len (session_main.wrk))
     return 0;
-  return &session_main.wrk[thread_index];
+  return session_main_get_worker (thread_index);
 }
 
 always_inline svm_msg_q_t *
 session_main_get_vpp_event_queue (u32 thread_index)
 {
-  return session_main.wrk[thread_index].vpp_event_queue;
+  return session_main_get_worker (thread_index)->vpp_event_queue;
 }
 
 always_inline u8