2019-08-02 08:59:09 +02:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
* Copyright (c) 2017 Red Hat, Inc.
|
2017-10-05 10:36:14 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef RTE_LIBRTE_VHOST_NUMA
|
|
|
|
#include <numaif.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <rte_tailq.h>
|
|
|
|
|
|
|
|
#include "iotlb.h"
|
|
|
|
#include "vhost.h"
|
|
|
|
|
|
|
|
struct vhost_iotlb_entry {
|
|
|
|
TAILQ_ENTRY(vhost_iotlb_entry) next;
|
|
|
|
|
|
|
|
uint64_t iova;
|
|
|
|
uint64_t uaddr;
|
|
|
|
uint64_t size;
|
|
|
|
uint8_t perm;
|
|
|
|
};
|
|
|
|
|
2017-10-05 10:36:15 +02:00
|
|
|
#define IOTLB_CACHE_SIZE 2048
|
|
|
|
|
2018-02-05 16:04:56 +01:00
|
|
|
static void
|
|
|
|
vhost_user_iotlb_cache_random_evict(struct vhost_virtqueue *vq);
|
|
|
|
|
2017-10-05 10:36:15 +02:00
|
|
|
static void
|
|
|
|
vhost_user_iotlb_pending_remove_all(struct vhost_virtqueue *vq)
|
|
|
|
{
|
|
|
|
struct vhost_iotlb_entry *node, *temp_node;
|
|
|
|
|
|
|
|
rte_rwlock_write_lock(&vq->iotlb_pending_lock);
|
|
|
|
|
eal: remove sys/queue.h from public headers
Currently there are some public headers that include 'sys/queue.h', which
is not POSIX, but usually provided by the Linux/BSD system library.
(Not in POSIX.1, POSIX.1-2001, or POSIX.1-2008. Present on the BSDs.)
The file is missing on Windows. During the Windows build, DPDK uses a
bundled copy, so building a DPDK library works fine. But when OVS or other
applications use DPDK as a library, because some DPDK public headers
include 'sys/queue.h', on Windows, it triggers an error due to no such
file.
One solution is to install the 'lib/eal/windows/include/sys/queue.h' into
Windows environment, such as [1]. However, this means DPDK exports the
functionalities of 'sys/queue.h' into the environment, which might cause
symbols, macros, headers clashing with other applications.
The patch fixes it by removing the "#include <sys/queue.h>" from
DPDK public headers, so programs including DPDK headers don't depend
on the system to provide 'sys/queue.h'. When these public headers use
macros such as TAILQ_xxx, we replace it by the ones with RTE_ prefix.
For Windows, we copy the definitions from <sys/queue.h> to rte_os.h
in Windows EAL. Note that these RTE_ macros are compatible with
<sys/queue.h>, both at the level of API (to use with <sys/queue.h>
macros in C files) and ABI (to avoid breaking it).
Additionally, the TAILQ_FOREACH_SAFE is not part of <sys/queue.h>,
the patch replaces it with RTE_TAILQ_FOREACH_SAFE.
[1] http://mails.dpdk.org/archives/dev/2021-August/216304.html
Suggested-by: Nick Connolly <nick.connolly@mayadata.io>
Suggested-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Signed-off-by: William Tu <u9012063@gmail.com>
Acked-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Acked-by: Narcisa Vasile <navasile@linux.microsoft.com>
2021-08-24 16:21:03 +00:00
|
|
|
RTE_TAILQ_FOREACH_SAFE(node, &vq->iotlb_pending_list, next, temp_node) {
|
2017-10-05 10:36:15 +02:00
|
|
|
TAILQ_REMOVE(&vq->iotlb_pending_list, node, next);
|
|
|
|
rte_mempool_put(vq->iotlb_pool, node);
|
|
|
|
}
|
|
|
|
|
|
|
|
rte_rwlock_write_unlock(&vq->iotlb_pending_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
vhost_user_iotlb_pending_miss(struct vhost_virtqueue *vq, uint64_t iova,
|
|
|
|
uint8_t perm)
|
|
|
|
{
|
|
|
|
struct vhost_iotlb_entry *node;
|
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
rte_rwlock_read_lock(&vq->iotlb_pending_lock);
|
|
|
|
|
|
|
|
TAILQ_FOREACH(node, &vq->iotlb_pending_list, next) {
|
|
|
|
if ((node->iova == iova) && (node->perm == perm)) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rte_rwlock_read_unlock(&vq->iotlb_pending_lock);
|
|
|
|
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-26 10:55:02 +01:00
|
|
|
vhost_user_iotlb_pending_insert(struct virtio_net *dev, struct vhost_virtqueue *vq,
|
2017-10-05 10:36:15 +02:00
|
|
|
uint64_t iova, uint8_t perm)
|
|
|
|
{
|
|
|
|
struct vhost_iotlb_entry *node;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
|
|
|
|
if (ret) {
|
vhost: prefix logs with context
We recently improved the log messages in the vhost library, adding some
context that helps filtering for a given vhost-user device.
However, some parts of the code were missed, and some later code changes
broke this new convention (fixes were sent previous to this patch).
Change the VHOST_LOG_CONFIG/DATA helpers and always ask for a string
used as context. This should help limit regressions on this topic.
Most of the time, the context is the vhost-user device socket path.
For the rest when a vhost-user device can not be related, generic
names were chosen:
- "dma", for vhost-user async DMA operations,
- "device", for vhost-user device creation and lookup,
- "thread", for threads management,
Signed-off-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
2022-07-01 15:20:56 +02:00
|
|
|
VHOST_LOG_CONFIG(dev->ifname, DEBUG,
|
|
|
|
"IOTLB pool %s empty, clear entries for pending insertion\n",
|
|
|
|
vq->iotlb_pool->name);
|
2018-02-05 16:04:56 +01:00
|
|
|
if (!TAILQ_EMPTY(&vq->iotlb_pending_list))
|
|
|
|
vhost_user_iotlb_pending_remove_all(vq);
|
|
|
|
else
|
|
|
|
vhost_user_iotlb_cache_random_evict(vq);
|
2017-10-05 10:36:15 +02:00
|
|
|
ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
|
|
|
|
if (ret) {
|
vhost: prefix logs with context
We recently improved the log messages in the vhost library, adding some
context that helps filtering for a given vhost-user device.
However, some parts of the code were missed, and some later code changes
broke this new convention (fixes were sent previous to this patch).
Change the VHOST_LOG_CONFIG/DATA helpers and always ask for a string
used as context. This should help limit regressions on this topic.
Most of the time, the context is the vhost-user device socket path.
For the rest when a vhost-user device can not be related, generic
names were chosen:
- "dma", for vhost-user async DMA operations,
- "device", for vhost-user device creation and lookup,
- "thread", for threads management,
Signed-off-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
2022-07-01 15:20:56 +02:00
|
|
|
VHOST_LOG_CONFIG(dev->ifname, ERR,
|
|
|
|
"IOTLB pool %s still empty, pending insertion failure\n",
|
|
|
|
vq->iotlb_pool->name);
|
2017-10-05 10:36:15 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
node->iova = iova;
|
|
|
|
node->perm = perm;
|
|
|
|
|
|
|
|
rte_rwlock_write_lock(&vq->iotlb_pending_lock);
|
|
|
|
|
|
|
|
TAILQ_INSERT_TAIL(&vq->iotlb_pending_list, node, next);
|
|
|
|
|
|
|
|
rte_rwlock_write_unlock(&vq->iotlb_pending_lock);
|
|
|
|
}
|
|
|
|
|
2018-02-05 16:04:57 +01:00
|
|
|
void
|
2017-10-05 10:36:15 +02:00
|
|
|
vhost_user_iotlb_pending_remove(struct vhost_virtqueue *vq,
|
|
|
|
uint64_t iova, uint64_t size, uint8_t perm)
|
|
|
|
{
|
|
|
|
struct vhost_iotlb_entry *node, *temp_node;
|
|
|
|
|
|
|
|
rte_rwlock_write_lock(&vq->iotlb_pending_lock);
|
|
|
|
|
eal: remove sys/queue.h from public headers
Currently there are some public headers that include 'sys/queue.h', which
is not POSIX, but usually provided by the Linux/BSD system library.
(Not in POSIX.1, POSIX.1-2001, or POSIX.1-2008. Present on the BSDs.)
The file is missing on Windows. During the Windows build, DPDK uses a
bundled copy, so building a DPDK library works fine. But when OVS or other
applications use DPDK as a library, because some DPDK public headers
include 'sys/queue.h', on Windows, it triggers an error due to no such
file.
One solution is to install the 'lib/eal/windows/include/sys/queue.h' into
Windows environment, such as [1]. However, this means DPDK exports the
functionalities of 'sys/queue.h' into the environment, which might cause
symbols, macros, headers clashing with other applications.
The patch fixes it by removing the "#include <sys/queue.h>" from
DPDK public headers, so programs including DPDK headers don't depend
on the system to provide 'sys/queue.h'. When these public headers use
macros such as TAILQ_xxx, we replace it by the ones with RTE_ prefix.
For Windows, we copy the definitions from <sys/queue.h> to rte_os.h
in Windows EAL. Note that these RTE_ macros are compatible with
<sys/queue.h>, both at the level of API (to use with <sys/queue.h>
macros in C files) and ABI (to avoid breaking it).
Additionally, the TAILQ_FOREACH_SAFE is not part of <sys/queue.h>,
the patch replaces it with RTE_TAILQ_FOREACH_SAFE.
[1] http://mails.dpdk.org/archives/dev/2021-August/216304.html
Suggested-by: Nick Connolly <nick.connolly@mayadata.io>
Suggested-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Signed-off-by: William Tu <u9012063@gmail.com>
Acked-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Acked-by: Narcisa Vasile <navasile@linux.microsoft.com>
2021-08-24 16:21:03 +00:00
|
|
|
RTE_TAILQ_FOREACH_SAFE(node, &vq->iotlb_pending_list, next,
|
|
|
|
temp_node) {
|
2017-10-05 10:36:15 +02:00
|
|
|
if (node->iova < iova)
|
|
|
|
continue;
|
|
|
|
if (node->iova >= iova + size)
|
|
|
|
continue;
|
|
|
|
if ((node->perm & perm) != node->perm)
|
|
|
|
continue;
|
|
|
|
TAILQ_REMOVE(&vq->iotlb_pending_list, node, next);
|
|
|
|
rte_mempool_put(vq->iotlb_pool, node);
|
|
|
|
}
|
|
|
|
|
|
|
|
rte_rwlock_write_unlock(&vq->iotlb_pending_lock);
|
|
|
|
}
|
2017-10-05 10:36:14 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
vhost_user_iotlb_cache_remove_all(struct vhost_virtqueue *vq)
|
|
|
|
{
|
|
|
|
struct vhost_iotlb_entry *node, *temp_node;
|
|
|
|
|
|
|
|
rte_rwlock_write_lock(&vq->iotlb_lock);
|
|
|
|
|
eal: remove sys/queue.h from public headers
Currently there are some public headers that include 'sys/queue.h', which
is not POSIX, but usually provided by the Linux/BSD system library.
(Not in POSIX.1, POSIX.1-2001, or POSIX.1-2008. Present on the BSDs.)
The file is missing on Windows. During the Windows build, DPDK uses a
bundled copy, so building a DPDK library works fine. But when OVS or other
applications use DPDK as a library, because some DPDK public headers
include 'sys/queue.h', on Windows, it triggers an error due to no such
file.
One solution is to install the 'lib/eal/windows/include/sys/queue.h' into
Windows environment, such as [1]. However, this means DPDK exports the
functionalities of 'sys/queue.h' into the environment, which might cause
symbols, macros, headers clashing with other applications.
The patch fixes it by removing the "#include <sys/queue.h>" from
DPDK public headers, so programs including DPDK headers don't depend
on the system to provide 'sys/queue.h'. When these public headers use
macros such as TAILQ_xxx, we replace it by the ones with RTE_ prefix.
For Windows, we copy the definitions from <sys/queue.h> to rte_os.h
in Windows EAL. Note that these RTE_ macros are compatible with
<sys/queue.h>, both at the level of API (to use with <sys/queue.h>
macros in C files) and ABI (to avoid breaking it).
Additionally, the TAILQ_FOREACH_SAFE is not part of <sys/queue.h>,
the patch replaces it with RTE_TAILQ_FOREACH_SAFE.
[1] http://mails.dpdk.org/archives/dev/2021-August/216304.html
Suggested-by: Nick Connolly <nick.connolly@mayadata.io>
Suggested-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Signed-off-by: William Tu <u9012063@gmail.com>
Acked-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Acked-by: Narcisa Vasile <navasile@linux.microsoft.com>
2021-08-24 16:21:03 +00:00
|
|
|
RTE_TAILQ_FOREACH_SAFE(node, &vq->iotlb_list, next, temp_node) {
|
2017-10-05 10:36:14 +02:00
|
|
|
TAILQ_REMOVE(&vq->iotlb_list, node, next);
|
|
|
|
rte_mempool_put(vq->iotlb_pool, node);
|
|
|
|
}
|
|
|
|
|
|
|
|
vq->iotlb_cache_nr = 0;
|
|
|
|
|
|
|
|
rte_rwlock_write_unlock(&vq->iotlb_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vhost_user_iotlb_cache_random_evict(struct vhost_virtqueue *vq)
|
|
|
|
{
|
|
|
|
struct vhost_iotlb_entry *node, *temp_node;
|
|
|
|
int entry_idx;
|
|
|
|
|
|
|
|
rte_rwlock_write_lock(&vq->iotlb_lock);
|
|
|
|
|
|
|
|
entry_idx = rte_rand() % vq->iotlb_cache_nr;
|
|
|
|
|
eal: remove sys/queue.h from public headers
Currently there are some public headers that include 'sys/queue.h', which
is not POSIX, but usually provided by the Linux/BSD system library.
(Not in POSIX.1, POSIX.1-2001, or POSIX.1-2008. Present on the BSDs.)
The file is missing on Windows. During the Windows build, DPDK uses a
bundled copy, so building a DPDK library works fine. But when OVS or other
applications use DPDK as a library, because some DPDK public headers
include 'sys/queue.h', on Windows, it triggers an error due to no such
file.
One solution is to install the 'lib/eal/windows/include/sys/queue.h' into
Windows environment, such as [1]. However, this means DPDK exports the
functionalities of 'sys/queue.h' into the environment, which might cause
symbols, macros, headers clashing with other applications.
The patch fixes it by removing the "#include <sys/queue.h>" from
DPDK public headers, so programs including DPDK headers don't depend
on the system to provide 'sys/queue.h'. When these public headers use
macros such as TAILQ_xxx, we replace it by the ones with RTE_ prefix.
For Windows, we copy the definitions from <sys/queue.h> to rte_os.h
in Windows EAL. Note that these RTE_ macros are compatible with
<sys/queue.h>, both at the level of API (to use with <sys/queue.h>
macros in C files) and ABI (to avoid breaking it).
Additionally, the TAILQ_FOREACH_SAFE is not part of <sys/queue.h>,
the patch replaces it with RTE_TAILQ_FOREACH_SAFE.
[1] http://mails.dpdk.org/archives/dev/2021-August/216304.html
Suggested-by: Nick Connolly <nick.connolly@mayadata.io>
Suggested-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Signed-off-by: William Tu <u9012063@gmail.com>
Acked-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Acked-by: Narcisa Vasile <navasile@linux.microsoft.com>
2021-08-24 16:21:03 +00:00
|
|
|
RTE_TAILQ_FOREACH_SAFE(node, &vq->iotlb_list, next, temp_node) {
|
2017-10-05 10:36:14 +02:00
|
|
|
if (!entry_idx) {
|
|
|
|
TAILQ_REMOVE(&vq->iotlb_list, node, next);
|
|
|
|
rte_mempool_put(vq->iotlb_pool, node);
|
|
|
|
vq->iotlb_cache_nr--;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
entry_idx--;
|
|
|
|
}
|
|
|
|
|
|
|
|
rte_rwlock_write_unlock(&vq->iotlb_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-01-26 10:55:02 +01:00
|
|
|
vhost_user_iotlb_cache_insert(struct virtio_net *dev, struct vhost_virtqueue *vq,
|
|
|
|
uint64_t iova, uint64_t uaddr,
|
|
|
|
uint64_t size, uint8_t perm)
|
2017-10-05 10:36:14 +02:00
|
|
|
{
|
|
|
|
struct vhost_iotlb_entry *node, *new_node;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
|
|
|
|
if (ret) {
|
vhost: prefix logs with context
We recently improved the log messages in the vhost library, adding some
context that helps filtering for a given vhost-user device.
However, some parts of the code were missed, and some later code changes
broke this new convention (fixes were sent previous to this patch).
Change the VHOST_LOG_CONFIG/DATA helpers and always ask for a string
used as context. This should help limit regressions on this topic.
Most of the time, the context is the vhost-user device socket path.
For the rest when a vhost-user device can not be related, generic
names were chosen:
- "dma", for vhost-user async DMA operations,
- "device", for vhost-user device creation and lookup,
- "thread", for threads management,
Signed-off-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
2022-07-01 15:20:56 +02:00
|
|
|
VHOST_LOG_CONFIG(dev->ifname, DEBUG,
|
|
|
|
"IOTLB pool %s empty, clear entries for cache insertion\n",
|
|
|
|
vq->iotlb_pool->name);
|
2018-02-05 16:04:56 +01:00
|
|
|
if (!TAILQ_EMPTY(&vq->iotlb_list))
|
|
|
|
vhost_user_iotlb_cache_random_evict(vq);
|
|
|
|
else
|
|
|
|
vhost_user_iotlb_pending_remove_all(vq);
|
2017-10-05 10:36:14 +02:00
|
|
|
ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
|
|
|
|
if (ret) {
|
vhost: prefix logs with context
We recently improved the log messages in the vhost library, adding some
context that helps filtering for a given vhost-user device.
However, some parts of the code were missed, and some later code changes
broke this new convention (fixes were sent previous to this patch).
Change the VHOST_LOG_CONFIG/DATA helpers and always ask for a string
used as context. This should help limit regressions on this topic.
Most of the time, the context is the vhost-user device socket path.
For the rest when a vhost-user device can not be related, generic
names were chosen:
- "dma", for vhost-user async DMA operations,
- "device", for vhost-user device creation and lookup,
- "thread", for threads management,
Signed-off-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
2022-07-01 15:20:56 +02:00
|
|
|
VHOST_LOG_CONFIG(dev->ifname, ERR,
|
|
|
|
"IOTLB pool %s still empty, cache insertion failed\n",
|
|
|
|
vq->iotlb_pool->name);
|
2017-10-05 10:36:14 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
new_node->iova = iova;
|
|
|
|
new_node->uaddr = uaddr;
|
|
|
|
new_node->size = size;
|
|
|
|
new_node->perm = perm;
|
|
|
|
|
|
|
|
rte_rwlock_write_lock(&vq->iotlb_lock);
|
|
|
|
|
|
|
|
TAILQ_FOREACH(node, &vq->iotlb_list, next) {
|
|
|
|
/*
|
|
|
|
* Entries must be invalidated before being updated.
|
|
|
|
* So if iova already in list, assume identical.
|
|
|
|
*/
|
|
|
|
if (node->iova == new_node->iova) {
|
|
|
|
rte_mempool_put(vq->iotlb_pool, new_node);
|
|
|
|
goto unlock;
|
|
|
|
} else if (node->iova > new_node->iova) {
|
|
|
|
TAILQ_INSERT_BEFORE(node, new_node, next);
|
|
|
|
vq->iotlb_cache_nr++;
|
|
|
|
goto unlock;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TAILQ_INSERT_TAIL(&vq->iotlb_list, new_node, next);
|
|
|
|
vq->iotlb_cache_nr++;
|
|
|
|
|
|
|
|
unlock:
|
2017-10-05 10:36:15 +02:00
|
|
|
vhost_user_iotlb_pending_remove(vq, iova, size, perm);
|
|
|
|
|
2017-10-05 10:36:14 +02:00
|
|
|
rte_rwlock_write_unlock(&vq->iotlb_lock);
|
2017-10-05 10:36:15 +02:00
|
|
|
|
2017-10-05 10:36:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
vhost_user_iotlb_cache_remove(struct vhost_virtqueue *vq,
|
|
|
|
uint64_t iova, uint64_t size)
|
|
|
|
{
|
|
|
|
struct vhost_iotlb_entry *node, *temp_node;
|
|
|
|
|
|
|
|
if (unlikely(!size))
|
|
|
|
return;
|
|
|
|
|
|
|
|
rte_rwlock_write_lock(&vq->iotlb_lock);
|
|
|
|
|
eal: remove sys/queue.h from public headers
Currently there are some public headers that include 'sys/queue.h', which
is not POSIX, but usually provided by the Linux/BSD system library.
(Not in POSIX.1, POSIX.1-2001, or POSIX.1-2008. Present on the BSDs.)
The file is missing on Windows. During the Windows build, DPDK uses a
bundled copy, so building a DPDK library works fine. But when OVS or other
applications use DPDK as a library, because some DPDK public headers
include 'sys/queue.h', on Windows, it triggers an error due to no such
file.
One solution is to install the 'lib/eal/windows/include/sys/queue.h' into
Windows environment, such as [1]. However, this means DPDK exports the
functionalities of 'sys/queue.h' into the environment, which might cause
symbols, macros, headers clashing with other applications.
The patch fixes it by removing the "#include <sys/queue.h>" from
DPDK public headers, so programs including DPDK headers don't depend
on the system to provide 'sys/queue.h'. When these public headers use
macros such as TAILQ_xxx, we replace it by the ones with RTE_ prefix.
For Windows, we copy the definitions from <sys/queue.h> to rte_os.h
in Windows EAL. Note that these RTE_ macros are compatible with
<sys/queue.h>, both at the level of API (to use with <sys/queue.h>
macros in C files) and ABI (to avoid breaking it).
Additionally, the TAILQ_FOREACH_SAFE is not part of <sys/queue.h>,
the patch replaces it with RTE_TAILQ_FOREACH_SAFE.
[1] http://mails.dpdk.org/archives/dev/2021-August/216304.html
Suggested-by: Nick Connolly <nick.connolly@mayadata.io>
Suggested-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Signed-off-by: William Tu <u9012063@gmail.com>
Acked-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Acked-by: Narcisa Vasile <navasile@linux.microsoft.com>
2021-08-24 16:21:03 +00:00
|
|
|
RTE_TAILQ_FOREACH_SAFE(node, &vq->iotlb_list, next, temp_node) {
|
2017-10-05 10:36:14 +02:00
|
|
|
/* Sorted list */
|
|
|
|
if (unlikely(iova + size < node->iova))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (iova < node->iova + node->size) {
|
|
|
|
TAILQ_REMOVE(&vq->iotlb_list, node, next);
|
|
|
|
rte_mempool_put(vq->iotlb_pool, node);
|
|
|
|
vq->iotlb_cache_nr--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rte_rwlock_write_unlock(&vq->iotlb_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
vhost_user_iotlb_cache_find(struct vhost_virtqueue *vq, uint64_t iova,
|
|
|
|
uint64_t *size, uint8_t perm)
|
|
|
|
{
|
|
|
|
struct vhost_iotlb_entry *node;
|
|
|
|
uint64_t offset, vva = 0, mapped = 0;
|
|
|
|
|
|
|
|
if (unlikely(!*size))
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
TAILQ_FOREACH(node, &vq->iotlb_list, next) {
|
|
|
|
/* List sorted by iova */
|
|
|
|
if (unlikely(iova < node->iova))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (iova >= node->iova + node->size)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (unlikely((perm & node->perm) != perm)) {
|
|
|
|
vva = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
offset = iova - node->iova;
|
|
|
|
if (!vva)
|
|
|
|
vva = node->uaddr + offset;
|
|
|
|
|
|
|
|
mapped += node->size - offset;
|
|
|
|
iova = node->iova + node->size;
|
|
|
|
|
|
|
|
if (mapped >= *size)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
/* Only part of the requested chunk is mapped */
|
|
|
|
if (unlikely(mapped < *size))
|
|
|
|
*size = mapped;
|
|
|
|
|
|
|
|
return vva;
|
|
|
|
}
|
|
|
|
|
2018-08-02 19:21:22 +02:00
|
|
|
void
|
|
|
|
vhost_user_iotlb_flush_all(struct vhost_virtqueue *vq)
|
|
|
|
{
|
|
|
|
vhost_user_iotlb_cache_remove_all(vq);
|
|
|
|
vhost_user_iotlb_pending_remove_all(vq);
|
|
|
|
}
|
|
|
|
|
2017-10-05 10:36:14 +02:00
|
|
|
int
|
|
|
|
vhost_user_iotlb_init(struct virtio_net *dev, int vq_index)
|
|
|
|
{
|
|
|
|
char pool_name[RTE_MEMPOOL_NAMESIZE];
|
|
|
|
struct vhost_virtqueue *vq = dev->virtqueue[vq_index];
|
vhost: fix false-positive warning from clang 5
When compiling with clang extra warning flags, such as used by default with
meson, a warning is given in iotlb.c:
lib/librte_vhost/iotlb.c:318:6: warning:
variable 'socket' is used uninitialized whenever
'if' condition is false [-Wsometimes-uninitialized]
This is a false positive, as the socket value will be initialized by the
call to get_mempolicy in the case where the NUMA build-time flag is set,
and in cases where it is not set, "if (ret)" will always be true as ret is
initialized to -1 and never changed.
However, this is not immediately obvious, and is perhaps a little fragile,
as it will break if other code using ret is subsequently added above the
call to get_mempolicy by someone unaware of this subtle dependency.
Therefore, we can fix the warning and making the code more robust by
explicitly initializing socket to zero, and moving the extra condition
check on the return from get_mempolicy() into the #ifdef
Fixes: d012d1f293f4 ("vhost: add IOTLB helper functions")
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
2017-10-11 12:28:17 +01:00
|
|
|
int socket = 0;
|
2017-10-05 10:36:14 +02:00
|
|
|
|
|
|
|
if (vq->iotlb_pool) {
|
|
|
|
/*
|
|
|
|
* The cache has already been initialized,
|
2017-10-05 10:36:15 +02:00
|
|
|
* just drop all cached and pending entries.
|
2017-10-05 10:36:14 +02:00
|
|
|
*/
|
2018-08-02 19:21:22 +02:00
|
|
|
vhost_user_iotlb_flush_all(vq);
|
2017-10-05 10:36:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef RTE_LIBRTE_VHOST_NUMA
|
vhost: fix false-positive warning from clang 5
When compiling with clang extra warning flags, such as used by default with
meson, a warning is given in iotlb.c:
lib/librte_vhost/iotlb.c:318:6: warning:
variable 'socket' is used uninitialized whenever
'if' condition is false [-Wsometimes-uninitialized]
This is a false positive, as the socket value will be initialized by the
call to get_mempolicy in the case where the NUMA build-time flag is set,
and in cases where it is not set, "if (ret)" will always be true as ret is
initialized to -1 and never changed.
However, this is not immediately obvious, and is perhaps a little fragile,
as it will break if other code using ret is subsequently added above the
call to get_mempolicy by someone unaware of this subtle dependency.
Therefore, we can fix the warning and making the code more robust by
explicitly initializing socket to zero, and moving the extra condition
check on the return from get_mempolicy() into the #ifdef
Fixes: d012d1f293f4 ("vhost: add IOTLB helper functions")
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
2017-10-11 12:28:17 +01:00
|
|
|
if (get_mempolicy(&socket, NULL, 0, vq, MPOL_F_NODE | MPOL_F_ADDR) != 0)
|
2017-10-05 10:36:14 +02:00
|
|
|
socket = 0;
|
vhost: fix false-positive warning from clang 5
When compiling with clang extra warning flags, such as used by default with
meson, a warning is given in iotlb.c:
lib/librte_vhost/iotlb.c:318:6: warning:
variable 'socket' is used uninitialized whenever
'if' condition is false [-Wsometimes-uninitialized]
This is a false positive, as the socket value will be initialized by the
call to get_mempolicy in the case where the NUMA build-time flag is set,
and in cases where it is not set, "if (ret)" will always be true as ret is
initialized to -1 and never changed.
However, this is not immediately obvious, and is perhaps a little fragile,
as it will break if other code using ret is subsequently added above the
call to get_mempolicy by someone unaware of this subtle dependency.
Therefore, we can fix the warning and making the code more robust by
explicitly initializing socket to zero, and moving the extra condition
check on the return from get_mempolicy() into the #ifdef
Fixes: d012d1f293f4 ("vhost: add IOTLB helper functions")
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
2017-10-11 12:28:17 +01:00
|
|
|
#endif
|
2017-10-05 10:36:14 +02:00
|
|
|
|
|
|
|
rte_rwlock_init(&vq->iotlb_lock);
|
2017-10-05 10:36:15 +02:00
|
|
|
rte_rwlock_init(&vq->iotlb_pending_lock);
|
2017-10-05 10:36:14 +02:00
|
|
|
|
|
|
|
TAILQ_INIT(&vq->iotlb_list);
|
2017-10-05 10:36:15 +02:00
|
|
|
TAILQ_INIT(&vq->iotlb_pending_list);
|
2017-10-05 10:36:14 +02:00
|
|
|
|
2020-03-12 08:19:18 +09:00
|
|
|
snprintf(pool_name, sizeof(pool_name), "iotlb_%u_%d_%d",
|
|
|
|
getpid(), dev->vid, vq_index);
|
vhost: prefix logs with context
We recently improved the log messages in the vhost library, adding some
context that helps filtering for a given vhost-user device.
However, some parts of the code were missed, and some later code changes
broke this new convention (fixes were sent previous to this patch).
Change the VHOST_LOG_CONFIG/DATA helpers and always ask for a string
used as context. This should help limit regressions on this topic.
Most of the time, the context is the vhost-user device socket path.
For the rest when a vhost-user device can not be related, generic
names were chosen:
- "dma", for vhost-user async DMA operations,
- "device", for vhost-user device creation and lookup,
- "thread", for threads management,
Signed-off-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
2022-07-01 15:20:56 +02:00
|
|
|
VHOST_LOG_CONFIG(dev->ifname, DEBUG, "IOTLB cache name: %s\n", pool_name);
|
2017-10-05 10:36:14 +02:00
|
|
|
|
|
|
|
/* If already created, free it and recreate */
|
|
|
|
vq->iotlb_pool = rte_mempool_lookup(pool_name);
|
2022-02-09 11:17:15 -08:00
|
|
|
rte_mempool_free(vq->iotlb_pool);
|
2017-10-05 10:36:14 +02:00
|
|
|
|
|
|
|
vq->iotlb_pool = rte_mempool_create(pool_name,
|
|
|
|
IOTLB_CACHE_SIZE, sizeof(struct vhost_iotlb_entry), 0,
|
|
|
|
0, 0, NULL, NULL, NULL, socket,
|
2021-10-19 20:40:18 +03:00
|
|
|
RTE_MEMPOOL_F_NO_CACHE_ALIGN |
|
|
|
|
RTE_MEMPOOL_F_SP_PUT);
|
2017-10-05 10:36:14 +02:00
|
|
|
if (!vq->iotlb_pool) {
|
vhost: prefix logs with context
We recently improved the log messages in the vhost library, adding some
context that helps filtering for a given vhost-user device.
However, some parts of the code were missed, and some later code changes
broke this new convention (fixes were sent previous to this patch).
Change the VHOST_LOG_CONFIG/DATA helpers and always ask for a string
used as context. This should help limit regressions on this topic.
Most of the time, the context is the vhost-user device socket path.
For the rest when a vhost-user device can not be related, generic
names were chosen:
- "dma", for vhost-user async DMA operations,
- "device", for vhost-user device creation and lookup,
- "thread", for threads management,
Signed-off-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
2022-07-01 15:20:56 +02:00
|
|
|
VHOST_LOG_CONFIG(dev->ifname, ERR, "Failed to create IOTLB cache pool %s\n",
|
|
|
|
pool_name);
|
2017-10-05 10:36:14 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
vq->iotlb_cache_nr = 0;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|