]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Perf: export mode for measuring feed time
authorJan Maria Matejka <mq@ucw.cz>
Thu, 1 Nov 2018 13:16:04 +0000 (14:16 +0100)
committerJan Maria Matejka <mq@ucw.cz>
Mon, 17 Dec 2018 14:16:41 +0000 (15:16 +0100)
doc/bird.sgml
proto/perf/config.Y
proto/perf/perf.c
proto/perf/perf.h

index 0d8d6b154b9139f4f7e33aeb1511c5a35800f0bd..2926c55681f1b3fd18bab7a19f1caa7db1269170 100644 (file)
@@ -3758,21 +3758,27 @@ protocol ospf MyOSPF {
 <p>The Perf protocol is a generator of fake routes together with a time measurement
 framework. Its purpose is to check BIRD performance and to benchmark filters.
 
-<p>This protocol runs in several steps. In each step, it generates 2^x routes,
+<p>Import mode of this protocol runs in several steps. In each step, it generates 2^x routes,
 imports them into the appropriate table and withdraws them. The exponent x is configurable.
 It runs the benchmark several times for the same x, then it increases x by one
 until it gets too high, then it stops.
 
+<p>Export mode of this protocol repeats route refresh from table and measures how long it takes.
+
 <p>Output data is logged on info level. There is a Perl script <cf>proto/perf/parse.pl</cf>
 which may be handy to parse the data and draw some plots.
 
 <p>Implementation of this protocol is experimental. Use with caution and do not keep
-any instance of Perf in production configs.
+any instance of Perf in production configs for long time. The config interface is also unstable
+and may change in future versions without warning.
 
 <sect1>Configuration
 <label id="perf-config">
 
 <p><descrip>
+       <tag><label id="perf-mode">mode import|export</tag>
+       Set perf mode. Default: import
+
        <tag><label id="perf-repeat">repeat <m/number/</tag>
        Run this amount of iterations of the benchmark for every amount step. Default: 4
 
index 52f509a65ab20f5d0b9dc7852fcdd75d77b14514..617b223360ce664b725f7c38a2151eabd3c7909c 100644 (file)
@@ -17,7 +17,7 @@ CF_DEFINES
 
 CF_DECLS
 
-CF_KEYWORDS(PERF, EXP, FROM, TO, REPEAT, THRESHOLD, MIN, MAX, KEEP)
+CF_KEYWORDS(PERF, EXP, FROM, TO, REPEAT, THRESHOLD, MIN, MAX, KEEP, MODE, IMPORT, EXPORT)
 
 CF_GRAMMAR
 
@@ -32,6 +32,7 @@ perf_proto_start: proto_start PERF
   PERF_CFG->threshold_max = 500 MS_;
   PERF_CFG->threshold_min = 1 MS_;
   PERF_CFG->keep = 0;
+  PERF_CFG->mode = PERF_MODE_IMPORT;
 };
 
 perf_proto:
@@ -47,6 +48,8 @@ perf_proto_item:
  | THRESHOLD MIN expr_us { PERF_CFG->threshold_min = $3; }
  | THRESHOLD MAX expr_us { PERF_CFG->threshold_max = $3; }
  | KEEP bool { PERF_CFG->keep = $2; }
+ | MODE IMPORT { PERF_CFG->mode = PERF_MODE_IMPORT; }
+ | MODE EXPORT { PERF_CFG->mode = PERF_MODE_EXPORT; }
 ;
 
 
index 733eeb880cb821698db73405bea42b781b9c2923..97fd8340201b75e6fecc14860c0ac87c52495b23 100644 (file)
@@ -209,13 +209,49 @@ perf_loop(void *data)
   ev_schedule(p->loop);
 }
 
+static void
+perf_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net UNUSED, struct rte *new UNUSED, struct rte *old UNUSED)
+{
+  struct perf_proto *p = (struct perf_proto *) P;
+  p->exp++;
+  return;
+}
+
+static void
+perf_feed_begin(struct channel *c, int initial UNUSED)
+{
+  struct perf_proto *p = (struct perf_proto *) c->proto;
+
+  p->run++;
+  p->data = xmalloc(sizeof(struct timespec));
+  p->exp = 0;
+
+  clock_gettime(CLOCK_MONOTONIC, p->data);
+}
+
+static void
+perf_feed_end(struct channel *c)
+{
+  struct perf_proto *p = (struct perf_proto *) c->proto;
+  struct timespec ts_end;
+  clock_gettime(CLOCK_MONOTONIC, &ts_end);
+
+  s64 feedtime = timediff(p->data, &ts_end);
+
+  PLOG("feed n=%lu time=%lu", p->exp, feedtime);
+
+  if (p->run < p->repeat)
+    channel_request_feeding(c);
+  else
+    PLOG("feed done");
+}
+
 static struct proto *
 perf_init(struct proto_config *CF)
 {
   struct proto *P = proto_new(CF);
 
   P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF));
-  P->ifa_notify = perf_ifa_notify;
 
   struct perf_proto *p = (struct perf_proto *) P;
 
@@ -229,6 +265,18 @@ perf_init(struct proto_config *CF)
   p->to = cf->to;
   p->repeat = cf->repeat;
   p->keep = cf->keep;
+  p->mode = cf->mode;
+
+  switch (p->mode) {
+    case PERF_MODE_IMPORT:
+      P->ifa_notify = perf_ifa_notify;
+      break;
+    case PERF_MODE_EXPORT:
+      P->rt_notify = perf_rt_notify;
+      P->feed_begin = perf_feed_begin;
+      P->feed_end = perf_feed_end;
+      break;
+  }
 
   return P;
 }
index f31becddc49cb0c401703946dc8e838bc465f5ca..301c6110b481cd16a18d5164c07fbf6cb13467fd 100644 (file)
@@ -9,6 +9,11 @@
 #ifndef _BIRD_PERF_H_
 #define _BIRD_PERF_H_
 
+enum perf_mode {
+  PERF_MODE_IMPORT,
+  PERF_MODE_EXPORT,
+};
+
 struct perf_config {
   struct proto_config p;
   btime threshold_min;
@@ -17,6 +22,7 @@ struct perf_config {
   uint to;
   uint repeat;
   uint keep;
+  enum perf_mode mode;
 };
 
 struct perf_proto {
@@ -33,6 +39,7 @@ struct perf_proto {
   uint exp;
   uint stop;
   uint keep;
+  enum perf_mode mode;
 };
 
 #endif