Skip to content

Commit

Permalink
ethdev: cleanup shared data with the last port
Browse files Browse the repository at this point in the history
If no port is allocated and no port owner is still registered,
ethdev from a primary process may release the memzone used to store
port data.
This makes it possible for the DPDK memory allocator to release
associated resources back to the OS.

Signed-off-by: David Marchand <[email protected]>
Acked-by: Morten Brørup <[email protected]>
  • Loading branch information
david-marchand authored and tmonjalo committed Oct 11, 2023
1 parent 7fe371e commit 36c46e7
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 1 deletion.
6 changes: 6 additions & 0 deletions lib/ethdev/ethdev_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ rte_eth_dev_allocate(const char *name)
eth_dev->data->backer_port_id = RTE_MAX_ETHPORTS;
eth_dev->data->mtu = RTE_ETHER_MTU;
pthread_mutex_init(&eth_dev->data->flow_ops_mutex, NULL);
RTE_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
eth_dev_shared_data->allocated_ports++;

unlock:
rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
Expand Down Expand Up @@ -265,6 +267,10 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
rte_free(eth_dev->data->dev_private);
pthread_mutex_destroy(&eth_dev->data->flow_ops_mutex);
memset(eth_dev->data, 0, sizeof(struct rte_eth_dev_data));
eth_dev->data = NULL;

eth_dev_shared_data->allocated_ports--;
eth_dev_shared_data_release();
}

rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
Expand Down
21 changes: 20 additions & 1 deletion lib/ethdev/ethdev_private.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";

static const struct rte_memzone *eth_dev_shared_mz;
struct eth_dev_shared *eth_dev_shared_data;

/* spinlock for eth device callbacks */
Expand Down Expand Up @@ -326,7 +327,7 @@ eth_dev_shared_data_prepare(void)
const unsigned int flags = 0;
const struct rte_memzone *mz;

if (eth_dev_shared_data == NULL) {
if (eth_dev_shared_mz == NULL) {
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
/* Allocate port data and ownership shared memory. */
mz = rte_memzone_reserve(MZ_RTE_ETH_DEV_DATA,
Expand All @@ -339,10 +340,13 @@ eth_dev_shared_data_prepare(void)
goto out;
}

eth_dev_shared_mz = mz;
eth_dev_shared_data = mz->addr;
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
eth_dev_shared_data->allocated_owners = 0;
eth_dev_shared_data->next_owner_id =
RTE_ETH_DEV_NO_OWNER + 1;
eth_dev_shared_data->allocated_ports = 0;
memset(eth_dev_shared_data->data, 0,
sizeof(eth_dev_shared_data->data));
}
Expand All @@ -351,6 +355,21 @@ eth_dev_shared_data_prepare(void)
return eth_dev_shared_data;
}

void
eth_dev_shared_data_release(void)
{
RTE_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);

if (eth_dev_shared_data->allocated_ports != 0)
return;
if (eth_dev_shared_data->allocated_owners != 0)
return;

rte_memzone_free(eth_dev_shared_mz);
eth_dev_shared_mz = NULL;
eth_dev_shared_data = NULL;
}

void
eth_dev_rxq_release(struct rte_eth_dev *dev, uint16_t qid)
{
Expand Down
4 changes: 4 additions & 0 deletions lib/ethdev/ethdev_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
#include "rte_ethdev.h"

struct eth_dev_shared {
uint64_t allocated_owners;
uint64_t next_owner_id;
uint64_t allocated_ports;
struct rte_eth_dev_data data[RTE_MAX_ETHPORTS];
};

Expand Down Expand Up @@ -69,6 +71,8 @@ void eth_dev_fp_ops_setup(struct rte_eth_fp_ops *fpo,

void *eth_dev_shared_data_prepare(void)
__rte_exclusive_locks_required(rte_mcfg_ethdev_get_lock());
void eth_dev_shared_data_release(void)
__rte_exclusive_locks_required(rte_mcfg_ethdev_get_lock());

void eth_dev_rxq_release(struct rte_eth_dev *dev, uint16_t qid);
void eth_dev_txq_release(struct rte_eth_dev *dev, uint16_t qid);
Expand Down
3 changes: 3 additions & 0 deletions lib/ethdev/rte_ethdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ rte_eth_dev_owner_new(uint64_t *owner_id)

if (eth_dev_shared_data_prepare() != NULL) {
*owner_id = eth_dev_shared_data->next_owner_id++;
eth_dev_shared_data->allocated_owners++;
ret = 0;
} else {
ret = -ENOMEM;
Expand Down Expand Up @@ -566,6 +567,8 @@ rte_eth_dev_owner_delete(const uint64_t owner_id)
RTE_ETHDEV_LOG(NOTICE,
"All port owners owned by %016"PRIx64" identifier have removed\n",
owner_id);
eth_dev_shared_data->allocated_owners--;
eth_dev_shared_data_release();
} else {
RTE_ETHDEV_LOG(ERR,
"Invalid owner ID=%016"PRIx64"\n",
Expand Down

0 comments on commit 36c46e7

Please sign in to comment.