vpp_lite: add cpu pinning support (VPP-467)
[vpp.git] / vlib / vlib / threads_cli.c
index 919baac..631fe0c 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define _GNU_SOURCE
 
 #include <vppinfra/format.h>
 #include <vlib/vlib.h>
 
 #include <vlib/threads.h>
+#include <vlib/unix/unix.h>
+
+static u8 *
+format_sched_policy_and_priority (u8 * s, va_list * args)
+{
+  long i = va_arg (*args, long);
+  struct sched_param sched_param;
+  u8 *t = 0;
+
+  switch (sched_getscheduler (i))
+    {
+#define _(v,f,str) case SCHED_POLICY_##f: t = (u8 *) str; break;
+      foreach_sched_policy
+#undef _
+    }
+  if (sched_getparam (i, &sched_param) == 0)
+    return format (s, "%s (%d)", t, sched_param.sched_priority);
+  else
+    return format (s, "%s (n/a)", t);
+}
 
 static clib_error_t *
 show_threads_fn (vlib_main_t * vm,
@@ -25,8 +46,8 @@ show_threads_fn (vlib_main_t * vm,
   vlib_worker_thread_t *w;
   int i;
 
-  vlib_cli_output (vm, "%-7s%-20s%-12s%-8s%-7s%-7s%-7s%-10s",
-                  "ID", "Name", "Type", "LWP",
+  vlib_cli_output (vm, "%-7s%-20s%-12s%-8s%-25s%-7s%-7s%-7s%-10s",
+                  "ID", "Name", "Type", "LWP", "Sched Policy (Priority)",
                   "lcore", "Core", "Socket", "State");
 
 #if !defined(__powerpc64__)
@@ -40,15 +61,54 @@ show_threads_fn (vlib_main_t * vm,
                     w->name ? w->name : (u8 *) "",
                     w->registration ? w->registration->name : "", w->lwp);
 
-#if DPDK==1
-      int lcore = w->dpdk_lcore_id;
-      if (lcore > -1)
+      line = format (line, "%-25U", format_sched_policy_and_priority, w->lwp);
+
+      int lcore = -1;
+      cpu_set_t cpuset;
+      CPU_ZERO (&cpuset);
+      int ret = -1;
+
+      ret =
+       pthread_getaffinity_np (w->thread_id, sizeof (cpu_set_t), &cpuset);
+      if (!ret)
+       {
+         int c;
+         for (c = 0; c < CPU_SETSIZE; c++)
+           if (CPU_ISSET (c, &cpuset))
+             {
+               if (lcore > -1)
+                 {
+                   lcore = -2;
+                   break;
+                 }
+               lcore = c;
+             }
+       }
+      else
        {
-         line = format (line, "%-7u%-7u%-7u",
-                        lcore,
-                        lcore_config[lcore].core_id,
-                        lcore_config[lcore].socket_id);
+         lcore = w->lcore_id;
+       }
 
+      if (lcore > -1)
+       {
+         const char *sys_cpu_path = "/sys/devices/system/cpu/cpu";
+         int socket_id = -1;
+         int core_id = -1;
+         u8 *p = 0;
+
+         p = format (p, "%s%u/topology/core_id%c", sys_cpu_path, lcore, 0);
+         vlib_sysfs_read ((char *) p, "%d", &core_id);
+
+         vec_reset_length (p);
+         p =
+           format (p,
+                   "%s%u/topology/physical_package_id%c",
+                   sys_cpu_path, lcore, 0);
+         vlib_sysfs_read ((char *) p, "%d", &socket_id);
+         vec_free (p);
+
+         line = format (line, "%-7u%-7u%-7u%", lcore, core_id, socket_id);
+#if DPDK==1
          switch (lcore_config[lcore].state)
            {
            case WAIT:
@@ -63,8 +123,15 @@ show_threads_fn (vlib_main_t * vm,
            default:
              line = format (line, "unknown");
            }
-       }
 #endif
+       }
+      else
+       {
+         line =
+           format (line, "%-7s%-7s%-7s%", (lcore == -2) ? "M" : "n/a", "n/a",
+                   "n/a");
+       }
+
       vlib_cli_output (vm, "%v", line);
       vec_free (line);
     }
@@ -321,8 +388,8 @@ test_frame_queue_nelts (vlib_main_t * vm, unformat_input_t * input,
   u32 fqix;
   u32 nelts = 0;
 
-  unformat (input, "%d", &nelts);
-  if ((nelts != 4) && (nelts != 8) && (nelts != 16) && (nelts != 32))
+  if ((unformat (input, "%d", &nelts) != 1) ||
+      ((nelts != 4) && (nelts != 8) && (nelts != 16) && (nelts != 32)))
     {
       return clib_error_return (0, "expecting 4,8,16,32");
     }