#ifndef included_vlib_node_h
#define included_vlib_node_h
+#include <vppinfra/cpu.h>
#include <vppinfra/longjmp.h>
#include <vppinfra/timing_wheel.h>
#include <vlib/trace.h> /* for vlib_trace_filter_t */
} \
__VA_ARGS__ vlib_node_registration_t x
+#if CLIB_DEBUG > 0
+#define VLIB_NODE_FUNCTION_CLONE_TEMPLATE(arch, fn)
+#define VLIB_NODE_FUNCTION_MULTIARCH_CLONE(fn)
+#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn)
+#else
+#define VLIB_NODE_FUNCTION_CLONE_TEMPLATE(arch, fn, tgt) \
+ uword \
+ __attribute__ ((flatten)) \
+ __attribute__ ((target (tgt))) \
+ CLIB_CPU_OPTIMIZED \
+ fn ## _ ## arch ( struct vlib_main_t * vm, \
+ struct vlib_node_runtime_t * node, \
+ struct vlib_frame_t * frame) \
+ { return fn (vm, node, frame); }
+
+#define VLIB_NODE_FUNCTION_MULTIARCH_CLONE(fn) \
+ foreach_march_variant(VLIB_NODE_FUNCTION_CLONE_TEMPLATE, fn)
+
+#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn) \
+ VLIB_NODE_FUNCTION_MULTIARCH_CLONE(fn) \
+ CLIB_MULTIARCH_SELECT_FN(fn, static inline) \
+ static void __attribute__((__constructor__)) \
+ __vlib_node_function_multiarch_select_##node (void) \
+ { node.function = fn ## _multiarch_select(); }
+#endif
+
always_inline vlib_node_registration_t *
vlib_node_next_registered (vlib_node_registration_t * c)
{
/* Max number of vector elements to process at once per node. */
#define VLIB_FRAME_SIZE 256
+#define VLIB_FRAME_ALIGN VLIB_MAX_CPUS
/* Calling frame (think stack frame) for a node. */
typedef struct vlib_frame_t {
/* When suspending saves cpu cycle counter when process is to be resumed. */
u64 resume_cpu_time;
+ /* Default output function and its argument for any CLI outputs
+ within the process. */
+ vlib_cli_output_function_t *output_function;
+ uword output_function_arg;
+
#ifdef CLIB_UNIX
/* Pad to a multiple of the page size so we can mprotect process stacks */
- CLIB_PAD_FROM_TO (0x140, 0x1000);
+#define PAGE_SIZE_MULTIPLE 0x1000
+#define ALIGN_ON_MULTIPLE_PAGE_BOUNDARY_FOR_MPROTECT __attribute__ ((aligned (PAGE_SIZE_MULTIPLE)))
+#else
+#define ALIGN_ON_MULTIPLE_PAGE_BOUNDARY_FOR_MPROTECT
#endif
+
/* Process stack. Starts here and extends 2^log2_n_stack_bytes
bytes. */
#define VLIB_PROCESS_STACK_MAGIC (0xdead7ead)
- u32 stack[0];
+ u32 stack[0] ALIGN_ON_MULTIPLE_PAGE_BOUNDARY_FOR_MPROTECT;
} vlib_process_t __attribute__ ((aligned (CLIB_CACHE_LINE_BYTES)));
+#ifdef CLIB_UNIX
+ /* Ensure that the stack is aligned on the multiple of the page size */
+typedef char assert_process_stack_must_be_aligned_exactly_to_page_size_multiple
+ [(sizeof(vlib_process_t) - PAGE_SIZE_MULTIPLE) == 0 ? 0 : -1];
+#endif
+
typedef struct {
u32 node_index;