From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f52.google.com (mail-wm0-f52.google.com [74.125.82.52]) by dpdk.org (Postfix) with ESMTP id 668C8374E for ; Fri, 30 Oct 2015 19:57:49 +0100 (CET) Received: by wmeg8 with SMTP id g8so18595966wme.0 for ; Fri, 30 Oct 2015 11:57:49 -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=8nFlgAOHDRm99yRm+uodw3oU6aGhT2tKOeDUsaN77jE=; b=hFIUSBxl0R8Jly1H7ZAxA+yXU+c7KnviBHJwHDbTgNlXjDN2H+tN7RdaV/gtcftq5M Ek+meJtvfaufL4I1Swa0H3jcm4ZzCOlqWgulzuREzjSgDLJqlIpcMW5kU1RYNRZDw9eC PKChQiRkIipsTiyRSOPiU/mzt+5ZDmvfgDFdoI1ms7iPQT8izyMa01SX9g24E4dbmX0c OKVbpxxT2xsXTMiypDAKL/x0RUtEf+oH6dro0vL1mbS+mZ/Spu2i4CughlVG3R1Vl5kY BSMjocdZ0zY5dDa00MXJ85UP7khZTXoCsccnLma7n0uiJb6Azks7LkveyAG4mcjZsMf+ 9HZg== 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=8nFlgAOHDRm99yRm+uodw3oU6aGhT2tKOeDUsaN77jE=; b=NY0rN1Qrys4YvoUAnagR1Wh5NGhK7CMwoZVc16WM2vmMenJKu8+GaU0+ERZ2CgIsN9 POMI+Mt0xUumRGA6GbGkJZhc4qVoQsKeWg2aqYhig0Ox3nRIVm3CAnUFZyXFxsbx9pUt K1hYLo9LndPs//n31inDvahCc0Nw8fAF9MJvhzYIqZyvAi5xPZAEjOrurH4qve3l8IPf 0mioCCQlnU9SRD9FO2F3h8dFAYJW8sLVh6JAWXVoe53+A3EhhyvOLzJadDDUBjqoxVVw ZpiCqPLPfzJXx7EVXj78AhhfQTrL0IV8gPJsOKGC2I4yQSzBr2k9aGTwHlzw3w9Zm2Vp GBeA== X-Gm-Message-State: ALoCoQnU8TMkSiKIkjyZEkS3Oe9lElzgStmXh8Q5KgJFia8VJMgw4Q4CjCqQaMxwMWSrcvg76H7N X-Received: by 10.28.137.211 with SMTP id l202mr5322742wmd.90.1446231469290; Fri, 30 Oct 2015 11:57:49 -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 l1sm4169949wmb.1.2015.10.30.11.57.48 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 30 Oct 2015 11:57:48 -0700 (PDT) From: Adrien Mazarguil To: dev@dpdk.org Date: Fri, 30 Oct 2015 19:57:22 +0100 Message-Id: <1446231443-8285-3-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 2/3] mlx4: 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:49 -0000 From: Nelio Laranjeiro Add interrupts handler for port status notification. Signed-off-by: Nelio Laranjeiro --- drivers/net/mlx4/mlx4.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/mlx4/mlx4.h | 3 + 2 files changed, 169 insertions(+) diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index af31573..cb08ee8 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -57,6 +57,7 @@ #include #include #include +#include /* Verbs header. */ /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ @@ -85,6 +86,7 @@ #include #include #include +#include #ifdef PEDANTIC #pragma GCC diagnostic error "-pedantic" #endif @@ -282,6 +284,7 @@ struct priv { unsigned int hw_csum_l2tun:1; /* Same for L2 tunnels. */ unsigned int rss:1; /* RSS is enabled. */ unsigned int vf:1; /* This is a VF device. */ + unsigned int pending_alarm:1; /* An alarm is pending. */ #ifdef INLINE_RECV unsigned int inl_recv_size; /* Inline recv size */ #endif @@ -292,6 +295,7 @@ struct priv { unsigned int txqs_n; /* TX queues array size. */ struct rxq *(*rxqs)[]; /* RX queues. */ struct txq *(*txqs)[]; /* TX queues. */ + struct rte_intr_handle intr_handle; /* Interrupt handler. */ rte_spinlock_t lock; /* Lock for control functions. */ }; @@ -3585,6 +3589,9 @@ mlx4_rx_queue_release(void *dpdk_rxq) priv_unlock(priv); } +static void +priv_dev_interrupt_handler_install(struct priv *, struct rte_eth_dev *); + /** * DPDK callback to start the device. * @@ -3646,6 +3653,7 @@ mlx4_dev_start(struct rte_eth_dev *dev) priv->started = 0; return -ret; } while ((--r) && ((rxq = (*priv->rxqs)[++i]), i)); + priv_dev_interrupt_handler_install(priv, dev); priv_unlock(priv); return 0; } @@ -3742,6 +3750,9 @@ removed_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) return 0; } +static void +priv_dev_interrupt_handler_uninstall(struct priv *, struct rte_eth_dev *); + /** * DPDK callback to close the device. * @@ -3802,6 +3813,7 @@ mlx4_dev_close(struct rte_eth_dev *dev) claim_zero(ibv_close_device(priv->ctx)); } else assert(priv->ctx == NULL); + priv_dev_interrupt_handler_uninstall(priv, dev); priv_unlock(priv); memset(priv, 0, sizeof(*priv)); } @@ -4693,6 +4705,158 @@ mlx4_getenv_int(const char *name) return atoi(val); } +static void +mlx4_dev_link_status_handler(void *); +static void +mlx4_dev_interrupt_handler(struct rte_intr_handle *, void *); + +/** + * 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; + mlx4_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(MLX4_ALARM_TIMEOUT_US, + mlx4_dev_link_status_handler, + dev); + } else + ret = 1; + } + return ret; +} + +/** + * Handle delayed link status event. + * + * @param arg + * Registered argument. + */ +static void +mlx4_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. + */ +static void +mlx4_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. + */ +static 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, + mlx4_dev_interrupt_handler, + dev); + if (priv->pending_alarm) + rte_eal_alarm_cancel(mlx4_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. + */ +static 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, + mlx4_dev_interrupt_handler, + dev); + } +} + static struct eth_driver mlx4_driver; /** @@ -4979,6 +5143,7 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) priv->dev = eth_dev; eth_dev->dev_ops = &mlx4_dev_ops; eth_dev->data->mac_addrs = priv->mac; + TAILQ_INIT(ð_dev->link_intr_cbs); /* Bring Ethernet device up. */ DEBUG("forcing Ethernet interface up"); @@ -5045,6 +5210,7 @@ static struct eth_driver mlx4_driver = { .name = MLX4_DRIVER_NAME, .id_table = mlx4_pci_id_map, .devinit = mlx4_pci_devinit, + .drv_flags = RTE_PCI_DRV_INTR_LSC, }, .dev_private_size = sizeof(struct priv) }; diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index 151c34b..d0c7bc2 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h @@ -83,6 +83,9 @@ #define MLX4_PMD_SOFT_COUNTERS 1 #endif +/* Alarm timeout. */ +#define MLX4_ALARM_TIMEOUT_US 100000 + enum { PCI_VENDOR_ID_MELLANOX = 0x15b3, }; -- 2.1.0