net/mana: support device removal interrupts
MANA supports PCI hot plug events. Add this interrupt to DPDK core so its parent PMD can detect device removal during Azure servicing or live migration. Signed-off-by: Long Li <longli@microsoft.com>
This commit is contained in:
parent
21958568c4
commit
bd15f237f2
@ -5,6 +5,7 @@
|
||||
;
|
||||
[Features]
|
||||
Link status = P
|
||||
Removal event = Y
|
||||
Multiprocess aware = Y
|
||||
Linux = Y
|
||||
x86-64 = Y
|
||||
|
@ -103,12 +103,18 @@ mana_dev_configure(struct rte_eth_dev *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mana_intr_uninstall(struct mana_priv *priv);
|
||||
|
||||
static int
|
||||
mana_dev_close(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct mana_priv *priv = dev->data->dev_private;
|
||||
int ret;
|
||||
|
||||
ret = mana_intr_uninstall(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ibv_close_device(priv->ib_ctx);
|
||||
if (ret) {
|
||||
ret = errno;
|
||||
@ -341,6 +347,96 @@ mana_ibv_device_to_pci_addr(const struct ibv_device *device,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handler from IB layer to notify this device is being removed.
|
||||
*/
|
||||
static void
|
||||
mana_intr_handler(void *arg)
|
||||
{
|
||||
struct mana_priv *priv = arg;
|
||||
struct ibv_context *ctx = priv->ib_ctx;
|
||||
struct ibv_async_event event;
|
||||
|
||||
/* Read and ack all messages from IB device */
|
||||
while (true) {
|
||||
if (ibv_get_async_event(ctx, &event))
|
||||
break;
|
||||
|
||||
if (event.event_type == IBV_EVENT_DEVICE_FATAL) {
|
||||
struct rte_eth_dev *dev;
|
||||
|
||||
dev = &rte_eth_devices[priv->port_id];
|
||||
if (dev->data->dev_conf.intr_conf.rmv)
|
||||
rte_eth_dev_callback_process(dev,
|
||||
RTE_ETH_EVENT_INTR_RMV, NULL);
|
||||
}
|
||||
|
||||
ibv_ack_async_event(&event);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
mana_intr_uninstall(struct mana_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rte_intr_callback_unregister(priv->intr_handle,
|
||||
mana_intr_handler, priv);
|
||||
if (ret <= 0) {
|
||||
DRV_LOG(ERR, "Failed to unregister intr callback ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rte_intr_instance_free(priv->intr_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mana_intr_install(struct mana_priv *priv)
|
||||
{
|
||||
int ret, flags;
|
||||
struct ibv_context *ctx = priv->ib_ctx;
|
||||
|
||||
priv->intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED);
|
||||
if (!priv->intr_handle) {
|
||||
DRV_LOG(ERR, "Failed to allocate intr_handle");
|
||||
rte_errno = ENOMEM;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rte_intr_fd_set(priv->intr_handle, -1);
|
||||
|
||||
flags = fcntl(ctx->async_fd, F_GETFL);
|
||||
ret = fcntl(ctx->async_fd, F_SETFL, flags | O_NONBLOCK);
|
||||
if (ret) {
|
||||
DRV_LOG(ERR, "Failed to change async_fd to NONBLOCK");
|
||||
goto free_intr;
|
||||
}
|
||||
|
||||
rte_intr_fd_set(priv->intr_handle, ctx->async_fd);
|
||||
rte_intr_type_set(priv->intr_handle, RTE_INTR_HANDLE_EXT);
|
||||
|
||||
ret = rte_intr_callback_register(priv->intr_handle,
|
||||
mana_intr_handler, priv);
|
||||
if (ret) {
|
||||
DRV_LOG(ERR, "Failed to register intr callback");
|
||||
rte_intr_fd_set(priv->intr_handle, -1);
|
||||
goto restore_fd;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
restore_fd:
|
||||
fcntl(ctx->async_fd, F_SETFL, flags);
|
||||
|
||||
free_intr:
|
||||
rte_intr_instance_free(priv->intr_handle);
|
||||
priv->intr_handle = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mana_proc_priv_init(struct rte_eth_dev *dev)
|
||||
{
|
||||
@ -623,6 +719,13 @@ mana_probe_port(struct ibv_device *ibdev, struct ibv_device_attr_ex *dev_attr,
|
||||
|
||||
rte_eth_copy_pci_info(eth_dev, pci_dev);
|
||||
|
||||
/* Create async interrupt handler */
|
||||
ret = mana_intr_install(priv);
|
||||
if (ret) {
|
||||
DRV_LOG(ERR, "Failed to install intr handler");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rte_spinlock_lock(&mana_shared_data->lock);
|
||||
mana_shared_data->primary_cnt++;
|
||||
rte_spinlock_unlock(&mana_shared_data->lock);
|
||||
|
@ -35,6 +35,7 @@ struct mana_priv {
|
||||
struct ibv_pd *ib_pd;
|
||||
struct ibv_pd *ib_parent_pd;
|
||||
void *db_page;
|
||||
struct rte_intr_handle *intr_handle;
|
||||
int max_rx_queues;
|
||||
int max_tx_queues;
|
||||
int max_rx_desc;
|
||||
|
Loading…
Reference in New Issue
Block a user