diff options
Diffstat (limited to 'accel-dp/main.c')
-rw-r--r-- | accel-dp/main.c | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/accel-dp/main.c b/accel-dp/main.c new file mode 100644 index 00000000..bdf81632 --- /dev/null +++ b/accel-dp/main.c @@ -0,0 +1,378 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> +#include <sys/stat.h> +#include <sys/resource.h> +#include <sys/socket.h> + +#include <rte_config.h> +#include <rte_memory.h> +#include <rte_memzone.h> +#include <rte_launch.h> +#include <rte_eal.h> +#include <rte_per_lcore.h> +#include <rte_lcore.h> +#include <rte_ethdev.h> +#include <rte_log.h> +#include <rte_errno.h> +#include <rte_debug.h> + +#include "init.h" +#include "conf_file.h" +#include "event.h" + +#define RTE_LOGTYPE_INIT RTE_LOGTYPE_USER1 +#define MBUF_CACHE_SIZE 128 + +int sock_fd; + +static struct rte_mempool *mbuf_pool; + +static LIST_HEAD(init_list); + +struct init { + struct list_head entry; + + int order; + void (*func)(void); +}; + +void register_init(int order, void (*func)(void)) +{ + struct init *i1, *i = malloc(sizeof(*i)); + struct list_head *p = init_list.next; + + i->order = order; + i->func = func; + + while (p != &init_list) { + i1 = list_entry(p, typeof(*i1), entry); + if (order < i1->order) + break; + p = p->next; + } + list_add_tail(&i->entry, p); +} + +static void run_init(void) +{ + struct init *i; + + list_for_each_entry(i, &init_list, entry) + i->func(); +} + +static void change_limits(void) +{ + FILE *f; + struct rlimit lim; + unsigned int nr_open = 1024*1024; + + f = fopen("/proc/sys/fs/nr_open", "r"); + if (f) { + fscanf(f, "%d", &nr_open); + fclose(f); + } + + lim.rlim_cur = nr_open; + lim.rlim_max = nr_open; + setrlimit(RLIMIT_NOFILE, &lim); +} + +static int bind_driver(const char *opt, char **val) +{ + char *ptr = strchr(opt, ':'); + char drv[128]; + int fd, r; + char fname[1024]; + char bus_id[64]; + struct stat st; + char vendor[16], device[16]; + + if (!ptr) + return -1; + + if (strchr(ptr + 1, ':')) { + memcpy(drv, opt, ptr - opt); + drv[ptr - opt] = 0; + opt = ptr + 1; + } else + strcpy(drv, "uio_pci_generic"); + + sprintf(bus_id, "0000:%s", opt); + + sprintf(fname, "/sys/bus/pci/devices/%s", bus_id); + if (stat(fname, &st)) { + fprintf(stderr, "%s: device not found\n", opt); + return -1; + } + + sprintf(fname, "/sys/bus/pci/devices/%s/vendor", bus_id); + fd = open(fname, O_RDONLY); + r = read(fd, vendor, sizeof(vendor)); + if (r <= 0) { + fprintf(stderr, "%s: failed to read vendor\n", opt); + close(fd); + return -1; + } + vendor[r - 1] = 0; + close(fd); + + sprintf(fname, "/sys/bus/pci/devices/%s/device", bus_id); + fd = open(fname, O_RDONLY); + r = read(fd, device, sizeof(device)); + if (r <= 0) { + fprintf(stderr, "%s: failed to read device\n", opt); + close(fd); + return -1; + } + device[r - 1] = 0; + close(fd); + + sprintf(fname, "modprobe -q %s", drv); + system(fname); + + sprintf(fname, "/sys/bus/pci/drivers/%s", drv); + if (stat(fname, &st)) { + fprintf(stderr, "%s: driver '%s' is not loaded\n", opt, drv); + return -1; + } + + sprintf(fname, "/sys/bus/pci/devices/%s/driver", bus_id); + + r = readlink(fname, fname, sizeof(fname)); + if (r > 0) { + fname[r] = 0; + ptr = fname + r - 1; + while (*ptr != '/') + ptr--; + + if (strcmp(ptr + 1, drv)) { + fprintf(stderr, "%s: unbind driver: %s\n", opt, ptr + 1); + + sprintf(fname, "/sys/bus/pci/devices/%s/driver/unbind", bus_id); + + fd = open(fname, O_WRONLY); + if (fd < 0) { + fprintf(stderr, "%s: failed to unbind driver: %s\n", opt, strerror(errno)); + return -1; + } + + if (write(fd, bus_id, strlen(bus_id)) < 0) { + fprintf(stderr, "%s: failed to unbind driver: %s\n", opt, strerror(errno)); + close(fd); + return -1; + } + close(fd); + } else + goto out; + } + + sprintf(fname, "/sys/bus/pci/drivers/%s/new_id", drv); + fd = open(fname, O_WRONLY); + if (fd < 0) { + fprintf(stderr, "%s: failed to bind driver %s: %s\n", opt, drv, strerror(errno)); + return -1; + } + + sprintf(fname, "%s %s", vendor, device); + if (write(fd, fname, strlen(fname)) < 0) { + fprintf(stderr, "%s: failed to bind driver %s: %s\n", opt, drv, strerror(errno)); + close(fd); + return -1; + } + close(fd); + + /*sprintf(fname, "/sys/bus/pci/drivers/%s/bind", drv); + fd = open(fname, O_WRONLY); + if (fd < 0) { + fprintf(stderr, "%s: failed to bind driver %s: %s\n", opt, drv, strerror(errno)); + close(fd); + return -1; + } + + if (write(fd, bus_id, strlen(bus_id)) < 0) { + fprintf(stderr, "%s: failed to bind driver %s: %s\n", opt, drv, strerror(errno)); + close(fd); + return -1; + } + close(fd);*/ + +out: + *val = (char *)opt; + return 0; +} + +static int build_rte_args(char **argv) +{ + int i = 0; + struct conf_sect *s = conf_get_sect("core"); + struct conf_opt *opt; + + if (!s) + return 0; + + for (opt = s->opt; opt; opt = opt->next) { + if (!strcmp(opt->name, "coremask")) { + argv[i++] = "-c"; + argv[i++] = opt->val; + } else if (!strcmp(opt->name, "corelist")) { + argv[i++] = "-l"; + argv[i++] = opt->val; + } else if (!strcmp(opt->name, "coremap")) { + argv[i++] = "--lcores"; + argv[i++] = opt->val; + } else if (!strcmp(opt->name, "master-lcore")) { + argv[i++] = "--master-lcore"; + argv[i++] = opt->val; + } else if (!strcmp(opt->name, "mem-channels")) { + argv[i++] = "-n"; + argv[i++] = opt->val; + } else if (!strcmp(opt->name, "mem-ranks")) { + argv[i++] = "-r"; + argv[i++] = opt->val; + } else if (!strcmp(opt->name, "socket-mem")) { + argv[i++] = "-m"; + argv[i++] = opt->val; + } else if (!strcmp(opt->name, "huge-dir")) { + argv[i++] = "--huge-dir"; + argv[i++] = opt->val; + } + } + + s = conf_get_sect("interface"); + + for (opt = s->opt; opt; opt = opt->next) { + const char *busid = conf_get_subopt(opt, "busid"); + if (!busid) { + fprintf(stderr, "%s: busid not specified\n", opt->name); + return -1; + } + + if (strcmp(busid, "kni")) { + if (bind_driver(busid, &argv[i + 1])) + return -1; + argv[i++] = "-w"; + i++; + } + } + + return i; +} + +static int init_pktmbuf_pool() +{ + int mbuf_cnt = 16*1024; + const char *opt = conf_get_opt("core", "mbuf-count"); + + if (opt) + mbuf_cnt = atoi(opt); + + mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", mbuf_cnt, MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + if (!mbuf_pool) { + fprintf(stderr, "%s\n", rte_strerror(rte_errno)); + return -1; + } + + return 0; +} + +int main(int argc, char **argv) +{ + unsigned lcore_id; + int i; + char *cf = NULL; + char *pid_file = NULL; + int goto_daemon = 0; + int rte_argc; + char *rte_argv[256]; + const char *opt; + int dist_lcore; + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-c") && i + 1 < argc) + cf = argv[++i]; + else if (!strcmp(argv[i], "-p") && i + 1 < argc) + pid_file = argv[++i]; + else if (!strcmp(argv[i], "-d")) + goto_daemon = 1; + } + + if (!cf) { + printf("usage: accel-dpdk [-d] [-p <pid file>] -c <config file>\n"); + return 1; + } + + if (conf_load(cf)) + return 1; + + rte_argv[0] = argv[0]; + rte_argc = build_rte_args(rte_argv + 1) + 1; + if (rte_argc == 0) + return 1; + + if (rte_eal_init(rte_argc, rte_argv) < 0) { + fprintf(stderr, "Cannot init EAL\n"); + return 1; + } + + if (init_pktmbuf_pool()) + return -1; + + sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + + run_init(); + + if (ctrl_init()) + return 1; + + if (eth_dev_init(mbuf_pool)) + return -1; + + if (kni_dev_init(mbuf_pool)) + return -1; + + opt = conf_get_opt("core", "distributor-lcore"); + if (opt) + dist_lcore = atoi(opt); + else + dist_lcore = -1; + + if (distributor_init(dist_lcore != -1)) + return -1; + + if (goto_daemon) + daemon(0, 0); + + change_limits(); + + if (pid_file) { + FILE *f = fopen(pid_file, "w"); + if (f) { + fprintf(f, "%i", getpid()); + fclose(f); + } + } + + /* call lcore_hello() on every slave lcore */ + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + printf("%i\n", lcore_id); + if (lcore_id == dist_lcore) + rte_eal_remote_launch(lcore_distributor, NULL, lcore_id); + else + rte_eal_remote_launch(lcore_worker, NULL, lcore_id); + } + + if (dist_lcore == -1) + distributor_loop(1); + else + event_loop(); + + rte_eal_mp_wait_lcore(); + return 0; +} |