Пример #1
0
/* Parse the argument given in the command line of the application */
int
app_parse_args(int argc, char **argv)
{
	int opt, ret;
	char **argvopt;
	int option_index;
	char *prgname = argv[0];
	static struct option lgopts[] = {
		//aniadido
		{"record", 1, 0, 0},
		//normal
		{"rx", 1, 0, 0},
		{"tx", 1, 0, 0},
		{"rsz", 1, 0, 0},
		{"bsz", 1, 0, 0},
		{"pos-lb", 1, 0, 0},
		{NULL, 0, 0, 0}
	};
	uint32_t arg_rx = 0;
	uint32_t arg_tx = 0;
	uint32_t arg_rsz = 0;
	uint32_t arg_bsz = 0;
	uint32_t arg_pos_lb = 0;

	argvopt = argv;

	while ((opt = getopt_long(argc, argvopt, "",
				lgopts, &option_index)) != EOF) {

		switch (opt) {
		/* long options */
		case 0:
			if (!strcmp(lgopts[option_index].name, "rx")) {
				arg_rx = 1;
				ret = parse_arg_rx(optarg);
				if (ret) {
					printf("Incorrect value for --rx argument (%d)\n", ret);
					return -1;
				}
			}
			if (!strcmp(lgopts[option_index].name, "tx")) {
				arg_tx = 1;
				ret = parse_arg_tx(optarg);
				if (ret) {
					printf("Incorrect value for --tx argument (%d)\n", ret);
					return -1;
				}
			}
			if (!strcmp(lgopts[option_index].name, "w")) {
				ret = parse_arg_w(optarg);
				if (ret) {
					printf("Incorrect value for --w argument (%d)\n", ret);
					return -1;
				}
			}
			if (!strcmp(lgopts[option_index].name, "record")) {
				strcpy(record_File,optarg);
				printf("Record value set to %s\n", record_File);					
			}
			if (!strcmp(lgopts[option_index].name, "rsz")) {
				arg_rsz = 1;
				ret = parse_arg_rsz(optarg);
				if (ret) {
					printf("Incorrect value for --rsz argument (%d)\n", ret);
					return -1;
				}
			}
			if (!strcmp(lgopts[option_index].name, "bsz")) {
				arg_bsz = 1;
				ret = parse_arg_bsz(optarg);
				if (ret) {
					printf("Incorrect value for --bsz argument (%d)\n", ret);
					return -1;
				}
			}
			if (!strcmp(lgopts[option_index].name, "pos-lb")) {
				arg_pos_lb = 1;
				ret = parse_arg_pos_lb(optarg);
				if (ret) {
					printf("Incorrect value for --pos-lb argument (%d)\n", ret);
					return -1;
				}
			}
			break;

		default:
			return -1;
		}
	}

	/* Check that all mandatory arguments are provided */
	if ((arg_rx == 0) || (arg_tx == 0) ){
		printf("Not all mandatory arguments are present\n");
		return -1;
	}

	/* Assign default values for the optional arguments not provided */
	if (arg_rsz == 0) {
		app.nic_rx_ring_size = APP_DEFAULT_NIC_RX_RING_SIZE;
		app.nic_tx_ring_size = APP_DEFAULT_NIC_TX_RING_SIZE;
		app.ring_rx_size = APP_DEFAULT_RING_RX_SIZE;
		app.ring_tx_size = APP_DEFAULT_RING_TX_SIZE;
	}

	if (arg_bsz == 0) {
		app.burst_size_io_rx_read = APP_DEFAULT_BURST_SIZE_IO_RX_READ;
		app.burst_size_io_rx_write = APP_DEFAULT_BURST_SIZE_IO_RX_WRITE;
		app.burst_size_io_tx_read = APP_DEFAULT_BURST_SIZE_IO_TX_READ;
		app.burst_size_io_tx_write = APP_DEFAULT_BURST_SIZE_IO_TX_WRITE;
		app.burst_size_worker_read = APP_DEFAULT_BURST_SIZE_WORKER_READ;
		app.burst_size_worker_write = APP_DEFAULT_BURST_SIZE_WORKER_WRITE;
	}

	if (arg_pos_lb == 0) {
		app.pos_lb = APP_DEFAULT_IO_RX_LB_POS;
	}
	
	if (optind >= 0)
		argv[optind - 1] = prgname;

	ret = optind - 1;
	optind = 0; /* reset getopt lib */
	return ret;
}
Пример #2
0
/* Parse the argument given in the command line of the application */
int
app_parse_args(int argc, const char *argv[]) {
  int opt, ret;
  char **argvopt;
  int option_index;
  const char *prgname = argv[0];
  static const struct option lgopts[] = {
    {"rx", 1, 0, 0},
    {"tx", 1, 0, 0},
    {"w", 1, 0, 0},
    {"rsz", 1, 0, 0},
    {"bsz", 1, 0, 0},
    {"no-cache", 0, 0, 0},
    {"core-assign", 1, 0, 0},
    {"kvstype", 1, 0, 0},
#ifdef __SSE4_2__
    {"hashtype", 1, 0, 0},
#endif /* __SSE4_2__ */
    {"fifoness", 1, 0, 0},
    {"show-core-config", 0, 0, 0},
    {NULL, 0, 0, 0}
  };
  uint32_t arg_p = 0;
  uint32_t arg_w = 0;
  uint32_t arg_rx = 0;
  uint32_t arg_tx = 0;
  uint32_t arg_rsz = 0;
  uint32_t arg_bsz = 0;

  uint64_t portmask = 0;
  char *end = NULL;
  struct app_lcore_params *lp, *htlp;
  unsigned lcore, htcore, lcore_count, i, wk_lcore_count = 0;
  unsigned rx_lcore_start, tx_lcore_start, wk_lcore_start;
  int rx_lcore_inc, tx_lcore_inc, wk_lcore_inc;
  uint8_t portid, port_count, count, n;
  bool show_core_assign = false;

  argvopt = (char **)argv;

  while ((opt = getopt_long(argc, argvopt, "p:w:",
                            lgopts, &option_index)) != EOF) {
    switch (opt) {
      case 'p':
        if (optarg[0] == '\0') {
          printf("Require value for -p argument\n");
          return -1;
        }
        portmask = (uint64_t)strtoull(optarg, &end, 16);
        if (end == NULL || *end != '\0') {
          printf("Non-numerical value for -p argument\n");
          return -1;
        }
        if (portmask == 0) {
          printf("Incorrect value for -p argument\n");
          return -1;
        }
        arg_p = 1;
        break;
      case 'w':
        if (optarg[0] == '\0') {
          printf("Require value for -w argument\n");
          return -1;
        }
        wk_lcore_count = (unsigned)strtoul(optarg, &end, 10);
        if (end == NULL || *end != '\0') {
          printf("Non-numerical value for -w argument\n");
          return -1;
        }
        if (wk_lcore_count == 0) {
          printf("Incorrect value for -w argument\n");
          return -1;
        }
        break;
        /* long options */
      case 0:
        if (!strcmp(lgopts[option_index].name, "rx")) {
          arg_rx = 1;
          ret = parse_arg_rx(optarg);
          if (ret) {
            printf("Incorrect value for --rx argument (%d)\n", ret);
            return -1;
          }
        }
        if (!strcmp(lgopts[option_index].name, "tx")) {
          arg_tx = 1;
          ret = parse_arg_tx(optarg);
          if (ret) {
            printf("Incorrect value for --tx argument (%d)\n", ret);
            return -1;
          }
        }
        if (!strcmp(lgopts[option_index].name, "w")) {
          arg_w = 1;
          ret = parse_arg_w(optarg);
          if (ret) {
            printf("Incorrect value for --w argument (%d)\n", ret);
            return -1;
          }
        }
        if (!strcmp(lgopts[option_index].name, "rsz")) {
          arg_rsz = 1;
          ret = parse_arg_rsz(optarg);
          if (ret) {
            printf("Incorrect value for --rsz argument (%d)\n", ret);
            return -1;
          }
        }
        if (!strcmp(lgopts[option_index].name, "bsz")) {
          arg_bsz = 1;
          ret = parse_arg_bsz(optarg);
          if (ret) {
            printf("Incorrect value for --bsz argument (%d)\n", ret);
            return -1;
          }
        }
        if (!strcmp(lgopts[option_index].name, "core-assign")) {
          ret = parse_arg_core_assign(optarg);
          if (ret) {
            printf("Incorrect value for --core-assign argument (%d)\n", ret);
            return -1;
          }
        }
        if (!strcmp(lgopts[option_index].name, "no-cache")) {
          app.no_cache = 1;
        }
        if (!strcmp(lgopts[option_index].name, "kvstype")) {
          ret = parse_arg_kvstype(optarg);
          if (ret) {
            printf("Incorrect value for --ksvtype argument (%d)\n", ret);
            return -1;
          }
        }
        if (!strcmp(lgopts[option_index].name, "hashtype")) {
          ret = parse_arg_hashtype(optarg);
          if (ret) {
            printf("Incorrect value for --hashtype argument (%d)\n", ret);
            return -1;
          }
        }
        if (!strcmp(lgopts[option_index].name, "fifoness")) {
          ret = parse_arg_fifoness(optarg);
          if (ret) {
            printf("Incorrect value for --fifoness argument (%d)\n", ret);
            return -1;
          }
        }
        if (!strcmp(lgopts[option_index].name, "show-core-config")) {
          show_core_assign = true;
        }
        break;

      default:
        printf("Incorrect option\n");
        return -1;
    }
  }

  /* Check that all mandatory arguments are provided */
  if ((arg_rx == 0 || arg_tx == 0 || arg_w == 0) && arg_p == 0) {
    lagopus_exit_error(EXIT_FAILURE,
                       "Not all mandatory arguments are present\n");
  }

  port_count = 0;
  if (arg_p != 0) {
    /**
     * Assign lcore for each thread automatically.
     */
    for (i = 0; i < 32; i++) {
      if ((portmask & (uint64_t)(1ULL << i)) != 0) {
        port_count++;
      }
    }
    if (port_count == 0) {
      lagopus_exit_error(EXIT_FAILURE,
                         "error: port is not specified.  use -p HEXNUM or --rx, --tx.\n");
    }
  }
  for (lcore_count = 0, lcore = 0; lcore < RTE_MAX_LCORE; lcore++) {
    if (lcore == rte_get_master_lcore()) {
      continue;
    }
    if (!rte_lcore_is_enabled(lcore)) {
      continue;
    }
    lp = &app.lcore_params[lcore];
    lp->socket_id = lcore_config[lcore].socket_id;
    lp->core_id = lcore_config[lcore].core_id;

    /* add lcore id except for hyper-threading core. */
    for (htcore = 0; htcore < lcore; htcore++) {
      if (!rte_lcore_is_enabled(htcore)) {
        continue;
      }
      htlp = &app.lcore_params[htcore];
      if (app.core_assign == CORE_ASSIGN_PERFORMANCE) {
        if (lp->socket_id == htlp->socket_id &&
            lp->core_id == htlp->core_id) {
          break;
        }
      }
    }
    if (htcore == lcore) {
      lcores[lcore_count++] = lcore;
    }
  }

  if (lcore_count == 0) {
    lagopus_exit_error(
      EXIT_FAILURE,
      "Not enough active core "
      "(need at least 2 active core%s)\n",
      app.core_assign == CORE_ASSIGN_PERFORMANCE ?
      " except for HTT core" : "");
  }
  if (app.core_assign == CORE_ASSIGN_MINIMUM) {
    lcore_count = 1;
  }
  if (lcore_count == 1) {
    /*
     * I/O and worker shares single lcore.
     */
    rx_lcore_start = 0;
    tx_lcore_start = 0;
    wk_lcore_start = 0;
    rx_lcore_inc = 0;
    tx_lcore_inc = 0;
    wk_lcore_inc = 0;
  } else if (port_count * 4 <= lcore_count) {
    /*
     * each ports rx has own lcore.
     * each ports tx has own lcore.
     * all other lcores are assigned as worker.
     */
    rx_lcore_start = 0;
    tx_lcore_start = rx_lcore_start + port_count;
    wk_lcore_start = tx_lcore_start + port_count;
    rx_lcore_inc = 1;
    tx_lcore_inc = 1;
    wk_lcore_inc = 1;
  } else if (port_count * 2 <= lcore_count) {
    /*
     * each ports (rx/tx) has own lcore.
     * all other lcores are assigned as worker.
     */
    rx_lcore_start = 0;
    tx_lcore_start = 0;
    wk_lcore_start = rx_lcore_start + port_count;
    rx_lcore_inc = 1;
    tx_lcore_inc = 1;
    wk_lcore_inc = 1;
  } else if (port_count <= lcore_count) {
    /*
     * odd ports and even ports (rx/tx) shared lcore.
     * all other lcores are assigned as worker.
     */
    rx_lcore_start = 0;
    tx_lcore_start = 0;
    wk_lcore_start = rx_lcore_start + (port_count + 1) / 2;
    rx_lcore_inc = 2;
    tx_lcore_inc = 2;
    wk_lcore_inc = 1;
  } else if (port_count <= lcore_count * 2) {
    /*
     * four ports (rx/tx) shared lcore.
     * all other lcores are assigned as worker.
     */
    rx_lcore_start = 0;
    tx_lcore_start = 0;
    wk_lcore_start = rx_lcore_start + (port_count + 3) / 4;
    rx_lcore_inc = 4;
    tx_lcore_inc = 4;
    wk_lcore_inc = 1;
  } else if (lcore_count >= 4) {
    /*
     * rx for all ports has own lcore.
     * tx for all ports has own lcore.
     * all other lcores are assigned as worker.
     */
    rx_lcore_start = 0;
    tx_lcore_start = 1;
    wk_lcore_start = 2;
    rx_lcore_inc = 0;
    tx_lcore_inc = 0;
    wk_lcore_inc = 1;
  } else {
    /*
     * I/O has own lcore.
     * all other lcores are assigned as worker.
     */
    rx_lcore_start = 0;
    tx_lcore_start = 0;
    wk_lcore_start = 1;
    rx_lcore_inc = 0;
    tx_lcore_inc = 0;
    wk_lcore_inc = 1;
  }
  /* assign core automatically */
  if (arg_rx == 0) {
    lcore = rx_lcore_start;
    count = rx_lcore_inc;
    for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {
      if ((portmask & (uint64_t)(1ULL << portid)) == 0) {
        continue;
      }
      if (assign_rx_lcore(portid, lcore) != 0) {
        return -5;
      }
      if (--count == 0) {
        lcore++;
        count = rx_lcore_inc;
      }
    }
  }
  if (arg_tx == 0) {
    lcore = tx_lcore_start;
    count = tx_lcore_inc;
    for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {
      if ((portmask & (uint64_t)(1ULL << portid)) == 0) {
        continue;
      }
      if (assign_tx_lcore(portid, lcore) != 0) {
        return -5;
      }
      if (--count == 0) {
        lcore++;
        count = tx_lcore_inc;
      }
    }
  }
  if (arg_w == 0) {
    if (wk_lcore_count == 0) {
      wk_lcore_count = lcore_count - wk_lcore_start;
    }
    for (lcore = wk_lcore_start;
         lcore < wk_lcore_start + wk_lcore_count;
         lcore++) {
      lp = &app.lcore_params[lcores[lcore]];
      if (lp->type == e_APP_LCORE_IO) {
        /* core is shared by I/O and worker. */
        lp->type = e_APP_LCORE_IO_WORKER;
      } else {
        lp->type = e_APP_LCORE_WORKER;
      }
      if (wk_lcore_inc != 1) {
        break;
      }
    }
  }

  /* Assign default values for the optional arguments not provided */
  if (arg_rsz == 0) {
    app.nic_rx_ring_size = APP_DEFAULT_NIC_RX_RING_SIZE;
    app.nic_tx_ring_size = APP_DEFAULT_NIC_TX_RING_SIZE;
    app.ring_rx_size = APP_DEFAULT_RING_RX_SIZE;
    app.ring_tx_size = APP_DEFAULT_RING_TX_SIZE;
  }

  if (arg_bsz == 0) {
    app.burst_size_io_rx_read = APP_DEFAULT_BURST_SIZE_IO_RX_READ;
    app.burst_size_io_rx_write = APP_DEFAULT_BURST_SIZE_IO_RX_WRITE;
    app.burst_size_io_tx_read = APP_DEFAULT_BURST_SIZE_IO_TX_READ;
    app.burst_size_io_tx_write = APP_DEFAULT_BURST_SIZE_IO_TX_WRITE;
    app.burst_size_worker_read = APP_DEFAULT_BURST_SIZE_WORKER_READ;
    app.burst_size_worker_write = APP_DEFAULT_BURST_SIZE_WORKER_WRITE;
  }

  /* Check cross-consistency of arguments */
  if (app_check_every_rx_port_is_tx_enabled() < 0) {
    lagopus_msg_error("At least one RX port is not enabled for TX.\n");
    return -2;
  }

  if (show_core_assign == true) {
    printf("core assign:\n");
    for (lcore = 0; lcore < RTE_MAX_LCORE; lcore++) {
      if (lcore_config[lcore].detected != true) {
        continue;
      }
      lp = &app.lcore_params[lcore];
      printf("  lcore %d:\n", lcore);
      if (lp->type == e_APP_LCORE_IO) {
        printf("    type: I/O\n");
      } else if (lp->type == e_APP_LCORE_WORKER) {
        printf("    type: WORKER\n");
      } else if (lp->type == e_APP_LCORE_IO_WORKER) {
        printf("    type: I/O WORKER\n");
      } else {
        printf("    type: not used\n");
      }
      for (n = 0; n < lp->io.rx.n_nic_queues; n++) {
        printf("    RX port %d (queue %d)\n",
               lp->io.rx.nic_queues[n].port,
               lp->io.rx.nic_queues[n].queue);
      }
      for (n = 0; n < lp->io.tx.n_nic_ports; n++) {
        printf("    TX port %d\n",
               lp->io.tx.nic_ports[n]);
      }
    }
    exit(0);
  }

  if (optind >= 0) {
    argv[optind - 1] = prgname;
  }
  ret = optind - 1;
  optind = 0; /* reset getopt lib */
  return ret;
}