get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 59079,
    "url": "https://patches.dpdk.org/api/patches/59079/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20190910171227.67843-1-alvinx.zhang@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20190910171227.67843-1-alvinx.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190910171227.67843-1-alvinx.zhang@intel.com",
    "date": "2019-09-10T17:12:27",
    "name": "[v4] net/i40e: validate all messages from VF",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "b90b4c2142c51fb86e634df81d41d328ddfa2549",
    "submitter": {
        "id": 1398,
        "url": "https://patches.dpdk.org/api/people/1398/?format=api",
        "name": "Alvin Zhang",
        "email": "alvinx.zhang@intel.com"
    },
    "delegate": {
        "id": 31221,
        "url": "https://patches.dpdk.org/api/users/31221/?format=api",
        "username": "yexl",
        "first_name": "xiaolong",
        "last_name": "ye",
        "email": "xiaolong.ye@intel.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20190910171227.67843-1-alvinx.zhang@intel.com/mbox/",
    "series": [
        {
            "id": 6352,
            "url": "https://patches.dpdk.org/api/series/6352/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=6352",
            "date": "2019-09-10T17:12:27",
            "name": "[v4] net/i40e: validate all messages from VF",
            "version": 4,
            "mbox": "https://patches.dpdk.org/series/6352/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/59079/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/59079/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 [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id B1AA31EE1C;\n\tTue, 10 Sep 2019 10:38:03 +0200 (CEST)",
            "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n\tby dpdk.org (Postfix) with ESMTP id B04991EE12\n\tfor <dev@dpdk.org>; Tue, 10 Sep 2019 10:38:01 +0200 (CEST)",
            "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t10 Sep 2019 01:38:00 -0700",
            "from unknown (HELO localhost.localdomain) ([10.240.176.181])\n\tby fmsmga001.fm.intel.com with ESMTP; 10 Sep 2019 01:37:59 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.64,489,1559545200\"; d=\"scan'208\";a=\"200240435\"",
        "From": "alvinx.zhang@intel.com",
        "To": "qi.z.zhang@intel.com,\n\tbeilei.xing@intel.com",
        "Cc": "dev@dpdk.org,\n\tAlvin Zhang <alvinx.zhang@intel.com>",
        "Date": "Wed, 11 Sep 2019 01:12:27 +0800",
        "Message-Id": "<20190910171227.67843-1-alvinx.zhang@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20190909151106.70803-1-alvinx.zhang@intel.com>",
        "References": "<20190909151106.70803-1-alvinx.zhang@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v4] net/i40e: validate all messages from VF",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Alvin Zhang <alvinx.zhang@intel.com>\n\nIf VF driver in VM continuous sending invalid messages by mailbox,\nit will waste CPU cycles on PF driver and impact other VF drivers\nconfiguration. I40E PF PMD can count the numbers of invalid and\nunsupported messages from VFs, when the counter of statistics from\na VF exceed maximum limitation, PF driver will ignore all of\nmessages from that VF for some seconds.\n\nSigned-off-by: Alvin Zhang <alvinx.zhang@intel.com>\n---\n\nv4: change the instruction file \"i40e.rst\".\nv3: resolve the compile issue on ubuntu 32-bit system.\nv2: modify codes according to the comments.\n\n doc/guides/nics/i40e.rst       |  12 +++\n drivers/net/i40e/i40e_ethdev.c |  82 ++++++++++++++++++\n drivers/net/i40e/i40e_ethdev.h |  32 +++++++\n drivers/net/i40e/i40e_pf.c     | 185 ++++++++++++++++++++++++++++++++---------\n 4 files changed, 270 insertions(+), 41 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst\nindex 0884e15..935706d 100644\n--- a/doc/guides/nics/i40e.rst\n+++ b/doc/guides/nics/i40e.rst\n@@ -185,6 +185,18 @@ Runtime Config Options\n \n   -w 84:00.0,use-latest-supported-vec=1\n \n+- ``Enable validation for VF message`` (default ``not enabled``)\n+\n+  The i40e PF PMD supports message validation which from VFs. This will count the\n+  numbers of continuous invalid and unsupported messages from VFs. If the counter of\n+  statistics from a VF exceed maximum limitation, PF driver will ignore all of messages\n+  from that VF for some seconds. Using the ``devargs`` option ``vf_max_wrong_msg``,\n+  user can specify how many continuous invalid and unsupported message that PF driver\n+  could tolerate and how many seconds during which PF driver will ignore all of\n+  messages from a VF, for example::\n+\n+  -w 84:00.0,vf_max_wrong_msg=4:6:30\n+\n Vector RX Pre-conditions\n ~~~~~~~~~~~~~~~~~~~~~~~~\n For Vector RX it is assumed that the number of descriptor rings will be a power\ndiff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c\nindex 4e40b7a..3d09fc2 100644\n--- a/drivers/net/i40e/i40e_ethdev.c\n+++ b/drivers/net/i40e/i40e_ethdev.c\n@@ -44,6 +44,7 @@\n #define ETH_I40E_SUPPORT_MULTI_DRIVER\t\"support-multi-driver\"\n #define ETH_I40E_QUEUE_NUM_PER_VF_ARG\t\"queue-num-per-vf\"\n #define ETH_I40E_USE_LATEST_VEC\t\"use-latest-supported-vec\"\n+#define ETH_I40E_MAX_VF_WRONG_MSG\t\"vf_max_wrong_msg\"\n \n #define I40E_CLEAR_PXE_WAIT_MS     200\n \n@@ -406,6 +407,7 @@ static int i40e_sw_tunnel_filter_insert(struct i40e_pf *pf,\n \tETH_I40E_SUPPORT_MULTI_DRIVER,\n \tETH_I40E_QUEUE_NUM_PER_VF_ARG,\n \tETH_I40E_USE_LATEST_VEC,\n+\tETH_I40E_MAX_VF_WRONG_MSG,\n \tNULL};\n \n static const struct rte_pci_id pci_id_i40e_map[] = {\n@@ -1256,6 +1258,84 @@ static inline void i40e_config_automask(struct i40e_pf *pf)\n \treturn 0;\n }\n \n+static int\n+read_vf_msg_check_info(__rte_unused const char *key,\n+\t\t\t       const char *value,\n+\t\t\t       void *opaque)\n+{\n+\tstruct i40e_wrong_vf_msg info;\n+\n+\tmemset(&info, 0, sizeof(info));\n+\t/*\n+\t * VF message checking function need 3 parameters, max_invalid,\n+\t * max_unsupported and silence_seconds.\n+\t * When continuous invalid or unsupported message statistics\n+\t * from a VF exceed the limitation of 'max_invalid' or\n+\t * 'max_unsupported', PF will ignore any message from that VF for\n+\t * 'silence_seconds' seconds.\n+\t */\n+\tif (sscanf(value, \"%u:%u:%u\", &info.max_invalid,\n+\t\t\t&info.max_unsupported, &info.silence_seconds)\n+\t\t\t!= 3) {\n+\t\tPMD_DRV_LOG(ERR, \"vf_max_wrong_msg error! format like: \"\n+\t\t\t\t\"vf_max_wrong_msg=4:6:60\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/*\n+\t * If invalid or unsupported message checking function is enabled\n+\t * by setting max_invalid or max_unsupported variable to not zero,\n+\t * 'slience_seconds' must be greater than zero.\n+\t */\n+\tif ((info.max_invalid || info.max_unsupported) &&\n+\t\t\t!info.silence_seconds) {\n+\t\tPMD_DRV_LOG(ERR, \"vf_max_wrong_msg error! last integer\"\n+\t\t\t\t\" must be larger than zero\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemcpy(opaque, &info, sizeof(struct i40e_wrong_vf_msg));\n+\treturn 0;\n+}\n+\n+static int\n+i40e_parse_vf_msg_check_info(struct rte_eth_dev *dev,\n+\t\tstruct i40e_wrong_vf_msg *wrong_info)\n+{\n+\tint ret = 0;\n+\tint kvargs_count;\n+\tstruct rte_kvargs *kvlist;\n+\n+\t/* reset all to zero */\n+\tmemset(wrong_info, 0, sizeof(*wrong_info));\n+\n+\tif (!dev->device->devargs)\n+\t\treturn ret;\n+\n+\tkvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);\n+\tif (!kvlist)\n+\t\treturn -EINVAL;\n+\n+\tkvargs_count = rte_kvargs_count(kvlist, ETH_I40E_MAX_VF_WRONG_MSG);\n+\tif (!kvargs_count)\n+\t\tgoto free_end;\n+\n+\tif (kvargs_count > 1) {\n+\t\tPMD_DRV_LOG(ERR, \"More than one argument \\\"%s\\\"!\",\n+\t\t\t\tETH_I40E_MAX_VF_WRONG_MSG);\n+\t\tret = -EINVAL;\n+\t\tgoto free_end;\n+\t}\n+\n+\tif (rte_kvargs_process(kvlist, ETH_I40E_MAX_VF_WRONG_MSG,\n+\t\t\tread_vf_msg_check_info, wrong_info) < 0)\n+\t\tret = -EINVAL;\n+\n+free_end:\n+\trte_kvargs_free(kvlist);\n+\treturn ret;\n+}\n+\n #define I40E_ALARM_INTERVAL 50000 /* us */\n \n static int\n@@ -1328,6 +1408,8 @@ static inline void i40e_config_automask(struct i40e_pf *pf)\n \t\treturn -EIO;\n \t}\n \n+\t/* read VF message checking function parameters */\n+\ti40e_parse_vf_msg_check_info(dev, &pf->wrong_vf_msg_conf);\n \t/* Check if need to support multi-driver */\n \ti40e_support_multi_driver(dev);\n \t/* Check if users want the latest supported vec path */\ndiff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h\nindex 38ac3ea..24e10c5 100644\n--- a/drivers/net/i40e/i40e_ethdev.h\n+++ b/drivers/net/i40e/i40e_ethdev.h\n@@ -426,6 +426,25 @@ struct i40e_pf_vf {\n \t/* version of the virtchnl from VF */\n \tstruct virtchnl_version_info version;\n \tuint32_t request_caps; /* offload caps requested from VF */\n+\n+\t/*\n+\t * Counter of message from VF\n+\t * invalid_cmd_cnt, invalid command since last valid command\n+\t * unsupported_cmd_cnt, unsupported command since last valid command\n+\t * invalid_total, total invalid command\n+\t * unsupported_total, total unsupported command\n+\t * ignored_cmd_cnt, ignored command in silence\n+\t */\n+\tuint16_t invalid_cmd_cnt;\n+\tuint16_t unsupported_cmd_cnt;\n+\tuint32_t invalid_total;\n+\tuint32_t unsupported_total;\n+\tuint32_t ignored_cmd_cnt;\n+\n+\t/* cycle of stop ignoring VF message */\n+\tuint64_t silence_end_cycle;\n+\t/* cycle of receive last invalid or unsupported message from VF*/\n+\tuint64_t last_wrong_msg_cycle;\n };\n \n /*\n@@ -900,6 +919,17 @@ struct i40e_rte_flow_rss_conf {\n \tuint16_t queue[I40E_MAX_Q_PER_TC]; /**< Queues indices to use. */\n };\n \n+struct i40e_wrong_vf_msg {\n+\tuint32_t max_invalid; /* maximal continuous invalid message from VF */\n+\t/* maximal continuous unsupported message from VF */\n+\tuint32_t max_unsupported;\n+\t/*\n+\t * silence seconds when VF send much more invalid or unsupported\n+\t * message\n+\t */\n+\tuint32_t silence_seconds;\n+};\n+\n /*\n  * Structure to store private data specific for PF instance.\n  */\n@@ -975,6 +1005,8 @@ struct i40e_pf {\n \tstruct i40e_customized_pctype customized_pctype[I40E_CUSTOMIZED_MAX];\n \t/* Switch Domain Id */\n \tuint16_t switch_domain_id;\n+\n+\tstruct i40e_wrong_vf_msg wrong_vf_msg_conf;\n };\n \n enum pending_msg {\ndiff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c\nindex b28d02e..8835f9c 100644\n--- a/drivers/net/i40e/i40e_pf.c\n+++ b/drivers/net/i40e/i40e_pf.c\n@@ -297,7 +297,7 @@\n \t\ti40e_pf_host_send_msg_to_vf(vf,\n \t\t\t\t\t    VIRTCHNL_OP_GET_VF_RESOURCES,\n \t\t\t\t\t    I40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \t/* only have 1 VSI by default */\n@@ -488,7 +488,7 @@\n \t\ti40e_pf_host_send_msg_to_vf(vf,\n \t\t\t\t\t    VIRTCHNL_OP_CONFIG_VSI_QUEUES,\n \t\t\t\t\t    I40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tif (!msg || vc_vqci->num_queue_pairs > vsi->nb_qps ||\n@@ -655,7 +655,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_CONFIG_IRQ_MAP,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tif (msg == NULL || msglen < sizeof(struct virtchnl_irq_map_info)) {\n@@ -795,7 +795,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_DISABLE_QUEUES,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tif (msg == NULL || msglen != sizeof(*q_sel)) {\n@@ -830,7 +830,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_ADD_ETH_ADDR,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tmemset(&filter, 0 , sizeof(struct i40e_mac_filter_info));\n@@ -876,7 +876,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_DEL_ETH_ADDR,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tif (msg == NULL || msglen <= sizeof(*addr_list)) {\n@@ -917,7 +917,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_ADD_VLAN,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tif (msg == NULL || msglen <= sizeof(*vlan_filter_list)) {\n@@ -958,7 +958,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_DEL_VLAN,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tif (msg == NULL || msglen <= sizeof(*vlan_filter_list)) {\n@@ -999,7 +999,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tif (msg == NULL || msglen != sizeof(*promisc)) {\n@@ -1031,16 +1031,18 @@\n {\n \ti40e_update_vsi_stats(vf->vsi);\n \n-\tif (b_op)\n+\tif (b_op) {\n \t\ti40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_GET_STATS,\n \t\t\t\t\t    I40E_SUCCESS,\n \t\t\t\t\t    (uint8_t *)&vf->vsi->eth_stats,\n \t\t\t\t\t    sizeof(vf->vsi->eth_stats));\n-\telse\n+\t} else {\n \t\ti40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_GET_STATS,\n \t\t\t\t\t    I40E_NOT_SUPPORTED,\n \t\t\t\t\t    (uint8_t *)&vf->vsi->eth_stats,\n \t\t\t\t\t    sizeof(vf->vsi->eth_stats));\n+\t\treturn I40E_NOT_SUPPORTED;\n+\t}\n \n \treturn I40E_SUCCESS;\n }\n@@ -1055,7 +1057,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_ENABLE_VLAN_STRIPPING,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tret = i40e_vsi_config_vlan_stripping(vf->vsi, TRUE);\n@@ -1078,7 +1080,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_DISABLE_VLAN_STRIPPING,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tret = i40e_vsi_config_vlan_stripping(vf->vsi, FALSE);\n@@ -1106,7 +1108,7 @@\n \t\t\tvf,\n \t\t\tVIRTCHNL_OP_CONFIG_RSS_LUT,\n \t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n-\t\treturn ret;\n+\t\treturn I40E_NOT_SUPPORTED;\n \t}\n \n \tif (!msg || msglen <= sizeof(struct virtchnl_rss_lut)) {\n@@ -1247,6 +1249,7 @@\n \tstruct i40e_pf *pf;\n \tuint32_t req_pairs = vfres->num_queue_pairs;\n \tuint32_t cur_pairs = vf->vsi->nb_used_qps;\n+\tint ret = I40E_SUCCESS;\n \n \tpf = vf->pf;\n \n@@ -1256,12 +1259,14 @@\n \tif (req_pairs == 0) {\n \t\tPMD_DRV_LOG(ERR, \"VF %d tried to request 0 queues. Ignoring.\\n\",\n \t\t\t    vf->vf_idx);\n+\t\tret = I40E_ERR_PARAM;\n \t} else if (req_pairs > I40E_MAX_QP_NUM_PER_VF) {\n \t\tPMD_DRV_LOG(ERR,\n \t\t\t    \"VF %d tried to request more than %d queues.\\n\",\n \t\t\t    vf->vf_idx,\n \t\t\t    I40E_MAX_QP_NUM_PER_VF);\n \t\tvfres->num_queue_pairs = I40E_MAX_QP_NUM_PER_VF;\n+\t\tret = I40E_ERR_PARAM;\n \t} else if (req_pairs > cur_pairs + pf->qp_pool.num_free) {\n \t\tPMD_DRV_LOG(ERR, \"VF %d requested %d queues (rounded to %d) \"\n \t\t\t\"but only %d available\\n\",\n@@ -1277,11 +1282,12 @@\n \t\tpf->vf_nb_qps = req_pairs;\n \t\ti40e_pf_host_process_cmd_reset_vf(vf);\n \n-\t\treturn 0;\n+\t\treturn I40E_SUCCESS;\n \t}\n \n-\treturn i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 0,\n+\ti40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 0,\n \t\t\t\t(u8 *)vfres, sizeof(*vfres));\n+\treturn ret;\n }\n \n void\n@@ -1306,11 +1312,19 @@\n \t}\n \n \tvf = &pf->vfs[vf_id];\n+\n+\t/* if timer not end, ignore the message and return */\n+\tif (rte_get_timer_cycles() < vf->silence_end_cycle) {\n+\t\tvf->ignored_cmd_cnt++;\n+\t\treturn;\n+\t}\n+\n \tif (!vf->vsi) {\n \t\tPMD_DRV_LOG(ERR, \"NO VSI associated with VF found\");\n \t\ti40e_pf_host_send_msg_to_vf(vf, opcode,\n \t\t\tI40E_ERR_NO_AVAILABLE_VSI, NULL, 0);\n-\t\treturn;\n+\t\tret = I40E_ERR_NO_AVAILABLE_VSI;\n+\t\tgoto err_cmd;\n \t}\n \n \t/* perform basic checks on the msg */\n@@ -1331,14 +1345,15 @@\n \n \tif (ret) {\n \t\tPMD_DRV_LOG(ERR, \"Invalid message from VF %u, opcode %u, len %u\",\n-\t\t\t    vf_id, opcode, msglen);\n+\t\t\t\tvf_id, opcode, msglen);\n \t\ti40e_pf_host_send_msg_to_vf(vf, opcode,\n-\t\t\t\t\t    I40E_ERR_PARAM, NULL, 0);\n-\t\treturn;\n+\t\t\t\tI40E_ERR_PARAM, NULL, 0);\n+\t\tret = I40E_ERR_PARAM;\n+\t\tgoto err_cmd;\n \t}\n \n \t/**\n-\t * initialise structure to send to user application\n+\t * initialize structure to send to user application\n \t * will return response from user in retval field\n \t */\n \tret_param.retval = RTE_PMD_I40E_MB_EVENT_PROCEED;\n@@ -1373,78 +1388,84 @@\n \t\tbreak;\n \tcase VIRTCHNL_OP_GET_VF_RESOURCES:\n \t\tPMD_DRV_LOG(INFO, \"OP_GET_VF_RESOURCES received\");\n-\t\ti40e_pf_host_process_cmd_get_vf_resource(vf, msg, b_op);\n+\t\tret = i40e_pf_host_process_cmd_get_vf_resource(vf, msg, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_CONFIG_VSI_QUEUES:\n \t\tPMD_DRV_LOG(INFO, \"OP_CONFIG_VSI_QUEUES received\");\n-\t\ti40e_pf_host_process_cmd_config_vsi_queues(vf, msg,\n+\t\tret = i40e_pf_host_process_cmd_config_vsi_queues(vf, msg,\n \t\t\t\t\t\t\t   msglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_CONFIG_IRQ_MAP:\n \t\tPMD_DRV_LOG(INFO, \"OP_CONFIG_IRQ_MAP received\");\n-\t\ti40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen, b_op);\n+\t\tret = i40e_pf_host_process_cmd_config_irq_map(vf, msg,\n+\t\t\t\tmsglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_ENABLE_QUEUES:\n \t\tPMD_DRV_LOG(INFO, \"OP_ENABLE_QUEUES received\");\n \t\tif (b_op) {\n-\t\t\ti40e_pf_host_process_cmd_enable_queues(vf, msg, msglen);\n+\t\t\tret = i40e_pf_host_process_cmd_enable_queues(vf,\n+\t\t\t\t\tmsg, msglen);\n \t\t\ti40e_notify_vf_link_status(dev, vf);\n \t\t} else {\n-\t\t\ti40e_pf_host_send_msg_to_vf(\n-\t\t\t\tvf, VIRTCHNL_OP_ENABLE_QUEUES,\n-\t\t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n+\t\t\ti40e_pf_host_send_msg_to_vf(vf,\n+\t\t\t\t\tVIRTCHNL_OP_ENABLE_QUEUES,\n+\t\t\t\t\tI40E_NOT_SUPPORTED, NULL, 0);\n+\t\t\tret = I40E_NOT_SUPPORTED;\n \t\t}\n \t\tbreak;\n \tcase VIRTCHNL_OP_DISABLE_QUEUES:\n \t\tPMD_DRV_LOG(INFO, \"OP_DISABLE_QUEUE received\");\n-\t\ti40e_pf_host_process_cmd_disable_queues(vf, msg, msglen, b_op);\n+\t\tret = i40e_pf_host_process_cmd_disable_queues(vf,\n+\t\t\t\tmsg, msglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_ADD_ETH_ADDR:\n \t\tPMD_DRV_LOG(INFO, \"OP_ADD_ETHER_ADDRESS received\");\n-\t\ti40e_pf_host_process_cmd_add_ether_address(vf, msg,\n+\t\tret = i40e_pf_host_process_cmd_add_ether_address(vf, msg,\n \t\t\t\t\t\t\t   msglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_DEL_ETH_ADDR:\n \t\tPMD_DRV_LOG(INFO, \"OP_DEL_ETHER_ADDRESS received\");\n-\t\ti40e_pf_host_process_cmd_del_ether_address(vf, msg,\n+\t\tret = i40e_pf_host_process_cmd_del_ether_address(vf, msg,\n \t\t\t\t\t\t\t   msglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_ADD_VLAN:\n \t\tPMD_DRV_LOG(INFO, \"OP_ADD_VLAN received\");\n-\t\ti40e_pf_host_process_cmd_add_vlan(vf, msg, msglen, b_op);\n+\t\tret = i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_DEL_VLAN:\n \t\tPMD_DRV_LOG(INFO, \"OP_DEL_VLAN received\");\n-\t\ti40e_pf_host_process_cmd_del_vlan(vf, msg, msglen, b_op);\n+\t\tret = i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:\n \t\tPMD_DRV_LOG(INFO, \"OP_CONFIG_PROMISCUOUS_MODE received\");\n-\t\ti40e_pf_host_process_cmd_config_promisc_mode(vf, msg,\n+\t\tret = i40e_pf_host_process_cmd_config_promisc_mode(vf, msg,\n \t\t\t\t\t\t\t     msglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_GET_STATS:\n \t\tPMD_DRV_LOG(INFO, \"OP_GET_STATS received\");\n-\t\ti40e_pf_host_process_cmd_get_stats(vf, b_op);\n+\t\tret = i40e_pf_host_process_cmd_get_stats(vf, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:\n \t\tPMD_DRV_LOG(INFO, \"OP_ENABLE_VLAN_STRIPPING received\");\n-\t\ti40e_pf_host_process_cmd_enable_vlan_strip(vf, b_op);\n+\t\tret = i40e_pf_host_process_cmd_enable_vlan_strip(vf, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:\n \t\tPMD_DRV_LOG(INFO, \"OP_DISABLE_VLAN_STRIPPING received\");\n-\t\ti40e_pf_host_process_cmd_disable_vlan_strip(vf, b_op);\n+\t\tret = i40e_pf_host_process_cmd_disable_vlan_strip(vf, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_CONFIG_RSS_LUT:\n \t\tPMD_DRV_LOG(INFO, \"OP_CONFIG_RSS_LUT received\");\n-\t\ti40e_pf_host_process_cmd_set_rss_lut(vf, msg, msglen, b_op);\n+\t\tret = i40e_pf_host_process_cmd_set_rss_lut(vf, msg,\n+\t\t\t\tmsglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_CONFIG_RSS_KEY:\n \t\tPMD_DRV_LOG(INFO, \"OP_CONFIG_RSS_KEY received\");\n-\t\ti40e_pf_host_process_cmd_set_rss_key(vf, msg, msglen, b_op);\n+\t\tret = i40e_pf_host_process_cmd_set_rss_key(vf, msg,\n+\t\t\t\tmsglen, b_op);\n \t\tbreak;\n \tcase VIRTCHNL_OP_REQUEST_QUEUES:\n \t\tPMD_DRV_LOG(INFO, \"OP_REQUEST_QUEUES received\");\n-\t\ti40e_pf_host_process_cmd_request_queues(vf, msg);\n+\t\tret = i40e_pf_host_process_cmd_request_queues(vf, msg);\n \t\tbreak;\n \n \t/* Don't add command supported below, which will\n@@ -1452,10 +1473,86 @@\n \t */\n \tdefault:\n \t\tPMD_DRV_LOG(ERR, \"%u received, not supported\", opcode);\n-\t\ti40e_pf_host_send_msg_to_vf(vf, opcode, I40E_ERR_PARAM,\n+\t\ti40e_pf_host_send_msg_to_vf(vf, opcode, I40E_NOT_SUPPORTED,\n \t\t\t\t\t\t\t\tNULL, 0);\n+\t\tret = I40E_NOT_SUPPORTED;\n \t\tbreak;\n \t}\n+\n+err_cmd:\n+\t/* If the amount of invalid or unsupported message been received\n+\t * from a VF exceed maximal limitation, PF will start a timer.\n+\t * Before the timer timed out, PF should ignore any message from\n+\t * that VF.\n+\t * Once the timer timed out, PF will accept a message from the VF,\n+\t * if this message is still invalid or unsupported, PF will\n+\t * restart the timer and enter another loop.\n+\t * If the last commond execute succeed and within 'silence_seconds'\n+\t * period of time, no invalid or unsupported message been\n+\t * received from same VF, the counter of 'invalid/unsupported'\n+\t * message for that VF will be reset to zero.\n+\t */\n+\tvf->silence_end_cycle = 0;\n+\tswitch (ret) {\n+\tcase I40E_SUCCESS:\n+\t\tif ((vf->invalid_cmd_cnt || vf->unsupported_cmd_cnt) &&\n+\t\t\t\trte_get_timer_cycles() >=\n+\t\t\t\tvf->last_wrong_msg_cycle +\n+\t\t\t\tpf->wrong_vf_msg_conf.silence_seconds *\n+\t\t\t\trte_get_timer_hz()) {\n+\t\t\tPMD_DRV_LOG(WARNING, \"VF %u message, ignored %u, \"\n+\t\t\t\t\t\"invalid %u, unsupported %u\", vf_id,\n+\t\t\t\t\tvf->ignored_cmd_cnt, vf->invalid_total,\n+\t\t\t\t\tvf->unsupported_total);\n+\t\t\tvf->unsupported_cmd_cnt = 0;\n+\t\t\tvf->invalid_cmd_cnt = 0;\n+\t\t}\n+\t\tbreak;\n+\n+\tcase I40E_ERR_PARAM:\n+\tcase I40E_ERR_NO_AVAILABLE_VSI:\n+\t\tvf->invalid_total++;\n+\t\tif (!pf->wrong_vf_msg_conf.max_invalid)\n+\t\t\tbreak;\n+\t\tvf->invalid_cmd_cnt++;\n+\t\tif (vf->invalid_cmd_cnt >\n+\t\t\t\tpf->wrong_vf_msg_conf.max_invalid) {\n+\t\t\tPMD_DRV_LOG(ERR, \"VF %u too much continuous invalid\"\n+\t\t\t\t\t\" message(%u, maximum %u, total %u)!\",\n+\t\t\t\t\tvf_id, vf->invalid_cmd_cnt,\n+\t\t\t\t\tpf->wrong_vf_msg_conf.max_invalid,\n+\t\t\t\t\tvf->invalid_total);\n+\t\t\tvf->silence_end_cycle = rte_get_timer_cycles() +\n+\t\t\t\t\tpf->wrong_vf_msg_conf.silence_seconds\n+\t\t\t\t\t* rte_get_timer_hz();\n+\t\t}\n+\n+\t\tvf->last_wrong_msg_cycle = rte_get_timer_cycles();\n+\t\tbreak;\n+\n+\tcase I40E_NOT_SUPPORTED:\n+\t\tvf->unsupported_total++;\n+\t\tif (!pf->wrong_vf_msg_conf.max_unsupported)\n+\t\t\tbreak;\n+\t\tvf->unsupported_cmd_cnt++;\n+\t\tif (vf->unsupported_cmd_cnt >\n+\t\t\t\tpf->wrong_vf_msg_conf.max_unsupported) {\n+\t\t\tPMD_DRV_LOG(ERR, \"VF %u too much continuous unsupported\"\n+\t\t\t\t\t\" message(%u, maximum %u, total %u)!\",\n+\t\t\t\t\tvf_id, vf->unsupported_cmd_cnt,\n+\t\t\t\t\tpf->wrong_vf_msg_conf.max_unsupported,\n+\t\t\t\t\tvf->unsupported_total);\n+\t\t\tvf->silence_end_cycle = rte_get_timer_cycles() +\n+\t\t\t\t\tpf->wrong_vf_msg_conf.silence_seconds\n+\t\t\t\t\t* rte_get_timer_hz();\n+\t\t}\n+\n+\t\tvf->last_wrong_msg_cycle = rte_get_timer_cycles();\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\treturn;\n }\n \n int\n@@ -1493,6 +1590,12 @@\n \t\tpf->vfs[i].pf = pf;\n \t\tpf->vfs[i].state = I40E_VF_INACTIVE;\n \t\tpf->vfs[i].vf_idx = i;\n+\n+\t\tpf->vfs[i].invalid_cmd_cnt = 0;\n+\t\tpf->vfs[i].unsupported_cmd_cnt = 0;\n+\t\tpf->vfs[i].silence_end_cycle = 0;\n+\t\tpf->vfs[i].last_wrong_msg_cycle = 0;\n+\n \t\tret = i40e_pf_host_vf_reset(&pf->vfs[i], 0);\n \t\tif (ret != I40E_SUCCESS)\n \t\t\tgoto fail;\n",
    "prefixes": [
        "v4"
    ]
}