dpdk_device_t *xd;
vlib_pci_addr_t last_pci_addr;
u32 last_pci_addr_port = 0;
- vlib_thread_registration_t *tr;
- uword *p;
+ vlib_thread_registration_t *tr, *tr_hqos;
+ uword *p, *p_hqos;
- u32 next_cpu = 0;
+ u32 next_cpu = 0, next_hqos_cpu = 0;
u8 af_packet_port_id = 0;
last_pci_addr.as_u32 = ~0;
vec_validate_aligned (dm->workers, tm->n_vlib_mains - 1,
CLIB_CACHE_LINE_BYTES);
+ dm->hqos_cpu_first_index = 0;
+ dm->hqos_cpu_count = 0;
+
+ /* find out which cpus will be used for I/O TX */
+ p_hqos = hash_get_mem (tm->thread_registrations_by_name, "hqos-threads");
+ tr_hqos = p_hqos ? (vlib_thread_registration_t *) p_hqos[0] : 0;
+
+ if (tr_hqos && tr_hqos->count > 0)
+ {
+ dm->hqos_cpu_first_index = tr_hqos->first_index;
+ dm->hqos_cpu_count = tr_hqos->count;
+ }
+
+ vec_validate_aligned (dm->devices_by_hqos_cpu, tm->n_vlib_mains - 1,
+ CLIB_CACHE_LINE_BYTES);
+
+ vec_validate_aligned (dm->hqos_threads, tm->n_vlib_mains - 1,
+ CLIB_CACHE_LINE_BYTES);
+
+#ifdef NETMAP
+ if (rte_netmap_probe () < 0)
+ return clib_error_return (0, "rte netmap probe failed");
+#endif
+
nports = rte_eth_dev_count ();
if (nports < 1)
{
else
xd->rx_q_used = 1;
- xd->dev_type = VNET_DPDK_DEV_ETH;
+ xd->flags |= DPDK_DEVICE_FLAG_PMD;
/* workaround for drivers not setting driver_name */
if ((!dev_info.driver_name) && (dev_info.pci_dev))
/* *INDENT-OFF* */
clib_bitmap_foreach (i, devconf->workers, ({
int cpu = dm->input_cpu_first_index + i;
- unsigned lcore = vlib_worker_threads[cpu].dpdk_lcore_id;
+ unsigned lcore = vlib_worker_threads[cpu].lcore_id;
vec_validate(xd->cpu_socket_id_by_queue, q);
xd->cpu_socket_id_by_queue[q] = rte_lcore_to_socket_id(lcore);
vec_add2(dm->devices_by_cpu[cpu], dq, 1);
for (q = 0; q < xd->rx_q_used; q++)
{
int cpu = dm->input_cpu_first_index + next_cpu;
- unsigned lcore = vlib_worker_threads[cpu].dpdk_lcore_id;
+ unsigned lcore = vlib_worker_threads[cpu].lcore_id;
/*
* numa node for worker thread handling this queue
next_cpu = 0;
}
+
+ if (devconf->hqos_enabled)
+ {
+ xd->flags |= DPDK_DEVICE_FLAG_HQOS;
+
+ if (devconf->hqos.hqos_thread_valid)
+ {
+ int cpu = dm->hqos_cpu_first_index + devconf->hqos.hqos_thread;
+
+ if (devconf->hqos.hqos_thread >= dm->hqos_cpu_count)
+ return clib_error_return (0, "invalid HQoS thread index");
+
+ vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
+ dq->device = xd->device_index;
+ dq->queue_id = 0;
+ }
+ else
+ {
+ int cpu = dm->hqos_cpu_first_index + next_hqos_cpu;
+
+ if (dm->hqos_cpu_count == 0)
+ return clib_error_return (0, "no HQoS threads available");
+
+ vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
+ dq->device = xd->device_index;
+ dq->queue_id = 0;
+
+ next_hqos_cpu++;
+ if (next_hqos_cpu == dm->hqos_cpu_count)
+ next_hqos_cpu = 0;
+
+ devconf->hqos.hqos_thread_valid = 1;
+ devconf->hqos.hqos_thread = cpu;
+ }
+ }
+
vec_validate_aligned (xd->tx_vectors, tm->n_vlib_mains,
CLIB_CACHE_LINE_BYTES);
for (j = 0; j < tm->n_vlib_mains; j++)
{
- vec_validate_ha (xd->tx_vectors[j], DPDK_TX_RING_SIZE,
+ vec_validate_ha (xd->tx_vectors[j], xd->nb_tx_desc,
sizeof (tx_ring_hdr_t), CLIB_CACHE_LINE_BYTES);
vec_reset_length (xd->tx_vectors[j]);
}
if (rv)
return rv;
+ if (devconf->hqos_enabled)
+ {
+ rv = dpdk_port_setup_hqos (xd, &devconf->hqos);
+ if (rv < 0)
+ return rv;
+ }
+
/* count the number of descriptors used for this device */
nb_desc += xd->nb_rx_desc + xd->nb_tx_desc * xd->tx_q_used;
/* Create vnet interface */
vec_add2_aligned (dm->devices, xd, 1, CLIB_CACHE_LINE_BYTES);
- xd->dev_type = VNET_DPDK_DEV_KNI;
+ xd->flags |= DPDK_DEVICE_FLAG_KNI;
xd->device_index = xd - dm->devices;
ASSERT (nports + i == xd->device_index);
CLIB_CACHE_LINE_BYTES);
for (j = 0; j < tm->n_vlib_mains; j++)
{
- vec_validate_ha (xd->tx_vectors[j], DPDK_TX_RING_SIZE,
+ vec_validate_ha (xd->tx_vectors[j], xd->nb_tx_desc,
sizeof (tx_ring_hdr_t), CLIB_CACHE_LINE_BYTES);
vec_reset_length (xd->tx_vectors[j]);
}
}
devconf->pci_addr.as_u32 = pci_addr.as_u32;
+ devconf->hqos_enabled = 0;
+ dpdk_device_config_hqos_default (&devconf->hqos);
if (!input)
return 0;
devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_OFF;
else if (unformat (input, "vlan-strip-offload on"))
devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_ON;
+ else
+ if (unformat
+ (input, "hqos %U", unformat_vlib_cli_sub_input, &sub_input))
+ {
+ devconf->hqos_enabled = 1;
+ error = unformat_hqos (&sub_input, &devconf->hqos);
+ if (error)
+ break;
+ }
+ else if (unformat (input, "hqos"))
+ {
+ devconf->hqos_enabled = 1;
+ }
else
{
error = clib_error_return (0, "unknown input `%U'",
else if (unformat (input, "default"))
;
+ else if (unformat_skip_white_space (input))
+ ;
else
{
error = clib_error_return (0, "unknown input `%U'",
/* *INDENT-OFF* */
clib_bitmap_foreach (c, tm->cpu_socket_bitmap, (
{
- u32 pages_avail, page_size, mem;
- u8 *s = 0;
- u8 *p = 0;
- char * numa_path = "/sys/devices/system/node/node%u/";
- char * nonnuma_path = "/sys/kernel/mm/";
- char * suffix = "hugepages/hugepages-%ukB/free_hugepages%c";
- char * path = NULL;
- struct stat sb_numa, sb_nonnuma;
-
- p = format(p, numa_path, c);
- if (stat(numa_path, &sb_numa) < 0)
- sb_numa.st_mode = 0;
-
- if (stat(nonnuma_path, &sb_nonnuma) < 0)
- sb_nonnuma.st_mode = 0;
-
- if (S_ISDIR(sb_numa.st_mode)) {
- path = (char*)format((u8*)path, "%s%s", p, suffix);
- } else if (S_ISDIR(sb_nonnuma.st_mode)) {
- path = (char*)format((u8*)path, "%s%s", nonnuma_path, suffix);
- } else {
- use_1g = 0;
- use_2m = 0;
- vec_free(p);
- break;
- }
+ int pages_avail, page_size, mem;
vec_validate(mem_by_socket, c);
mem = mem_by_socket[c];
page_size = 1024;
- pages_avail = 0;
- s = format (s, path, page_size * 1024, 0);
- vlib_sysfs_read ((char *) s, "%u", &pages_avail);
- vec_reset_length (s);
+ pages_avail = vlib_sysfs_get_free_hugepages(c, page_size * 1024);
- if (page_size * pages_avail < mem)
+ if (pages_avail < 0 || page_size * pages_avail < mem)
use_1g = 0;
page_size = 2;
- pages_avail = 0;
- s = format (s, path, page_size * 1024, 0);
- vlib_sysfs_read ((char *) s, "%u", &pages_avail);
- vec_reset_length (s);
+ pages_avail = vlib_sysfs_get_free_hugepages(c, page_size * 1024);
- if (page_size * pages_avail < mem)
+ if (pages_avail < 0 || page_size * pages_avail < mem)
use_2m = 0;
-
- vec_free(s);
- vec_free(p);
- vec_free(path);
}));
/* *INDENT-ON* */
u8 hw_flags_chg = 0;
/* only update link state for PMD interfaces */
- if (xd->dev_type != VNET_DPDK_DEV_ETH)
+ if ((xd->flags & DPDK_DEVICE_FLAG_PMD) == 0)
return;
xd->time_last_link_update = now ? now : xd->time_last_link_update;
dpdk_update_link_state (xd, now);
#if DPDK_VHOST_USER
- if (xd->dev_type == VNET_DPDK_DEV_VHOST_USER)
+ if (xd->flags & DPDK_DEVICE_FLAG_VHOST_USER)
if (dpdk_vhost_user_process_if (vm, xd, vu_state) != 0)
continue;
#endif