get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/13299/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 13299,
    "url": "http://patches.dpdk.org/api/patches/13299/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1465282390-6025-9-git-send-email-zhe.tao@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1465282390-6025-9-git-send-email-zhe.tao@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1465282390-6025-9-git-send-email-zhe.tao@intel.com",
    "date": "2016-06-07T06:53:10",
    "name": "[dpdk-dev,v4,8/8] i40e: implement device reset on VF",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "13682fef17cba13dba878a1c7316067c25ebefb9",
    "submitter": {
        "id": 276,
        "url": "http://patches.dpdk.org/api/people/276/?format=api",
        "name": "Zhe Tao",
        "email": "zhe.tao@intel.com"
    },
    "delegate": {
        "id": 10,
        "url": "http://patches.dpdk.org/api/users/10/?format=api",
        "username": "bruce",
        "first_name": "Bruce",
        "last_name": "Richardson",
        "email": "bruce.richardson@intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1465282390-6025-9-git-send-email-zhe.tao@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/13299/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/13299/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id B999495D4;\n\tTue,  7 Jun 2016 08:53:44 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id A499E91B8\n\tfor <dev@dpdk.org>; Tue,  7 Jun 2016 08:53:42 +0200 (CEST)",
            "from orsmga003.jf.intel.com ([10.7.209.27])\n\tby orsmga101.jf.intel.com with ESMTP; 06 Jun 2016 23:53:42 -0700",
            "from shvmail01.sh.intel.com ([10.239.29.42])\n\tby orsmga003.jf.intel.com with ESMTP; 06 Jun 2016 23:53:41 -0700",
            "from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com\n\t[10.239.29.89])\n\tby shvmail01.sh.intel.com with ESMTP id u576rcuo008797;\n\tTue, 7 Jun 2016 14:53:38 +0800",
            "from shecgisg004.sh.intel.com (localhost [127.0.0.1])\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP\n\tid u576rZ8G006116; Tue, 7 Jun 2016 14:53:37 +0800",
            "(from zhetao@localhost)\n\tby shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id u576rZlS006112; \n\tTue, 7 Jun 2016 14:53:35 +0800"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.26,432,1459839600\"; d=\"scan'208\";a=\"823109761\"",
        "From": "Zhe Tao <zhe.tao@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "wenzhuo.lu@intel.com, zhe.tao@intel.com, konstantin.ananyev@intel.com,\n\tbruce.richardson@intel.com, jing.d.chen@intel.com,\n\tcunming.liang@intel.com, jingjing.wu@intel.com, helin.zhang@intel.com",
        "Date": "Tue,  7 Jun 2016 14:53:10 +0800",
        "Message-Id": "<1465282390-6025-9-git-send-email-zhe.tao@intel.com>",
        "X-Mailer": "git-send-email 1.7.4.1",
        "In-Reply-To": "<1465282390-6025-1-git-send-email-zhe.tao@intel.com>",
        "References": "<1465278858-5131-1-git-send-email-zhe.tao@intel.com>\n\t<1465282390-6025-1-git-send-email-zhe.tao@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v4 8/8] i40e: implement device reset on VF",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Implement the device reset function.\n1, Add the fake RX/TX functions.\n2, The reset function tries to stop RX/TX by replacing\n   the RX/TX functions with the fake ones and getting the\n   locks to make sure the regular RX/TX finished.\n3, After the RX/TX stopped, reset the VF port, and then\n   release the locks.\n\nSigned-off-by: Zhe Tao <zhe.tao@intel.com>\n---\n doc/guides/rel_notes/release_16_07.rst |   5 ++\n drivers/net/i40e/i40e_ethdev.h         |   7 +-\n drivers/net/i40e/i40e_ethdev_vf.c      | 152 ++++++++++++++++++++++++++++++++-\n drivers/net/i40e/i40e_rxtx.c           |  10 +++\n drivers/net/i40e/i40e_rxtx.h           |   4 +\n 5 files changed, 172 insertions(+), 6 deletions(-)",
    "diff": "diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst\nindex a4c0cc3..f43b867 100644\n--- a/doc/guides/rel_notes/release_16_07.rst\n+++ b/doc/guides/rel_notes/release_16_07.rst\n@@ -62,6 +62,11 @@ New Features\n   callback in the message handler to notice the APP. APP need call the device\n   reset API to reset the VF port.\n \n+* **Added VF reset support for i40e VF driver.**\n+\n+  Added a new implementaion to allow i40e VF driver to\n+  reset the functionality and state of itself.\n+\n \n Resolved Issues\n ---------------\ndiff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h\nindex 672d920..dcd6e0f 100644\n--- a/drivers/net/i40e/i40e_ethdev.h\n+++ b/drivers/net/i40e/i40e_ethdev.h\n@@ -541,9 +541,8 @@ struct i40e_adapter {\n \tstruct rte_timecounter rx_tstamp_tc;\n \tstruct rte_timecounter tx_tstamp_tc;\n \n-\t/* For VF reset backup */\n-\teth_rx_burst_t rx_backup;\n-\teth_tx_burst_t tx_backup;\n+\t/* For VF reset */\n+\tuint8_t reset_number;\n };\n \n int i40e_dev_switch_queues(struct i40e_pf *pf, bool on);\n@@ -597,6 +596,8 @@ void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,\n void i40e_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,\n \tstruct rte_eth_txq_info *qinfo);\n \n+void i40evf_emulate_vf_reset(uint8_t port_id);\n+\n /* I40E_DEV_PRIVATE_TO */\n #define I40E_DEV_PRIVATE_TO_PF(adapter) \\\n \t(&((struct i40e_adapter *)adapter)->pf)\ndiff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c\nindex 46d8a7c..d873d2d 100644\n--- a/drivers/net/i40e/i40e_ethdev_vf.c\n+++ b/drivers/net/i40e/i40e_ethdev_vf.c\n@@ -157,6 +157,12 @@ i40evf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);\n static void i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,\n \t\t\t\t   uint8_t *msg,\n \t\t\t\t   uint16_t msglen);\n+static int i40evf_dev_uninit(struct rte_eth_dev *eth_dev);\n+static int i40evf_dev_init(struct rte_eth_dev *eth_dev);\n+static void i40evf_dev_close(struct rte_eth_dev *dev);\n+static int i40evf_dev_start(struct rte_eth_dev *dev);\n+static int i40evf_dev_configure(struct rte_eth_dev *dev);\n+static int i40evf_handle_vf_reset(struct rte_eth_dev *dev);\n \n /* Default hash key buffer for RSS */\n static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];\n@@ -223,6 +229,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {\n \t.reta_query           = i40evf_dev_rss_reta_query,\n \t.rss_hash_update      = i40evf_dev_rss_hash_update,\n \t.rss_hash_conf_get    = i40evf_dev_rss_hash_conf_get,\n+\t.dev_reset            = i40evf_handle_vf_reset\n };\n \n /*\n@@ -1309,6 +1316,140 @@ i40evf_uninit_vf(struct rte_eth_dev *dev)\n }\n \n static void\n+i40e_vf_queue_reset(struct rte_eth_dev *dev)\n+{\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\tstruct i40e_rx_queue *rxq = dev->data->rx_queues[i];\n+\n+\t\tif (rxq->q_set) {\n+\t\t\ti40e_dev_rx_queue_setup(dev,\n+\t\t\t\t\t\trxq->queue_id,\n+\t\t\t\t\t\trxq->nb_rx_desc,\n+\t\t\t\t\t\trxq->socket_id,\n+\t\t\t\t\t\t&rxq->rxconf,\n+\t\t\t\t\t\trxq->mp);\n+\t\t}\n+\n+\t\trxq = dev->data->rx_queues[i];\n+\t\trte_spinlock_trylock(&rxq->rx_lock);\n+\t}\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\tstruct i40e_tx_queue *txq = dev->data->tx_queues[i];\n+\n+\t\tif (txq->q_set) {\n+\t\t\ti40e_dev_tx_queue_setup(dev,\n+\t\t\t\t\t\ttxq->queue_id,\n+\t\t\t\t\t\ttxq->nb_tx_desc,\n+\t\t\t\t\t\ttxq->socket_id,\n+\t\t\t\t\t\t&txq->txconf);\n+\t\t}\n+\n+\t\ttxq = dev->data->tx_queues[i];\n+\t\trte_spinlock_trylock(&txq->tx_lock);\n+\t}\n+}\n+\n+static void\n+i40e_vf_reset_dev(struct rte_eth_dev *dev)\n+{\n+\tstruct i40e_adapter *adapter =\n+\t\tI40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\n+\ti40evf_dev_close(dev);\n+\tPMD_DRV_LOG(DEBUG, \"i40evf dev close complete\");\n+\ti40evf_dev_uninit(dev);\n+\tPMD_DRV_LOG(DEBUG, \"i40evf dev detached\");\n+\tmemset(dev->data->dev_private, 0,\n+\t       (uint64_t)&adapter->reset_number - (uint64_t)adapter);\n+\n+\ti40evf_dev_configure(dev);\n+\ti40evf_dev_init(dev);\n+\tPMD_DRV_LOG(DEBUG, \"i40evf dev attached\");\n+\ti40e_vf_queue_reset(dev);\n+\tPMD_DRV_LOG(DEBUG, \"i40evf queue reset\");\n+\ti40evf_dev_start(dev);\n+\tPMD_DRV_LOG(DEBUG, \"i40evf dev restart\");\n+}\n+\n+static uint16_t\n+i40evf_recv_pkts_detach(void __rte_unused *rx_queue,\n+\t\t\tstruct rte_mbuf __rte_unused **rx_pkts,\n+\t\t\tuint16_t __rte_unused nb_pkts)\n+{\n+\treturn 0;\n+}\n+\n+static uint16_t\n+i40evf_xmit_pkts_detach(void __rte_unused *tx_queue,\n+\t\t\tstruct rte_mbuf __rte_unused **tx_pkts,\n+\t\t\tuint16_t __rte_unused nb_pkts)\n+{\n+\treturn 0;\n+}\n+\n+static int\n+i40evf_handle_vf_reset(struct rte_eth_dev *dev)\n+{\n+\tstruct i40e_adapter *adapter =\n+\t\tI40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n+\tuint16_t i = 0;\n+\tstruct i40e_rx_queue *rxq;\n+\tstruct i40e_tx_queue *txq;\n+\n+\tif (!dev->data->dev_started)\n+\t\treturn 0;\n+\n+\tadapter->reset_number = 1;\n+\n+\t/**\n+\t * Stop RX/TX by fake functions and locks.\n+\t * Fake functions are used to make RX/TX lock easier.\n+\t */\n+\tdev->rx_pkt_burst = i40evf_recv_pkts_detach;\n+\tdev->tx_pkt_burst = i40evf_xmit_pkts_detach;\n+\n+\tif (dev->data->rx_queues)\n+\t\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\t\trxq = dev->data->rx_queues[i];\n+\t\t\trte_spinlock_lock(&rxq->rx_lock);\n+\t\t}\n+\n+\tif (dev->data->tx_queues)\n+\t\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\t\ttxq = dev->data->tx_queues[i];\n+\t\t\trte_spinlock_lock(&txq->tx_lock);\n+\t\t}\n+\n+\ti40e_vf_reset_dev(dev);\n+\n+\tadapter->reset_number = 0;\n+\n+\tif (dev->data->rx_queues)\n+\t\tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n+\t\t\trxq = dev->data->rx_queues[i];\n+\t\t\trte_spinlock_unlock(&rxq->rx_lock);\n+\t\t}\n+\n+\tif (dev->data->tx_queues)\n+\t\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\t\ttxq = dev->data->tx_queues[i];\n+\t\t\trte_spinlock_unlock(&txq->tx_lock);\n+\t\t}\n+\n+\treturn 0;\n+}\n+\n+void\n+i40evf_emulate_vf_reset(uint8_t port_id)\n+{\n+\tstruct rte_eth_dev *dev = &rte_eth_devices[port_id];\n+\n+\ti40evf_handle_vf_reset(dev);\n+}\n+\n+static void\n i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,\n \t\t\t   uint8_t *msg,\n \t\t\t   __rte_unused uint16_t msglen)\n@@ -1446,13 +1587,18 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)\n \tstruct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(\\\n \t\t\teth_dev->data->dev_private);\n \tstruct rte_pci_device *pci_dev = eth_dev->pci_dev;\n+\tstruct i40e_adapter *adapter =\n+\t\tI40E_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);\n \n \tPMD_INIT_FUNC_TRACE();\n-\n \t/* assign ops func pointer */\n \teth_dev->dev_ops = &i40evf_eth_dev_ops;\n-\teth_dev->rx_pkt_burst = RX_LOCK_FUNCTION(eth_dev, i40e_recv_pkts);\n-\teth_dev->tx_pkt_burst = TX_LOCK_FUNCTION(eth_dev, i40e_xmit_pkts);\n+\tif (adapter->reset_number) {\n+\t\teth_dev->rx_pkt_burst =\n+\t\t\tRX_LOCK_FUNCTION(eth_dev, i40e_recv_pkts);\n+\t\teth_dev->tx_pkt_burst =\n+\t\t\tTX_LOCK_FUNCTION(eth_dev, i40e_xmit_pkts);\n+\t}\n \n \t/*\n \t * For secondary processes, we don't initialise any further as primary\ndiff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c\nindex 0a6dcfb..f6caf4e 100644\n--- a/drivers/net/i40e/i40e_rxtx.c\n+++ b/drivers/net/i40e/i40e_rxtx.c\n@@ -2147,6 +2147,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,\n \tuint16_t len, i;\n \tuint16_t base, bsf, tc_mapping;\n \tint use_def_burst_func = 1;\n+\tstruct rte_eth_rxconf conf = *rx_conf;\n \n \tif (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {\n \t\tstruct i40e_vf *vf =\n@@ -2185,6 +2186,8 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,\n \t\treturn -ENOMEM;\n \t}\n \trxq->mp = mp;\n+\trxq->socket_id = socket_id;\n+\trxq->rxconf = conf;\n \trxq->nb_rx_desc = nb_desc;\n \trxq->rx_free_thresh = rx_conf->rx_free_thresh;\n \trxq->queue_id = queue_idx;\n@@ -2364,6 +2367,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \tuint32_t ring_size;\n \tuint16_t tx_rs_thresh, tx_free_thresh;\n \tuint16_t i, base, bsf, tc_mapping;\n+\tstruct rte_eth_txconf conf = *tx_conf;\n \n \tif (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {\n \t\tstruct i40e_vf *vf =\n@@ -2487,6 +2491,8 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,\n \t}\n \n \ttxq->nb_tx_desc = nb_desc;\n+\ttxq->socket_id = socket_id;\n+\ttxq->txconf = conf;\n \ttxq->tx_rs_thresh = tx_rs_thresh;\n \ttxq->tx_free_thresh = tx_free_thresh;\n \ttxq->pthresh = tx_conf->tx_thresh.pthresh;\n@@ -2951,8 +2957,12 @@ void\n i40e_dev_free_queues(struct rte_eth_dev *dev)\n {\n \tuint16_t i;\n+\tstruct i40e_adapter *adapter =\n+\t\tI40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);\n \n \tPMD_INIT_FUNC_TRACE();\n+\tif (adapter->reset_number)\n+\t\treturn;\n \n \tfor (i = 0; i < dev->data->nb_rx_queues; i++) {\n \t\ti40e_dev_rx_queue_release(dev->data->rx_queues[i]);\ndiff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h\nindex a1c13b8..7ee33dc 100644\n--- a/drivers/net/i40e/i40e_rxtx.h\n+++ b/drivers/net/i40e/i40e_rxtx.h\n@@ -141,6 +141,8 @@ struct i40e_rx_queue {\n \tuint16_t rx_using_sse; /**<flag indicate the usage of vPMD for rx */\n \tuint8_t dcb_tc;         /**< Traffic class of rx queue */\n \trte_spinlock_t rx_lock; /**< lock for rx path */\n+\tuint8_t socket_id;\n+\tstruct rte_eth_rxconf rxconf;\n };\n \n struct i40e_tx_entry {\n@@ -183,6 +185,8 @@ struct i40e_tx_queue {\n \tbool tx_deferred_start; /**< don't start this queue in dev start */\n \tuint8_t dcb_tc;         /**< Traffic class of tx queue */\n \trte_spinlock_t tx_lock; /**< lock for tx path */\n+\tuint8_t socket_id;\n+\tstruct rte_eth_txconf txconf;\n };\n \n /** Offload features */\n",
    "prefixes": [
        "dpdk-dev",
        "v4",
        "8/8"
    ]
}