From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wi0-f169.google.com (mail-wi0-f169.google.com [209.85.212.169]) by dpdk.org (Postfix) with ESMTP id 4D990935A for ; Fri, 30 Oct 2015 19:57:52 +0100 (CET) Received: by wijp11 with SMTP id p11so17182657wij.0 for ; Fri, 30 Oct 2015 11:57:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind_com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=AxNEIlonvPiq4R4Yv42n48K7eiEIkKwfn2UgtoHOX20=; b=tTDwuRICS+QTOp85vdlKuDyFuqVKGAcscdhtku2CACW6ZeOUysMrO1FrtK0mP5FGCm 4g7WaCNRZAN4Se2oDDYto4P8Y9SXX+C/YpZQQ2x5g0Jk/K8WPGTQWwHb4pNUJMNJt9+G ZIDLUY3jvQgcVt0qX+02Fz5LCairtV6+TQl3FXt+1jXut0FHtQrtCMh6XDyqu8+Vna4z TS9n442t26EcRXcTmLDz8e125nsnJz9TS9E3QTFh7Fjfl6/jj+keVZ44KBrtgjRW0qqI 6ZKhaWe1maeOBfDUn5EpBg54HlE2SzEY2q00KrbjjxmCfCULlqopm598pFk01kCJuvvE o+7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=AxNEIlonvPiq4R4Yv42n48K7eiEIkKwfn2UgtoHOX20=; b=IRAuVm5nMsfmoWHdg2mmd6elt/iFzl0WybQtvuVKtQH/JwHRx+vkdyZnjUw5/ghAIh Oq+c9oztbCiJuZFWqIfD0d1eMbBy/KGYDrur6H55I+zH0uUnFnn9JFl0TXXug9ojsJXh OUCRAmrrMfryz0xJ16mY3u0ZwWiKuyT/vvYuCGkOP4FWfEIn22Pb/tkZ5oOXQxAGHY7i VyhqfoweT/zSx2/SynQ1EPqVSJFVE/kKdtPuoQHp3e+EaMcCAJK0lJU/lbtGWP+Uq2cj XsvjQ6lSOcO/Mm+6pngyjZKRQ+X1uOeKNGbfhenEEt967VymfVPergpv+VMf8gOdghi4 uW3A== X-Gm-Message-State: ALoCoQktELBs9cFW1U/TIDLUSXYlsHJ5PotDiCd7WRIBkPu+HM4eb9TlPRHLVyuB+lTw4gL42Eha X-Received: by 10.194.186.196 with SMTP id fm4mr12064995wjc.152.1446231472184; Fri, 30 Oct 2015 11:57:52 -0700 (PDT) Received: from 6wind.com (guy78-3-82-239-227-177.fbx.proxad.net. [82.239.227.177]) by smtp.gmail.com with ESMTPSA id jt9sm8398310wjc.24.2015.10.30.11.57.50 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 30 Oct 2015 11:57:51 -0700 (PDT) From: Adrien Mazarguil To: dev@dpdk.org Date: Fri, 30 Oct 2015 19:57:23 +0100 Message-Id: <1446231443-8285-4-git-send-email-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446231443-8285-1-git-send-email-adrien.mazarguil@6wind.com> References: <1444067795-29748-1-git-send-email-adrien.mazarguil@6wind.com> <1446231443-8285-1-git-send-email-adrien.mazarguil@6wind.com> Subject: [dpdk-dev] [PATCH v2 3/3] mlx5: handle interrupts X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Oct 2015 18:57:52 -0000 From: Nelio Laranjeiro Add interrupts handler for port status notification. Signed-off-by: Nelio Laranjeiro Signed-off-by: Adrien Mazarguil --- drivers/net/mlx5/mlx5.c | 3 + drivers/net/mlx5/mlx5.h | 7 ++ drivers/net/mlx5/mlx5_defs.h | 3 + drivers/net/mlx5/mlx5_ethdev.c | 150 ++++++++++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_trigger.c | 4 ++ 5 files changed, 167 insertions(+) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 97ce902..9636588 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -86,6 +86,7 @@ mlx5_dev_close(struct rte_eth_dev *dev) (void *)dev, ((priv->ctx != NULL) ? priv->ctx->device->name : "")); /* In case mlx5_dev_stop() has not been called. */ + priv_dev_interrupt_handler_uninstall(priv, dev); priv_allmulticast_disable(priv); priv_promiscuous_disable(priv); priv_mac_addrs_disable(priv); @@ -450,6 +451,7 @@ mlx5_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) priv->dev = eth_dev; eth_dev->dev_ops = &mlx5_dev_ops; eth_dev->data->mac_addrs = priv->mac; + TAILQ_INIT(ð_dev->link_intr_cbs); /* Bring Ethernet device up. */ DEBUG("forcing Ethernet interface up"); @@ -523,6 +525,7 @@ static struct eth_driver mlx5_driver = { .name = MLX5_DRIVER_NAME, .id_table = mlx5_pci_id_map, .devinit = mlx5_pci_devinit, + .drv_flags = RTE_PCI_DRV_INTR_LSC, }, .dev_private_size = sizeof(struct priv) }; diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 03e33d6..0daacc8 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -58,6 +58,7 @@ #include #include #include +#include #ifdef PEDANTIC #pragma GCC diagnostic error "-pedantic" #endif @@ -101,6 +102,7 @@ struct priv { unsigned int hw_csum:1; /* Checksum offload is supported. */ unsigned int hw_csum_l2tun:1; /* Same for L2 tunnels. */ unsigned int vf:1; /* This is a VF device. */ + unsigned int pending_alarm:1; /* An alarm is pending. */ /* RX/TX queues. */ unsigned int rxqs_n; /* RX queues array size. */ unsigned int txqs_n; /* TX queues array size. */ @@ -115,6 +117,7 @@ struct priv { unsigned int hash_rxqs_n; /* Hash RX QPs array size. */ /* RSS configuration array indexed by hash RX queue type. */ struct rte_eth_rss_conf *(*rss_conf)[]; + struct rte_intr_handle intr_handle; /* Interrupt handler. */ rte_spinlock_t lock; /* Lock for control functions. */ }; @@ -157,6 +160,10 @@ int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *); int mlx5_dev_set_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *); int mlx5_ibv_device_to_pci_addr(const struct ibv_device *, struct rte_pci_addr *); +void mlx5_dev_link_status_handler(void *); +void mlx5_dev_interrupt_handler(struct rte_intr_handle *, void *); +void priv_dev_interrupt_handler_uninstall(struct priv *, struct rte_eth_dev *); +void priv_dev_interrupt_handler_install(struct priv *, struct rte_eth_dev *); /* mlx5_mac.c */ diff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h index 3952c71..bb82c9a 100644 --- a/drivers/net/mlx5/mlx5_defs.h +++ b/drivers/net/mlx5/mlx5_defs.h @@ -78,4 +78,7 @@ #define MLX5_PMD_SOFT_COUNTERS 1 #endif +/* Alarm timeout. */ +#define MLX5_ALARM_TIMEOUT_US 100000 + #endif /* RTE_PMD_MLX5_DEFS_H_ */ diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index fac685e..84e877c 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -47,6 +47,7 @@ #include #include #include +#include /* DPDK headers don't like -pedantic. */ #ifdef PEDANTIC @@ -56,6 +57,8 @@ #include #include #include +#include +#include #ifdef PEDANTIC #pragma GCC diagnostic error "-pedantic" #endif @@ -790,3 +793,150 @@ mlx5_ibv_device_to_pci_addr(const struct ibv_device *device, fclose(file); return 0; } + +/** + * Link status handler. + * + * @param priv + * Pointer to private structure. + * @param dev + * Pointer to the rte_eth_dev structure. + * + * @return + * Nonzero if the callback process can be called immediately. + */ +static int +priv_dev_link_status_handler(struct priv *priv, struct rte_eth_dev *dev) +{ + struct ibv_async_event event; + int port_change = 0; + int ret = 0; + + /* Read all message and acknowledge them. */ + for (;;) { + if (ibv_get_async_event(priv->ctx, &event)) + break; + + if (event.event_type == IBV_EVENT_PORT_ACTIVE || + event.event_type == IBV_EVENT_PORT_ERR) + port_change = 1; + else + DEBUG("event type %d on port %d not handled", + event.event_type, event.element.port_num); + ibv_ack_async_event(&event); + } + + if (port_change ^ priv->pending_alarm) { + struct rte_eth_link *link = &dev->data->dev_link; + + priv->pending_alarm = 0; + mlx5_link_update_unlocked(dev, 0); + if (((link->link_speed == 0) && link->link_status) || + ((link->link_speed != 0) && !link->link_status)) { + /* Inconsistent status, check again later. */ + priv->pending_alarm = 1; + rte_eal_alarm_set(MLX5_ALARM_TIMEOUT_US, + mlx5_dev_link_status_handler, + dev); + } else + ret = 1; + } + return ret; +} + +/** + * Handle delayed link status event. + * + * @param arg + * Registered argument. + */ +void +mlx5_dev_link_status_handler(void *arg) +{ + struct rte_eth_dev *dev = arg; + struct priv *priv = dev->data->dev_private; + int ret; + + priv_lock(priv); + assert(priv->pending_alarm == 1); + ret = priv_dev_link_status_handler(priv, dev); + priv_unlock(priv); + if (ret) + _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC); +} + +/** + * Handle interrupts from the NIC. + * + * @param[in] intr_handle + * Interrupt handler. + * @param cb_arg + * Callback argument. + */ +void +mlx5_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg) +{ + struct rte_eth_dev *dev = cb_arg; + struct priv *priv = dev->data->dev_private; + int ret; + + (void)intr_handle; + priv_lock(priv); + ret = priv_dev_link_status_handler(priv, dev); + priv_unlock(priv); + if (ret) + _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC); +} + +/** + * Uninstall interrupt handler. + * + * @param priv + * Pointer to private structure. + * @param dev + * Pointer to the rte_eth_dev structure. + */ +void +priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev) +{ + if (!dev->data->dev_conf.intr_conf.lsc) + return; + rte_intr_callback_unregister(&priv->intr_handle, + mlx5_dev_interrupt_handler, + dev); + if (priv->pending_alarm) + rte_eal_alarm_cancel(mlx5_dev_link_status_handler, dev); + priv->pending_alarm = 0; + priv->intr_handle.fd = 0; + priv->intr_handle.type = 0; +} + +/** + * Install interrupt handler. + * + * @param priv + * Pointer to private structure. + * @param dev + * Pointer to the rte_eth_dev structure. + */ +void +priv_dev_interrupt_handler_install(struct priv *priv, struct rte_eth_dev *dev) +{ + int rc, flags; + + if (!dev->data->dev_conf.intr_conf.lsc) + return; + assert(priv->ctx->async_fd > 0); + flags = fcntl(priv->ctx->async_fd, F_GETFL); + rc = fcntl(priv->ctx->async_fd, F_SETFL, flags | O_NONBLOCK); + if (rc < 0) { + INFO("failed to change file descriptor async event queue"); + dev->data->dev_conf.intr_conf.lsc = 0; + } else { + priv->intr_handle.fd = priv->ctx->async_fd; + priv->intr_handle.type = RTE_INTR_HANDLE_EXT; + rte_intr_callback_register(&priv->intr_handle, + mlx5_dev_interrupt_handler, + dev); + } +} diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c index 68e00a0..ff1203d 100644 --- a/drivers/net/mlx5/mlx5_trigger.c +++ b/drivers/net/mlx5/mlx5_trigger.c @@ -37,6 +37,8 @@ #endif #include #include +#include +#include #ifdef PEDANTIC #pragma GCC diagnostic error "-pedantic" #endif @@ -87,6 +89,7 @@ mlx5_dev_start(struct rte_eth_dev *dev) priv_mac_addrs_disable(priv); priv_destroy_hash_rxqs(priv); } + priv_dev_interrupt_handler_install(priv, dev); priv_unlock(priv); return -err; } @@ -114,6 +117,7 @@ mlx5_dev_stop(struct rte_eth_dev *dev) priv_promiscuous_disable(priv); priv_mac_addrs_disable(priv); priv_destroy_hash_rxqs(priv); + priv_dev_interrupt_handler_uninstall(priv, dev); priv->started = 0; priv_unlock(priv); } -- 2.1.0