summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChristian Ehrhardt <christian.ehrhardt@canonical.com>2017-03-02 16:15:51 +0100
committerChristian Ehrhardt <christian.ehrhardt@canonical.com>2017-03-03 14:41:36 +0100
commitce3d555e43e3795b5d9507fcfc76b7a0a92fd0d6 (patch)
tree3a9e9f8f6a62c7146fb391eae34481b2af4f7ff2 /lib
parent6b3e017e5d25f15da73f7700f7f2ac553ef1a2e9 (diff)
Imported Upstream version 16.11.1
Change-Id: I1e965265578efaaf08e5628607f53d2386d2df9f Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/librte_cryptodev/rte_cryptodev.c5
-rw-r--r--lib/librte_cryptodev/rte_cryptodev_pmd.h5
-rw-r--r--lib/librte_eal/common/eal_common_devargs.c1
-rw-r--r--lib/librte_eal/common/eal_common_vdev.c8
-rw-r--r--lib/librte_eal/common/include/rte_version.h2
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_pci_uio.c2
-rw-r--r--lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c1
-rw-r--r--lib/librte_ether/rte_ethdev.c105
-rw-r--r--lib/librte_ether/rte_ether_version.map1
-rw-r--r--lib/librte_mempool/rte_mempool.h4
-rw-r--r--lib/librte_mempool/rte_mempool_stack.c2
-rw-r--r--lib/librte_sched/rte_sched.c4
-rw-r--r--lib/librte_vhost/fd_man.c200
-rw-r--r--lib/librte_vhost/fd_man.h2
-rw-r--r--lib/librte_vhost/vhost.c1
-rw-r--r--lib/librte_vhost/vhost_user.c13
-rw-r--r--lib/librte_vhost/virtio_net.c7
17 files changed, 220 insertions, 143 deletions
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 127e8d0d..54e95d5c 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -225,13 +225,14 @@ rte_cryptodev_create_vdev(const char *name, const char *args)
}
int
-rte_cryptodev_get_dev_id(const char *name) {
+rte_cryptodev_get_dev_id(const char *name)
+{
unsigned i;
if (name == NULL)
return -1;
- for (i = 0; i < rte_cryptodev_globals->max_devs; i++)
+ for (i = 0; i < rte_cryptodev_globals->nb_devs; i++)
if ((strcmp(rte_cryptodev_globals->devs[i].data->name, name)
== 0) &&
(rte_cryptodev_globals->devs[i].attached ==
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index abfe2dc1..c6a57945 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -183,8 +183,9 @@ rte_cryptodev_pmd_get_named_dev(const char *name)
if (name == NULL)
return NULL;
- for (i = 0, dev = &rte_cryptodev_globals->devs[i];
- i < rte_cryptodev_globals->max_devs; i++) {
+ for (i = 0; i < rte_cryptodev_globals->max_devs; i++) {
+ dev = &rte_cryptodev_globals->devs[i];
+
if ((dev->attached == RTE_CRYPTODEV_ATTACHED) &&
(strcmp(dev->data->name, name) == 0))
return dev;
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717b..ffa8ad96 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -72,6 +72,7 @@ rte_eal_parse_devargs_str(const char *devargs_str,
if (*drvargs == NULL) {
free(*drvname);
+ *drvname = NULL;
return -1;
}
return 0;
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
index 0ff2377d..7d6e54f4 100644
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ b/lib/librte_eal/common/eal_common_vdev.c
@@ -111,6 +111,14 @@ rte_eal_vdev_uninit(const char *name)
return driver->remove(name);
}
+ /* Give new names precedence over aliases. */
+ TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+ if (driver->driver.alias &&
+ !strncmp(driver->driver.alias, name,
+ strlen(driver->driver.alias)))
+ return driver->remove(name);
+ }
+
RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
return -EINVAL;
}
diff --git a/lib/librte_eal/common/include/rte_version.h b/lib/librte_eal/common/include/rte_version.h
index da204e63..0de35fb7 100644
--- a/lib/librte_eal/common/include/rte_version.h
+++ b/lib/librte_eal/common/include/rte_version.h
@@ -66,7 +66,7 @@ extern "C" {
/**
* Patch level number i.e. the z in yy.mm.z
*/
-#define RTE_VER_MINOR 0
+#define RTE_VER_MINOR 1
/**
* Extra string to be appended to version number
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b754..3e4ffb57 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -133,7 +133,7 @@ pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num)
snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
dev = makedev(major, minor);
ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
- if (f == NULL) {
+ if (ret != 0) {
RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
__func__, strerror(errno));
return -1;
diff --git a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
index 00cf919b..fb4a2f84 100644
--- a/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
+++ b/lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c
@@ -301,6 +301,7 @@ vfio_mp_sync_thread(void __rte_unused * arg)
vfio_mp_sync_send_request(conn_sock, SOCKET_ERR);
else
vfio_mp_sync_send_fd(conn_sock, fd);
+ close(fd);
break;
case SOCKET_REQ_GROUP:
/* wait for group number */
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index fde8112f..5a317594 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -189,6 +189,20 @@ rte_eth_dev_find_free_port(void)
return RTE_MAX_ETHPORTS;
}
+static struct rte_eth_dev *
+eth_dev_get(uint8_t port_id)
+{
+ struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];
+
+ eth_dev->data = &rte_eth_dev_data[port_id];
+ eth_dev->attached = DEV_ATTACHED;
+
+ eth_dev_last_created_port = port_id;
+ nb_ports++;
+
+ return eth_dev;
+}
+
struct rte_eth_dev *
rte_eth_dev_allocate(const char *name)
{
@@ -210,13 +224,41 @@ rte_eth_dev_allocate(const char *name)
return NULL;
}
- eth_dev = &rte_eth_devices[port_id];
- eth_dev->data = &rte_eth_dev_data[port_id];
+ eth_dev = eth_dev_get(port_id);
snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
eth_dev->data->port_id = port_id;
- eth_dev->attached = DEV_ATTACHED;
- eth_dev_last_created_port = port_id;
- nb_ports++;
+
+ return eth_dev;
+}
+
+/*
+ * Attach to a port already registered by the primary process, which
+ * makes sure that the same device would have the same port id both
+ * in the primary and secondary process.
+ */
+static struct rte_eth_dev *
+eth_dev_attach_secondary(const char *name)
+{
+ uint8_t i;
+ struct rte_eth_dev *eth_dev;
+
+ if (rte_eth_dev_data == NULL)
+ rte_eth_dev_data_alloc();
+
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+ if (strcmp(rte_eth_dev_data[i].name, name) == 0)
+ break;
+ }
+ if (i == RTE_MAX_ETHPORTS) {
+ RTE_PMD_DEBUG_TRACE(
+ "device %s is not driven by the primary process\n",
+ name);
+ return NULL;
+ }
+
+ eth_dev = eth_dev_get(i);
+ RTE_ASSERT(eth_dev->data->port_id == i);
+
return eth_dev;
}
@@ -246,16 +288,28 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
sizeof(ethdev_name));
- eth_dev = rte_eth_dev_allocate(ethdev_name);
- if (eth_dev == NULL)
- return -ENOMEM;
-
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev = rte_eth_dev_allocate(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
eth_dev->data->dev_private = rte_zmalloc("ethdev private structure",
eth_drv->dev_private_size,
RTE_CACHE_LINE_SIZE);
if (eth_dev->data->dev_private == NULL)
rte_panic("Cannot allocate memzone for private port data\n");
+ } else {
+ eth_dev = eth_dev_attach_secondary(ethdev_name);
+ if (eth_dev == NULL) {
+ /*
+ * if we failed to attach a device, it means the
+ * device is skipped in primary process, due to
+ * some errors. If so, we return a positive value,
+ * to let EAL skip it for the secondary process
+ * as well.
+ */
+ return 1;
+ }
}
eth_dev->pci_dev = pci_dev;
eth_dev->driver = eth_drv;
@@ -376,6 +430,9 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)
return -EINVAL;
}
+ if (!nb_ports)
+ return -ENODEV;
+
*port_id = RTE_MAX_ETHPORTS;
for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
@@ -1343,8 +1400,10 @@ get_xstats_count(uint8_t port_id)
} else
count = 0;
count += RTE_NB_STATS;
- count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
- count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
+ count += RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS) *
+ RTE_NB_RXQ_STATS;
+ count += RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS) *
+ RTE_NB_TXQ_STATS;
return count;
}
@@ -1358,6 +1417,7 @@ rte_eth_xstats_get_names(uint8_t port_id,
int cnt_expected_entries;
int cnt_driver_entries;
uint32_t idx, id_queue;
+ uint16_t num_q;
cnt_expected_entries = get_xstats_count(port_id);
if (xstats_names == NULL || cnt_expected_entries < 0 ||
@@ -1374,7 +1434,8 @@ rte_eth_xstats_get_names(uint8_t port_id,
"%s", rte_stats_strings[idx].name);
cnt_used_entries++;
}
- for (id_queue = 0; id_queue < dev->data->nb_rx_queues; id_queue++) {
+ num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ for (id_queue = 0; id_queue < num_q; id_queue++) {
for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) {
snprintf(xstats_names[cnt_used_entries].name,
sizeof(xstats_names[0].name),
@@ -1384,7 +1445,8 @@ rte_eth_xstats_get_names(uint8_t port_id,
}
}
- for (id_queue = 0; id_queue < dev->data->nb_tx_queues; id_queue++) {
+ num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ for (id_queue = 0; id_queue < num_q; id_queue++) {
for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) {
snprintf(xstats_names[cnt_used_entries].name,
sizeof(xstats_names[0].name),
@@ -1420,14 +1482,18 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
unsigned count = 0, i, q;
signed xcount = 0;
uint64_t val, *stats_ptr;
+ uint16_t nb_rxqs, nb_txqs;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
dev = &rte_eth_devices[port_id];
+ nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+
/* Return generic statistics */
- count = RTE_NB_STATS + (dev->data->nb_rx_queues * RTE_NB_RXQ_STATS) +
- (dev->data->nb_tx_queues * RTE_NB_TXQ_STATS);
+ count = RTE_NB_STATS + (nb_rxqs * RTE_NB_RXQ_STATS) +
+ (nb_txqs * RTE_NB_TXQ_STATS);
/* implemented by the driver */
if (dev->dev_ops->xstats_get != NULL) {
@@ -1458,7 +1524,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
}
/* per-rxq stats */
- for (q = 0; q < dev->data->nb_rx_queues; q++) {
+ for (q = 0; q < nb_rxqs; q++) {
for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
stats_ptr = RTE_PTR_ADD(&eth_stats,
rte_rxq_stats_strings[i].offset +
@@ -1469,7 +1535,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
}
/* per-txq stats */
- for (q = 0; q < dev->data->nb_tx_queues; q++) {
+ for (q = 0; q < nb_txqs; q++) {
for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
stats_ptr = RTE_PTR_ADD(&eth_stats,
rte_txq_stats_strings[i].offset +
@@ -1479,8 +1545,11 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
}
}
- for (i = 0; i < count + xcount; i++)
+ for (i = 0; i < count; i++)
xstats[i].id = i;
+ /* add an offset to driver-specific stats */
+ for ( ; i < count + xcount; i++)
+ xstats[i].id += count;
return count + xcount;
}
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 72be66d8..fd622635 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -19,7 +19,6 @@ DPDK_2.2 {
rte_eth_dev_bypass_ver_show;
rte_eth_dev_bypass_wd_reset;
rte_eth_dev_bypass_wd_timeout_show;
- rte_eth_dev_callback_process;
rte_eth_dev_callback_register;
rte_eth_dev_callback_unregister;
rte_eth_dev_close;
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 440f3b1b..956ce04b 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -610,9 +610,7 @@ typedef void (rte_mempool_ctor_t)(struct rte_mempool *, void *);
* never be used. The access to the per-lcore table is of course
* faster than the multi-producer/consumer pool. The cache can be
* disabled if the cache_size argument is set to 0; it can be useful to
- * avoid losing objects in cache. Note that even if not used, the
- * memory space for cache is always reserved in a mempool structure,
- * except if CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE is set to 0.
+ * avoid losing objects in cache.
* @param private_data_size
* The size of the private data appended after the mempool
* structure. This is useful for storing some private data after the
diff --git a/lib/librte_mempool/rte_mempool_stack.c b/lib/librte_mempool/rte_mempool_stack.c
index 5fd8af24..817f77e6 100644
--- a/lib/librte_mempool/rte_mempool_stack.c
+++ b/lib/librte_mempool/rte_mempool_stack.c
@@ -118,7 +118,7 @@ stack_dequeue(struct rte_mempool *mp, void **obj_table,
s->len -= n;
rte_spinlock_unlock(&s->sl);
- return n;
+ return 0;
}
static unsigned
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index e6dace2f..614705d8 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -735,12 +735,14 @@ void
rte_sched_port_free(struct rte_sched_port *port)
{
uint32_t qindex;
- uint32_t n_queues_per_port = rte_sched_port_queues_per_port(port);
+ uint32_t n_queues_per_port;
/* Check user parameters */
if (port == NULL)
return;
+ n_queues_per_port = rte_sched_port_queues_per_port(port);
+
/* Free enqueued mbufs */
for (qindex = 0; qindex < n_queues_per_port; qindex++) {
struct rte_mbuf **mbufs = rte_sched_port_qbase(port, qindex);
diff --git a/lib/librte_vhost/fd_man.c b/lib/librte_vhost/fd_man.c
index 2d3eeb7d..8a075da2 100644
--- a/lib/librte_vhost/fd_man.c
+++ b/lib/librte_vhost/fd_man.c
@@ -35,93 +35,91 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
-#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
+#include <string.h>
#include <rte_common.h>
#include <rte_log.h>
#include "fd_man.h"
-/**
- * Returns the index in the fdset for a given fd.
- * If fd is -1, it means to search for a free entry.
- * @return
- * index for the fd, or -1 if fd isn't in the fdset.
- */
+#define FDPOLLERR (POLLERR | POLLHUP | POLLNVAL)
+
static int
-fdset_find_fd(struct fdset *pfdset, int fd)
+get_last_valid_idx(struct fdset *pfdset, int last_valid_idx)
{
int i;
- if (pfdset == NULL)
- return -1;
-
- for (i = 0; i < MAX_FDS && pfdset->fd[i].fd != fd; i++)
+ for (i = last_valid_idx; i >= 0 && pfdset->fd[i].fd == -1; i--)
;
- return i == MAX_FDS ? -1 : i;
+ return i;
}
-static int
-fdset_find_free_slot(struct fdset *pfdset)
+static void
+fdset_move(struct fdset *pfdset, int dst, int src)
{
- return fdset_find_fd(pfdset, -1);
+ pfdset->fd[dst] = pfdset->fd[src];
+ pfdset->rwfds[dst] = pfdset->rwfds[src];
}
-static int
-fdset_add_fd(struct fdset *pfdset, int idx, int fd,
- fd_cb rcb, fd_cb wcb, void *dat)
+/*
+ * Find deleted fd entries and remove them
+ */
+static void
+fdset_shrink(struct fdset *pfdset)
{
- struct fdentry *pfdentry;
+ int i;
+ int last_valid_idx = get_last_valid_idx(pfdset, pfdset->num - 1);
- if (pfdset == NULL || idx >= MAX_FDS || fd >= FD_SETSIZE)
- return -1;
+ pthread_mutex_lock(&pfdset->fd_mutex);
- pfdentry = &pfdset->fd[idx];
- pfdentry->fd = fd;
- pfdentry->rcb = rcb;
- pfdentry->wcb = wcb;
- pfdentry->dat = dat;
+ for (i = 0; i < last_valid_idx; i++) {
+ if (pfdset->fd[i].fd != -1)
+ continue;
- return 0;
+ fdset_move(pfdset, i, last_valid_idx);
+ last_valid_idx = get_last_valid_idx(pfdset, last_valid_idx - 1);
+ }
+ pfdset->num = last_valid_idx + 1;
+
+ pthread_mutex_unlock(&pfdset->fd_mutex);
}
/**
- * Fill the read/write fd_set with the fds in the fdset.
+ * Returns the index in the fdset for a given fd.
* @return
- * the maximum fds filled in the read/write fd_set.
+ * index for the fd, or -1 if fd isn't in the fdset.
*/
static int
-fdset_fill(fd_set *rfset, fd_set *wfset, struct fdset *pfdset)
+fdset_find_fd(struct fdset *pfdset, int fd)
{
- struct fdentry *pfdentry;
- int i, maxfds = -1;
- int num = MAX_FDS;
+ int i;
- if (pfdset == NULL)
- return -1;
+ for (i = 0; i < pfdset->num && pfdset->fd[i].fd != fd; i++)
+ ;
- for (i = 0; i < num; i++) {
- pfdentry = &pfdset->fd[i];
- if (pfdentry->fd != -1) {
- int added = 0;
- if (pfdentry->rcb && rfset) {
- FD_SET(pfdentry->fd, rfset);
- added = 1;
- }
- if (pfdentry->wcb && wfset) {
- FD_SET(pfdentry->fd, wfset);
- added = 1;
- }
- if (added)
- maxfds = pfdentry->fd < maxfds ?
- maxfds : pfdentry->fd;
- }
- }
- return maxfds;
+ return i == pfdset->num ? -1 : i;
+}
+
+static void
+fdset_add_fd(struct fdset *pfdset, int idx, int fd,
+ fd_cb rcb, fd_cb wcb, void *dat)
+{
+ struct fdentry *pfdentry = &pfdset->fd[idx];
+ struct pollfd *pfd = &pfdset->rwfds[idx];
+
+ pfdentry->fd = fd;
+ pfdentry->rcb = rcb;
+ pfdentry->wcb = wcb;
+ pfdentry->dat = dat;
+
+ pfd->fd = fd;
+ pfd->events = rcb ? POLLIN : 0;
+ pfd->events |= wcb ? POLLOUT : 0;
+ pfd->revents = 0;
}
void
@@ -151,16 +149,13 @@ fdset_add(struct fdset *pfdset, int fd, fd_cb rcb, fd_cb wcb, void *dat)
return -1;
pthread_mutex_lock(&pfdset->fd_mutex);
-
- /* Find a free slot in the list. */
- i = fdset_find_free_slot(pfdset);
- if (i == -1 || fdset_add_fd(pfdset, i, fd, rcb, wcb, dat) < 0) {
+ i = pfdset->num < MAX_FDS ? pfdset->num++ : -1;
+ if (i == -1) {
pthread_mutex_unlock(&pfdset->fd_mutex);
return -2;
}
- pfdset->num++;
-
+ fdset_add_fd(pfdset, i, fd, rcb, wcb, dat);
pthread_mutex_unlock(&pfdset->fd_mutex);
return 0;
@@ -189,7 +184,6 @@ fdset_del(struct fdset *pfdset, int fd)
pfdset->fd[i].fd = -1;
pfdset->fd[i].rcb = pfdset->fd[i].wcb = NULL;
pfdset->fd[i].dat = NULL;
- pfdset->num--;
i = -1;
}
pthread_mutex_unlock(&pfdset->fd_mutex);
@@ -198,24 +192,6 @@ fdset_del(struct fdset *pfdset, int fd)
return dat;
}
-/**
- * Unregister the fd at the specified slot from the fdset.
- */
-static void
-fdset_del_slot(struct fdset *pfdset, int index)
-{
- if (pfdset == NULL || index < 0 || index >= MAX_FDS)
- return;
-
- pthread_mutex_lock(&pfdset->fd_mutex);
-
- pfdset->fd[index].fd = -1;
- pfdset->fd[index].rcb = pfdset->fd[index].wcb = NULL;
- pfdset->fd[index].dat = NULL;
- pfdset->num--;
-
- pthread_mutex_unlock(&pfdset->fd_mutex);
-}
/**
* This functions runs in infinite blocking loop until there is no fd in
@@ -229,55 +205,64 @@ fdset_del_slot(struct fdset *pfdset, int index)
void
fdset_event_dispatch(struct fdset *pfdset)
{
- fd_set rfds, wfds;
- int i, maxfds;
+ int i;
+ struct pollfd *pfd;
struct fdentry *pfdentry;
- int num = MAX_FDS;
fd_cb rcb, wcb;
void *dat;
- int fd;
+ int fd, numfds;
int remove1, remove2;
- int ret;
+ int need_shrink;
if (pfdset == NULL)
return;
while (1) {
- struct timeval tv;
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- pthread_mutex_lock(&pfdset->fd_mutex);
-
- maxfds = fdset_fill(&rfds, &wfds, pfdset);
-
- pthread_mutex_unlock(&pfdset->fd_mutex);
/*
- * When select is blocked, other threads might unregister
+ * When poll is blocked, other threads might unregister
* listenfds from and register new listenfds into fdset.
- * When select returns, the entries for listenfds in the fdset
+ * When poll returns, the entries for listenfds in the fdset
* might have been updated. It is ok if there is unwanted call
* for new listenfds.
*/
- ret = select(maxfds + 1, &rfds, &wfds, NULL, &tv);
- if (ret <= 0)
- continue;
+ pthread_mutex_lock(&pfdset->fd_mutex);
+ numfds = pfdset->num;
+ pthread_mutex_unlock(&pfdset->fd_mutex);
- for (i = 0; i < num; i++) {
- remove1 = remove2 = 0;
+ poll(pfdset->rwfds, numfds, 1000 /* millisecs */);
+
+ need_shrink = 0;
+ for (i = 0; i < numfds; i++) {
pthread_mutex_lock(&pfdset->fd_mutex);
+
pfdentry = &pfdset->fd[i];
fd = pfdentry->fd;
+ pfd = &pfdset->rwfds[i];
+
+ if (fd < 0) {
+ need_shrink = 1;
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+ continue;
+ }
+
+ if (!pfd->revents) {
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+ continue;
+ }
+
+ remove1 = remove2 = 0;
+
rcb = pfdentry->rcb;
wcb = pfdentry->wcb;
dat = pfdentry->dat;
pfdentry->busy = 1;
+
pthread_mutex_unlock(&pfdset->fd_mutex);
- if (fd >= 0 && FD_ISSET(fd, &rfds) && rcb)
+
+ if (rcb && pfd->revents & (POLLIN | FDPOLLERR))
rcb(fd, dat, &remove1);
- if (fd >= 0 && FD_ISSET(fd, &wfds) && wcb)
+ if (wcb && pfd->revents & (POLLOUT | FDPOLLERR))
wcb(fd, dat, &remove2);
pfdentry->busy = 0;
/*
@@ -292,8 +277,13 @@ fdset_event_dispatch(struct fdset *pfdset)
* listen fd in another thread, we couldn't call
* fd_set_del.
*/
- if (remove1 || remove2)
- fdset_del_slot(pfdset, i);
+ if (remove1 || remove2) {
+ pfdentry->fd = -1;
+ need_shrink = 1;
+ }
}
+
+ if (need_shrink)
+ fdset_shrink(pfdset);
}
}
diff --git a/lib/librte_vhost/fd_man.h b/lib/librte_vhost/fd_man.h
index bd66ed1c..d319cac6 100644
--- a/lib/librte_vhost/fd_man.h
+++ b/lib/librte_vhost/fd_man.h
@@ -35,6 +35,7 @@
#define _FD_MAN_H_
#include <stdint.h>
#include <pthread.h>
+#include <poll.h>
#define MAX_FDS 1024
@@ -49,6 +50,7 @@ struct fdentry {
};
struct fdset {
+ struct pollfd rwfds[MAX_FDS];
struct fdentry fd[MAX_FDS];
pthread_mutex_t fd_mutex;
int num; /* current fd number of this fdset */
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 31825b82..e4150934 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -250,6 +250,7 @@ vhost_new_device(void)
if (i == MAX_VHOST_DEVICE) {
RTE_LOG(ERR, VHOST_CONFIG,
"Failed to find a free slot for new device.\n");
+ rte_free(dev);
return -1;
}
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 6b83c15f..0cb1c677 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -447,14 +447,14 @@ add_guest_pages(struct virtio_net *dev, struct virtio_memory_region *reg,
reg_size -= size;
while (reg_size > 0) {
+ size = RTE_MIN(reg_size, page_size);
host_phys_addr = rte_mem_virt2phy((void *)(uintptr_t)
host_user_addr);
- add_one_guest_page(dev, guest_phys_addr, host_phys_addr,
- page_size);
+ add_one_guest_page(dev, guest_phys_addr, host_phys_addr, size);
- host_user_addr += page_size;
- guest_phys_addr += page_size;
- reg_size -= page_size;
+ host_user_addr += size;
+ guest_phys_addr += size;
+ reg_size -= size;
}
}
@@ -567,7 +567,8 @@ vhost_user_set_mem_table(struct virtio_net *dev, struct VhostUserMsg *pmsg)
reg->host_user_addr = (uint64_t)(uintptr_t)mmap_addr +
mmap_offset;
- add_guest_pages(dev, reg, alignment);
+ if (dev->dequeue_zero_copy)
+ add_guest_pages(dev, reg, alignment);
RTE_LOG(INFO, VHOST_CONFIG,
"guest memory region %u, size: 0x%" PRIx64 "\n"
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 595f67c4..337470d6 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -195,6 +195,8 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vring_desc *descs,
struct vring_desc *desc;
uint64_t desc_addr;
struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0, 0, 0, 0, 0, 0}, 0};
+ /* A counter to avoid desc dead loop chain */
+ uint16_t nr_desc = 1;
desc = &descs[desc_idx];
desc_addr = gpa_to_vva(dev, desc->addr);
@@ -233,7 +235,7 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vring_desc *descs,
/* Room in vring buffer is not enough */
return -1;
}
- if (unlikely(desc->next >= size))
+ if (unlikely(desc->next >= size || ++nr_desc > size))
return -1;
desc = &descs[desc->next];
@@ -677,6 +679,7 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
default:
m->l3_len = 0;
*l4_proto = 0;
+ *l4_hdr = NULL;
break;
}
}
@@ -713,7 +716,7 @@ vhost_dequeue_offload(struct virtio_net_hdr *hdr, struct rte_mbuf *m)
}
}
- if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+ if (l4_hdr && hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
case VIRTIO_NET_HDR_GSO_TCPV4:
case VIRTIO_NET_HDR_GSO_TCPV6: