Skip to content

Commit

Permalink
main: add --poll-mode option
Browse files Browse the repository at this point in the history
Add command line flag to disable automatic and adaptive micro sleep
based on link speed and RX queue size.

Signed-off-by: Robin Jarry <[email protected]>
  • Loading branch information
rjarry committed Apr 17, 2024
1 parent 712cf23 commit 4ff2344
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^".*'
Priority: -1
- Regex: '^<(br_|br/)'
- Regex: '^<(br_|br\.)'
Priority: 100
- Regex: '^<(rte_|event|ecoli|stb_|numa.h)'
Priority: 500
Expand Down
8 changes: 4 additions & 4 deletions main/br.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
#ifndef _BR
#define _BR

#include <event2/event.h>

#include <sched.h>
#include <stdbool.h>

struct boring_router {
struct br_args {
const char *api_sock_path;
unsigned log_level;
bool test_mode;
bool poll_mode;
};

const struct br_args *br_args(void);

#endif
8 changes: 4 additions & 4 deletions main/dpdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

int br_rte_log_type;

int dpdk_init(struct boring_router *br) {
int dpdk_init(struct br_args *args) {
char main_lcore[32] = {0};
char **eal_args = NULL;
int ret = -1;
Expand All @@ -42,17 +42,17 @@ int dpdk_init(struct boring_router *br) {
arrpush(eal_args, "-a");
arrpush(eal_args, "0000:00:00.0");

if (br->test_mode) {
if (args->test_mode) {
arrpush(eal_args, "--no-shconf");
arrpush(eal_args, "--no-huge");
arrpush(eal_args, "-m");
arrpush(eal_args, "1024");
} else {
arrpush(eal_args, "--in-memory");
}
if (br->log_level >= RTE_LOG_DEBUG) {
if (args->log_level >= RTE_LOG_DEBUG) {
arrpush(eal_args, "--log-level=*:debug");
} else if (br->log_level >= RTE_LOG_INFO) {
} else if (args->log_level >= RTE_LOG_INFO) {
arrpush(eal_args, "--log-level=*:info");
} else {
arrpush(eal_args, "--log-level=*:notice");
Expand Down
2 changes: 1 addition & 1 deletion main/dpdk.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include "br.h"

int dpdk_init(struct boring_router *);
int dpdk_init(struct br_args *);
void dpdk_fini(void);

#endif
44 changes: 27 additions & 17 deletions main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,41 +37,49 @@ static void usage(const char *prog) {
puts(" -h, --help Display this help message and exit.");
puts(" -v, --verbose Increase verbosity.");
puts(" -t, --test-mode Run in test mode (no hugepages).");
puts(" -p, --poll-mode Disable automatic micro-sleep.");
puts(" -s PATH, --socket PATH Path the control plane API socket.");
puts(" Default: BR_SOCK_PATH from env or");
printf(" %s).\n", BR_DEFAULT_SOCK_PATH);
}

static struct boring_router br;
static struct event_base *ev_base;
static struct br_args args;

const struct br_args *br_args(void) {
return &args;
}

static int parse_args(int argc, char **argv) {
int c;

#define FLAGS ":s:htv"
#define FLAGS ":s:htpv"
static struct option long_options[] = {
{"socket", required_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'},
{"test-mode", no_argument, NULL, 't'},
{"poll-mode", no_argument, NULL, 'p'},
{"verbose", no_argument, NULL, 'v'},
{0},
};

opterr = 0; // disable getopt default error reporting

br.api_sock_path = getenv("BR_SOCK_PATH");
br.log_level = RTE_LOG_NOTICE;
args.api_sock_path = getenv("BR_SOCK_PATH");
args.log_level = RTE_LOG_NOTICE;

while ((c = getopt_long(argc, argv, FLAGS, long_options, NULL)) != -1) {
switch (c) {
case 's':
br.api_sock_path = optarg;
args.api_sock_path = optarg;
break;
case 't':
br.test_mode = true;
args.test_mode = true;
break;
case 'p':
args.poll_mode = true;
break;
case 'v':
br.log_level++;
args.log_level++;
break;
case 'h':
usage(argv[0]);
Expand All @@ -94,8 +102,8 @@ static int parse_args(int argc, char **argv) {
return -1;
}

if (br.api_sock_path == NULL)
br.api_sock_path = BR_DEFAULT_SOCK_PATH;
if (args.api_sock_path == NULL)
args.api_sock_path = BR_DEFAULT_SOCK_PATH;

return 0;
}
Expand All @@ -122,6 +130,8 @@ static ssize_t send_response(evutil_socket_t sock, struct br_api_response *resp)
return send(sock, resp, len, MSG_DONTWAIT | MSG_NOSIGNAL);
}

static struct event_base *ev_base;

static void api_write_cb(evutil_socket_t sock, short what, void *priv) {
struct event *ev = event_base_get_running_event(ev_base);
struct br_api_response *resp = priv;
Expand Down Expand Up @@ -295,16 +305,16 @@ static int listen_api_socket(void) {
}

addr.un.sun_family = AF_UNIX;
strncpy(addr.un.sun_path, br.api_sock_path, sizeof addr.un.sun_path - 1);
strncpy(addr.un.sun_path, args.api_sock_path, sizeof addr.un.sun_path - 1);

if (bind(fd, &addr.a, sizeof(addr.un)) < 0) {
LOG(ERR, "bind: %s: %s", br.api_sock_path, strerror(errno));
LOG(ERR, "bind: %s: %s", args.api_sock_path, strerror(errno));
close(fd);
return -1;
}

if (listen(fd, BACKLOG) < 0) {
LOG(ERR, "listen: %s: %s", br.api_sock_path, strerror(errno));
LOG(ERR, "listen: %s: %s", args.api_sock_path, strerror(errno));
close(fd);
return -1;
}
Expand All @@ -318,11 +328,11 @@ static int listen_api_socket(void) {
);
if (ev_listen == NULL || event_add(ev_listen, NULL) < 0) {
close(fd);
LOG(ERR, "event_new: %s: %s", br.api_sock_path, strerror(errno));
LOG(ERR, "event_new: %s: %s", args.api_sock_path, strerror(errno));
return -1;
}

LOG(INFO, "listening on API socket %s", br.api_sock_path);
LOG(INFO, "listening on API socket %s", args.api_sock_path);

return 0;
}
Expand All @@ -333,7 +343,7 @@ int main(int argc, char **argv) {
if (parse_args(argc, argv) < 0)
goto end;

if (dpdk_init(&br) < 0)
if (dpdk_init(&args) < 0)
goto dpdk_stop;

modules_init();
Expand All @@ -359,7 +369,7 @@ int main(int argc, char **argv) {
event_free_finalize(0, ev_listen, finalize_close_fd);
if (ev_base)
event_base_free(ev_base);
unlink(br.api_sock_path);
unlink(args.api_sock_path);
libevent_global_shutdown();
modules_fini();
dpdk_stop:
Expand Down
17 changes: 12 additions & 5 deletions modules/infra/control/graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "graph.h"

#include <br.h>
#include <br_api.h>
#include <br_control.h>
#include <br_datapath.h>
Expand Down Expand Up @@ -166,7 +167,10 @@ static int worker_graph_new(struct worker *worker, uint8_t index) {
goto err;
}
n_rxqs = 0;
max_sleep_us = 1000; // unreasonably long maximum (1ms)
if (br_args()->poll_mode)
max_sleep_us = 0;
else
max_sleep_us = 1000; // unreasonably long maximum (1ms)
arrforeach (qmap, worker->rxqs) {
if (!qmap->enabled)
continue;
Expand All @@ -177,10 +181,13 @@ static int worker_graph_new(struct worker *worker, uint8_t index) {
qmap->queue_id);
rx->queues[n_rxqs].port_id = qmap->port_id;
rx->queues[n_rxqs].rxq_id = qmap->queue_id;
// divide buffer size by two to take into account the time to wakeup from sleep
rx_buffer_us = port_get_rxq_buffer_us(qmap->port_id, qmap->queue_id) / 2;
if (rx_buffer_us < max_sleep_us)
max_sleep_us = rx_buffer_us;
if (!br_args()->poll_mode) {
// divide buffer size by two to take into account
// the time to wakeup from sleep
rx_buffer_us = port_get_rxq_buffer_us(qmap->port_id, qmap->queue_id) / 2;
if (rx_buffer_us < max_sleep_us)
max_sleep_us = rx_buffer_us;
}
n_rxqs++;
}
rx->n_queues = n_rxqs;
Expand Down
9 changes: 6 additions & 3 deletions modules/infra/datapath/main_loop.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2023 Robin Jarry

#include <br.h>
#include <br_control.h>
#include <br_datapath.h>
#include <br_log.h>
Expand Down Expand Up @@ -147,9 +148,11 @@ void *br_datapath_loop(void *priv) {
log(ERR, "pthread_setname_np: %s", rte_strerror(rte_errno));
return NULL;
}
if (prctl(PR_SET_TIMERSLACK, SLEEP_RESOLUTION_NS) < 0) {
log(ERR, "prctl(PR_SET_TIMERSLACK): %s", strerror(errno));
return NULL;
if (!br_args()->poll_mode) {
if (prctl(PR_SET_TIMERSLACK, SLEEP_RESOLUTION_NS) < 0) {
log(ERR, "prctl(PR_SET_TIMERSLACK): %s", strerror(errno));
return NULL;
}
}

log(INFO, "lcore_id = %d", w->lcore_id);
Expand Down

0 comments on commit 4ff2344

Please sign in to comment.