Commit f001e32c authored by Maria Matejka's avatar Maria Matejka
Browse files

Worker: Lock and queue optimization

parent 4a6b7b69
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -147,12 +147,14 @@ class BIRDWQStateLogPrinter(BIRDPrinter):
    typeTag = "worker_queue_state"

    def queueval(self):
        return "%(worker) 4d %(what)s: pending %(pending)s, running %(running)s, stop %(stop)s" % {
        return "%(worker) 4d %(what)s: running %(running)s, workers %(workers)s, max_workers %(max_workers)s, stop %(stop)s, pending %(pending)s" % {
                "worker": self.val['worker_id'],
                "what": str(self.val['what']),
                "pending": str(self.val['queue']['pending']),
                "running": str(self.val['queue']['running']),
                "workers": str(self.val['queue']['workers']),
                "max_workers": str(self.val['queue']['max_workers']),
                "stop": str(self.val['queue']['stop']),
                "pending": str(self.val['queue']['pending']),
                }

    def semval(self):
@@ -175,8 +177,26 @@ class BIRDWQStateLogPrinter(BIRDPrinter):
                "semname": semname
                }

    def lockstate(self):
        lock = self.val["domain"]["lock"]
        readers = lock & ((1 << 30) - 1)
        prepended = (lock >> 30) & ((1 << 30) - 1)
        waiting_writers = (lock >> 60) & 1 == 1
        waiting_readers = (lock >> 61) & 1 == 1
        writer_locked = (lock >> 62) & 1 == 1
        spinlock = (lock >> 63) & 1 == 1

        return "RDLOCK=%(rdlock)u PREP=%(prep)u%(ww)s%(wr)s%(wl)s%(spin)s" % {
                "rdlock": readers,
                "prep": prepended,
                "ww": " W+" if waiting_writers else "",
                "wr": " R+" if waiting_readers else "",
                "wl": " WL" if writer_locked else "",
                "spin": " SPIN" if spinlock else "",
                }

    def domval(self):
        return "%(worker) 4d %(what)s: %(task)s on %(domain)s: RP=%(rdtasks_n)u WP=%(wrtasks_n)u RS=%(rdsem_n)u WS=%(wrsem_n)u RL=%(rdlocked)u PREP=%(prepended)u" % {
        return "%(worker) 4d %(what)s: %(task)s on %(domain)s: RP=%(rdtasks_n)u WP=%(wrtasks_n)u RS=%(rdsem_n)u WS=%(wrsem_n)u %(lockstate)s" % {
                "worker": self.val['worker_id'],
                "what": str(self.val["what"]),
                "task": str(self.val["domain"]["task"]),
@@ -185,8 +205,7 @@ class BIRDWQStateLogPrinter(BIRDPrinter):
                "wrtasks_n": self.val["domain"]["wrtasks_n"],
                "rdsem_n": self.val["domain"]["rdsem_n"],
                "wrsem_n": self.val["domain"]["wrsem_n"],
                "rdlocked": self.val["domain"]["rdlocked"],
                "prepended": self.val["domain"]["prepended"],
                "lockstate": self.lockstate(),
                }

    def nothing(self):
@@ -256,6 +275,7 @@ class BIRDWQStateLogCommand(gdb.Command):
        statelog_size = gdb.lookup_symbol("STATELOG_SIZE")[0].value()
        statelog_pos = wq["statelog_pos"]

        print("offset", int(statelog_pos / statelog_size) * statelog_size)
        print("   idx  WID command")

        for i in range(total):
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ struct config {
  u32 watchdog_timeout;			/* Watchdog timeout (in seconds, 0 = disabled) */
  uint workers;				/* How many workers should run by default */
  uint max_workers;			/* How many workers should run at maximum */
  uint queue_size;			/* How many items can be in the global queue */
  char *err_msg;			/* Parser error message */
  int err_lino;				/* Line containing error */
  int err_chno;				/* Character where the parser stopped */
+17 −0
Original line number Diff line number Diff line
@@ -619,6 +619,23 @@ include "tablename.conf";;
	<cf/protocol/ times, and the <cf/iso long ms/ format for <cf/base/ and
	<cf/log/ times.

	<tag><label id="opt-worker">worker <m/number/ [ max <m/number/]</tag>
	Set number of workers to run BIRD. The first number states how many concurrent
	threads are allowed to run, plus one if you run BFD (it has its own thread).
	It's recommended to set this to at most the number of your CPU cores.
	By default, this is 4.

	The max number is a maximal number of threads allowed to exist (plus one for BFD).
	Setting this to a too low value may lead to deadlocks in the route propagation task chain.
	By default, this is 8; if this clause is omitted and the worker count
	is more than 4, this is twice the worker count.

	<tag><label id="opt-queue-size">queue size <m/number/</tag>
	Set how many tasks can wait in the task queue for workers. Higher value means
	more memory consumed with lesser thread switching overhead. Zero means no buffer
	at all. By default, this is 64 and you probably don't want to change it unless
	you are fine-tuning your route server performance.

	<tag><label id="opt-table"><m/nettype/ table <m/name/ [sorted]</tag>
	Create a new routing table. The default routing tables <cf/master4/ and
	<cf/master6/ are created implicitly, other routing tables have to be
+16 −0
Original line number Diff line number Diff line
@@ -170,3 +170,19 @@ list_length(list *l)

  return len;
}

/* Move all nodes from one list to another */
LIST_INLINE void
move_list(list *dest, list *src)
{
  dest->head = src->head;
  dest->null = NULL;
  dest->tail = src->tail;

  dest->head->prev = &dest->head_node;
  dest->tail->next = &dest->tail_node;

  src->head = &src->tail_node;
  src->null = NULL;
  src->tail = &src->head_node;
}
+1 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ typedef union list { /* In fact two overlayed nodes */
void add_tail(list *, node *);
void add_head(list *, node *);
void rem_node(node *);
void move_list(list *dest, list *src);
void add_tail_list(list *, list *);
void init_list(list *);
void insert_node(node *, node *);
Loading