Commit 2c137591 authored by Maria Matejka's avatar Maria Matejka
Browse files

Reducing filter stack size to allow for lesser thread stack size

parent ceef6de4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ struct config {
  u32 proto_default_debug;		/* Default protocol debug mask */
  u32 proto_default_mrtdump;		/* Default protocol mrtdump mask */
  u32 channel_default_debug;		/* Default channel debug mask */
  u16 filter_vstk, filter_estk;		/* Filter stack depth */
  struct timeformat tf_route;		/* Time format for 'show route' */
  struct timeformat tf_proto;		/* Time format for 'show protocol' */
  struct timeformat tf_log;		/* Time format for the logfile */
+7 −1
Original line number Diff line number Diff line
@@ -288,7 +288,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
	PREPEND, FIRST, LAST, LAST_NONAGGREGATED, MATCH,
	EMPTY,
	FILTER, WHERE, EVAL, ATTRIBUTE,
	BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT)
	BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT, STACKS)

%nonassoc THEN
%nonassoc ELSE
@@ -312,6 +312,12 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,

CF_GRAMMAR

conf: FILTER STACKS expr expr ';' {
  new_config->filter_vstk = $3;
  new_config->filter_estk = $4;
 }
 ;

conf: filter_def ;
filter_def:
   FILTER symbol { $2 = cf_define_symbol($2, SYM_FILTER, filter, NULL); cf_push_scope( $2 ); }
+2 −1
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ FID_INTERPRET_BODY()')
#	that was needed in the former implementation.
m4_define(LINEX, `FID_INTERPRET_EXEC()LINEX_($1)FID_INTERPRET_NEW()return $1 FID_INTERPRET_BODY()')
m4_define(LINEX_, `do {
  if (fstk->ecnt + 1 >= fstk->elen) runtime("Filter execution stack overflow");
  fstk->estk[fstk->ecnt].pos = 0;
  fstk->estk[fstk->ecnt].line = $1;
  fstk->estk[fstk->ecnt].ventry = fstk->vcnt;
@@ -232,7 +233,7 @@ FID_INTERPRET_BODY()')
#	state the result and put it to the right place.
m4_define(RESULT, `RESULT_TYPE([[$1]]) RESULT_([[$1]],[[$2]],[[$3]])')
m4_define(RESULT_, `RESULT_VAL([[ (struct f_val) { .type = $1, .val.$2 = $3 } ]])')
m4_define(RESULT_VAL, `FID_HIC(, [[do { res = $1; fstk->vcnt++; } while (0)]],
m4_define(RESULT_VAL, `FID_HIC(, [[do { res = $1; f_vcnt_check_overflow(1); fstk->vcnt++; } while (0)]],
[[return fi_constant(what, $1)]])')
m4_define(RESULT_VOID, `RESULT_VAL([[ (struct f_val) { .type = T_VOID } ]])')

+1 −0
Original line number Diff line number Diff line
@@ -1003,6 +1003,7 @@
    curline.vbase = curline.ventry;

    /* Storage for local variables */
    f_vcnt_check_overflow(sym->function->vars);
    memset(&(fstk->vstk[fstk->vcnt]), 0, sizeof(struct f_val) * sym->function->vars);
    fstk->vcnt += sym->function->vars;
  }
+36 −27
Original line number Diff line number Diff line
@@ -50,30 +50,28 @@ enum f_exception {
  FE_RETURN = 0x1,
};


struct filter_stack {
  /* Value stack for execution */
#define F_VAL_STACK_MAX	4096
  uint vcnt;				/* Current value stack size; 0 for empty */
  uint ecnt;				/* Current execute stack size; 0 for empty */

  struct f_val vstk[F_VAL_STACK_MAX];	/* The stack itself */

  /* Instruction stack for execution */
#define F_EXEC_STACK_MAX 4096
  struct {
struct filter_exec_stack {
  const struct f_line *line;		/* The line that is being executed */
  uint pos;				/* Instruction index in the line */
  uint ventry;				/* Value stack depth on entry */
  uint vbase;				/* Where to index variable positions from */
  enum f_exception emask;		/* Exception mask */
  } estk[F_EXEC_STACK_MAX];
};

/* Internal filter state, to be allocated on stack when executing filters */
struct filter_state {
  /* Stacks needed for execution */
  struct filter_stack *stack;
  struct filter_stack {
    /* Current filter stack depth */

    /* Value stack */
    uint vcnt, vlen;
    struct f_val *vstk;

    /* Instruction stack for execution */
    uint ecnt, elen;
    struct filter_exec_stack *estk;
  } stack;

  /* The route we are processing. This may be NULL to indicate no route available. */
  struct rte **rte;
@@ -95,10 +93,13 @@ struct filter_state {
};

_Thread_local static struct filter_state filter_state;
_Thread_local static struct filter_stack filter_stack;

void (*bt_assert_hook)(int result, const struct f_line_item *assert);

#define _f_stack_init(fs, px, def) ((fs).stack.px##stk = alloca(sizeof(*(fs).stack.px##stk) * ((fs).stack.px##len = (config && config->filter_##px##stk) ? config->filter_##px##stk : (def))))

#define f_stack_init(fs) ( _f_stack_init(fs, v, 128), _f_stack_init(fs, e, 128) )

static inline void f_cache_eattrs(struct filter_state *fs)
{
  fs->eattrs = &((*fs->rte)->attrs->eattrs);
@@ -163,15 +164,17 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val)
  ASSERT(line->args == 0);

  /* Initialize the filter stack */
  struct filter_stack *fstk = fs->stack;
  struct filter_stack *fstk = &fs->stack;

  fstk->vcnt = line->vars;
  memset(fstk->vstk, 0, sizeof(struct f_val) * line->vars);

  /* The same as with the value stack. Not resetting the stack for performance reasons. */
  fstk->ecnt = 1;
  fstk->estk[0].line = line;
  fstk->estk[0].pos = 0;
  fstk->estk[0] = (struct filter_exec_stack) {
    .line = line,
    .pos = 0,
  };

#define curline fstk->estk[fstk->ecnt-1]

@@ -191,6 +194,8 @@ interpret(struct filter_state *fs, const struct f_line *line, struct f_val *val)
#define v2 vv(1)
#define v3 vv(2)

#define f_vcnt_check_overflow(n) do { if (fstk->vcnt + n >= fstk->vlen) runtime("Filter execution stack overflow"); } while (0)

#define runtime(fmt, ...) do { \
  if (!(fs->flags & FF_SILENT)) \
    log_rl(&rl_runtime_err, L_ERR "filters, line %d: " fmt, what->lineno, ##__VA_ARGS__); \
@@ -276,12 +281,13 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i

  /* Initialize the filter state */
  filter_state = (struct filter_state) {
    .stack = &filter_stack,
    .rte = rte,
    .pool = tmp_pool,
    .flags = flags,
  };

  f_stack_init(filter_state);

  LOG_BUFFER_INIT(filter_state.buf);

  /* Run the interpreter itself */
@@ -340,11 +346,12 @@ enum filter_return
f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool)
{
  filter_state = (struct filter_state) {
    .stack = &filter_stack,
    .rte = rte,
    .pool = tmp_pool,
  };

  f_stack_init(filter_state);

  LOG_BUFFER_INIT(filter_state.buf);

  ASSERT(!((*rte)->flags & REF_COW));
@@ -363,10 +370,11 @@ enum filter_return
f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
{
  filter_state = (struct filter_state) {
    .stack = &filter_stack,
    .pool = tmp_pool,
  };

  f_stack_init(filter_state);

  LOG_BUFFER_INIT(filter_state.buf);

  enum filter_return fret = interpret(&filter_state, expr, pres);
@@ -383,10 +391,11 @@ f_eval_int(const struct f_line *expr)
{
  /* Called independently in parse-time to eval expressions */
  filter_state = (struct filter_state) {
    .stack = &filter_stack,
    .pool = cfg_mem,
  };

  f_stack_init(filter_state);

  struct f_val val;

  LOG_BUFFER_INIT(filter_state.buf);
Loading