From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id CABD6A2EE8 for ; Mon, 9 Sep 2019 15:37:08 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 55EBA1EC4E; Mon, 9 Sep 2019 15:37:08 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id E29D61EC49 for ; Mon, 9 Sep 2019 15:37:06 +0200 (CEST) X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Sep 2019 06:37:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,484,1559545200"; d="scan'208";a="183819937" Received: from yexl-server.sh.intel.com (HELO localhost) ([10.67.117.5]) by fmsmga008.fm.intel.com with ESMTP; 09 Sep 2019 06:37:02 -0700 Date: Mon, 9 Sep 2019 21:34:52 +0800 From: Ye Xiaolong To: alvinx.zhang@intel.com Cc: qi.z.zhang@intel.com, beilei.xing@intel.com, dev@dpdk.org Message-ID: <20190909133452.GA28432@intel.com> References: <20190909100140.36772-1-alvinx.zhang@intel.com> <20190909151106.70803-1-alvinx.zhang@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190909151106.70803-1-alvinx.zhang@intel.com> User-Agent: Mutt/1.9.4 (2018-02-28) Subject: Re: [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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Hi, alvinx Could you add some changelog to your patch, it would be easier for reviewers/readers to know what changes you've made compared to last version. Thanks, Xiaolong On 09/09, alvinx.zhang@intel.com wrote: >From: Alvin Zhang > >If VF driver in VM continuous sending invalid messages by mailbox, >it will waste CPU cycles on PF driver and impact other VF drivers >configuration. I40E PF PMD can count the numbers of invalid and >unsupported messages from VFs, when the counter of statistics from >a VF exceed maximum limitation, PF driver will ignore all of >messages from that VF for some seconds. > >Signed-off-by: Alvin Zhang >--- > doc/guides/nics/i40e.rst | 12 +++ > drivers/net/i40e/i40e_ethdev.c | 82 ++++++++++++++++++ > drivers/net/i40e/i40e_ethdev.h | 32 +++++++ > drivers/net/i40e/i40e_pf.c | 185 ++++++++++++++++++++++++++++++++--------- > 4 files changed, 270 insertions(+), 41 deletions(-) > >diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst >index 0884e15..935706d 100644 >--- a/doc/guides/nics/i40e.rst >+++ b/doc/guides/nics/i40e.rst >@@ -185,6 +185,18 @@ Runtime Config Options > > -w 84:00.0,use-latest-supported-vec=1 > >+- ``Enable validation for VF message`` (default ``not enabled``) >+ >+ The i40e PF PMD supports message validation which from VFs. This will count the >+ numbers of continuous invalid and unsupported messages from VFs. If the counter of >+ statistics from a VF exceed maximum limitation, PF driver will ignore all of messages >+ from that VF for some seconds. Using the ``devargs`` option ``vf_max_wrong_msg``, >+ user can specify how many continuous invalid and unsupported message that PF driver >+ could tolerate and how many seconds during which PF driver will ignore all of >+ messages from a VF, for example:: >+ >+ -w 84:00.0,vf_max_wrong_msg=4:6:30 >+ > Vector RX Pre-conditions > ~~~~~~~~~~~~~~~~~~~~~~~~ > For Vector RX it is assumed that the number of descriptor rings will be a power >diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c >index 4e40b7a..3d09fc2 100644 >--- a/drivers/net/i40e/i40e_ethdev.c >+++ b/drivers/net/i40e/i40e_ethdev.c >@@ -44,6 +44,7 @@ > #define ETH_I40E_SUPPORT_MULTI_DRIVER "support-multi-driver" > #define ETH_I40E_QUEUE_NUM_PER_VF_ARG "queue-num-per-vf" > #define ETH_I40E_USE_LATEST_VEC "use-latest-supported-vec" >+#define ETH_I40E_MAX_VF_WRONG_MSG "vf_max_wrong_msg" > > #define I40E_CLEAR_PXE_WAIT_MS 200 > >@@ -406,6 +407,7 @@ static int i40e_sw_tunnel_filter_insert(struct i40e_pf *pf, > ETH_I40E_SUPPORT_MULTI_DRIVER, > ETH_I40E_QUEUE_NUM_PER_VF_ARG, > ETH_I40E_USE_LATEST_VEC, >+ ETH_I40E_MAX_VF_WRONG_MSG, > NULL}; > > static const struct rte_pci_id pci_id_i40e_map[] = { >@@ -1256,6 +1258,84 @@ static inline void i40e_config_automask(struct i40e_pf *pf) > return 0; > } > >+static int >+read_vf_msg_check_info(__rte_unused const char *key, >+ const char *value, >+ void *opaque) >+{ >+ struct i40e_wrong_vf_msg info; >+ >+ memset(&info, 0, sizeof(info)); >+ /* >+ * VF message checking function need 3 parameters, max_invalid, >+ * max_unsupported and silence_seconds. >+ * When continuous invalid or unsupported message statistics >+ * from a VF exceed the limitation of 'max_invalid' or >+ * 'max_unsupported', PF will ignore any message from that VF for >+ * 'silence_seconds' seconds. >+ */ >+ if (sscanf(value, "%u:%u:%u", &info.max_invalid, >+ &info.max_unsupported, &info.silence_seconds) >+ != 3) { >+ PMD_DRV_LOG(ERR, "vf_max_wrong_msg error! format like: " >+ "vf_max_wrong_msg=4:6:60"); >+ return -EINVAL; >+ } >+ >+ /* >+ * If invalid or unsupported message checking function is enabled >+ * by setting max_invalid or max_unsupported variable to not zero, >+ * 'slience_seconds' must be greater than zero. >+ */ >+ if ((info.max_invalid || info.max_unsupported) && >+ !info.silence_seconds) { >+ PMD_DRV_LOG(ERR, "vf_max_wrong_msg error! last integer" >+ " must be larger than zero"); >+ return -EINVAL; >+ } >+ >+ memcpy(opaque, &info, sizeof(struct i40e_wrong_vf_msg)); >+ return 0; >+} >+ >+static int >+i40e_parse_vf_msg_check_info(struct rte_eth_dev *dev, >+ struct i40e_wrong_vf_msg *wrong_info) >+{ >+ int ret = 0; >+ int kvargs_count; >+ struct rte_kvargs *kvlist; >+ >+ /* reset all to zero */ >+ memset(wrong_info, 0, sizeof(*wrong_info)); >+ >+ if (!dev->device->devargs) >+ return ret; >+ >+ kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys); >+ if (!kvlist) >+ return -EINVAL; >+ >+ kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_MAX_VF_WRONG_MSG); >+ if (!kvargs_count) >+ goto free_end; >+ >+ if (kvargs_count > 1) { >+ PMD_DRV_LOG(ERR, "More than one argument \"%s\"!", >+ ETH_I40E_MAX_VF_WRONG_MSG); >+ ret = -EINVAL; >+ goto free_end; >+ } >+ >+ if (rte_kvargs_process(kvlist, ETH_I40E_MAX_VF_WRONG_MSG, >+ read_vf_msg_check_info, wrong_info) < 0) >+ ret = -EINVAL; >+ >+free_end: >+ rte_kvargs_free(kvlist); >+ return ret; >+} >+ > #define I40E_ALARM_INTERVAL 50000 /* us */ > > static int >@@ -1328,6 +1408,8 @@ static inline void i40e_config_automask(struct i40e_pf *pf) > return -EIO; > } > >+ /* read VF message checking function parameters */ >+ i40e_parse_vf_msg_check_info(dev, &pf->wrong_vf_msg_conf); > /* Check if need to support multi-driver */ > i40e_support_multi_driver(dev); > /* Check if users want the latest supported vec path */ >diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h >index 38ac3ea..24e10c5 100644 >--- a/drivers/net/i40e/i40e_ethdev.h >+++ b/drivers/net/i40e/i40e_ethdev.h >@@ -426,6 +426,25 @@ struct i40e_pf_vf { > /* version of the virtchnl from VF */ > struct virtchnl_version_info version; > uint32_t request_caps; /* offload caps requested from VF */ >+ >+ /* >+ * Counter of message from VF >+ * invalid_cmd_cnt, invalid command since last valid command >+ * unsupported_cmd_cnt, unsupported command since last valid command >+ * invalid_total, total invalid command >+ * unsupported_total, total unsupported command >+ * ignored_cmd_cnt, ignored command in silence >+ */ >+ uint16_t invalid_cmd_cnt; >+ uint16_t unsupported_cmd_cnt; >+ uint32_t invalid_total; >+ uint32_t unsupported_total; >+ uint32_t ignored_cmd_cnt; >+ >+ /* cycle of stop ignoring VF message */ >+ uint64_t silence_end_cycle; >+ /* cycle of receive last invalid or unsupported message from VF*/ >+ uint64_t last_wrong_msg_cycle; > }; > > /* >@@ -900,6 +919,17 @@ struct i40e_rte_flow_rss_conf { > uint16_t queue[I40E_MAX_Q_PER_TC]; /**< Queues indices to use. */ > }; > >+struct i40e_wrong_vf_msg { >+ uint32_t max_invalid; /* maximal continuous invalid message from VF */ >+ /* maximal continuous unsupported message from VF */ >+ uint32_t max_unsupported; >+ /* >+ * silence seconds when VF send much more invalid or unsupported >+ * message >+ */ >+ uint32_t silence_seconds; >+}; >+ > /* > * Structure to store private data specific for PF instance. > */ >@@ -975,6 +1005,8 @@ struct i40e_pf { > struct i40e_customized_pctype customized_pctype[I40E_CUSTOMIZED_MAX]; > /* Switch Domain Id */ > uint16_t switch_domain_id; >+ >+ struct i40e_wrong_vf_msg wrong_vf_msg_conf; > }; > > enum pending_msg { >diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c >index b28d02e..8835f9c 100644 >--- a/drivers/net/i40e/i40e_pf.c >+++ b/drivers/net/i40e/i40e_pf.c >@@ -297,7 +297,7 @@ > i40e_pf_host_send_msg_to_vf(vf, > VIRTCHNL_OP_GET_VF_RESOURCES, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > /* only have 1 VSI by default */ >@@ -488,7 +488,7 @@ > i40e_pf_host_send_msg_to_vf(vf, > VIRTCHNL_OP_CONFIG_VSI_QUEUES, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > if (!msg || vc_vqci->num_queue_pairs > vsi->nb_qps || >@@ -655,7 +655,7 @@ > vf, > VIRTCHNL_OP_CONFIG_IRQ_MAP, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > if (msg == NULL || msglen < sizeof(struct virtchnl_irq_map_info)) { >@@ -795,7 +795,7 @@ > vf, > VIRTCHNL_OP_DISABLE_QUEUES, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > if (msg == NULL || msglen != sizeof(*q_sel)) { >@@ -830,7 +830,7 @@ > vf, > VIRTCHNL_OP_ADD_ETH_ADDR, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > memset(&filter, 0 , sizeof(struct i40e_mac_filter_info)); >@@ -876,7 +876,7 @@ > vf, > VIRTCHNL_OP_DEL_ETH_ADDR, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > if (msg == NULL || msglen <= sizeof(*addr_list)) { >@@ -917,7 +917,7 @@ > vf, > VIRTCHNL_OP_ADD_VLAN, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) { >@@ -958,7 +958,7 @@ > vf, > VIRTCHNL_OP_DEL_VLAN, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) { >@@ -999,7 +999,7 @@ > vf, > VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > if (msg == NULL || msglen != sizeof(*promisc)) { >@@ -1031,16 +1031,18 @@ > { > i40e_update_vsi_stats(vf->vsi); > >- if (b_op) >+ if (b_op) { > i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_GET_STATS, > I40E_SUCCESS, > (uint8_t *)&vf->vsi->eth_stats, > sizeof(vf->vsi->eth_stats)); >- else >+ } else { > i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_GET_STATS, > I40E_NOT_SUPPORTED, > (uint8_t *)&vf->vsi->eth_stats, > sizeof(vf->vsi->eth_stats)); >+ return I40E_NOT_SUPPORTED; >+ } > > return I40E_SUCCESS; > } >@@ -1055,7 +1057,7 @@ > vf, > VIRTCHNL_OP_ENABLE_VLAN_STRIPPING, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > ret = i40e_vsi_config_vlan_stripping(vf->vsi, TRUE); >@@ -1078,7 +1080,7 @@ > vf, > VIRTCHNL_OP_DISABLE_VLAN_STRIPPING, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > ret = i40e_vsi_config_vlan_stripping(vf->vsi, FALSE); >@@ -1106,7 +1108,7 @@ > vf, > VIRTCHNL_OP_CONFIG_RSS_LUT, > I40E_NOT_SUPPORTED, NULL, 0); >- return ret; >+ return I40E_NOT_SUPPORTED; > } > > if (!msg || msglen <= sizeof(struct virtchnl_rss_lut)) { >@@ -1247,6 +1249,7 @@ > struct i40e_pf *pf; > uint32_t req_pairs = vfres->num_queue_pairs; > uint32_t cur_pairs = vf->vsi->nb_used_qps; >+ int ret = I40E_SUCCESS; > > pf = vf->pf; > >@@ -1256,12 +1259,14 @@ > if (req_pairs == 0) { > PMD_DRV_LOG(ERR, "VF %d tried to request 0 queues. Ignoring.\n", > vf->vf_idx); >+ ret = I40E_ERR_PARAM; > } else if (req_pairs > I40E_MAX_QP_NUM_PER_VF) { > PMD_DRV_LOG(ERR, > "VF %d tried to request more than %d queues.\n", > vf->vf_idx, > I40E_MAX_QP_NUM_PER_VF); > vfres->num_queue_pairs = I40E_MAX_QP_NUM_PER_VF; >+ ret = I40E_ERR_PARAM; > } else if (req_pairs > cur_pairs + pf->qp_pool.num_free) { > PMD_DRV_LOG(ERR, "VF %d requested %d queues (rounded to %d) " > "but only %d available\n", >@@ -1277,11 +1282,12 @@ > pf->vf_nb_qps = req_pairs; > i40e_pf_host_process_cmd_reset_vf(vf); > >- return 0; >+ return I40E_SUCCESS; > } > >- return i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 0, >+ i40e_pf_host_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 0, > (u8 *)vfres, sizeof(*vfres)); >+ return ret; > } > > void >@@ -1306,11 +1312,19 @@ > } > > vf = &pf->vfs[vf_id]; >+ >+ /* if timer not end, ignore the message and return */ >+ if (rte_get_timer_cycles() < vf->silence_end_cycle) { >+ vf->ignored_cmd_cnt++; >+ return; >+ } >+ > if (!vf->vsi) { > PMD_DRV_LOG(ERR, "NO VSI associated with VF found"); > i40e_pf_host_send_msg_to_vf(vf, opcode, > I40E_ERR_NO_AVAILABLE_VSI, NULL, 0); >- return; >+ ret = I40E_ERR_NO_AVAILABLE_VSI; >+ goto err_cmd; > } > > /* perform basic checks on the msg */ >@@ -1331,14 +1345,15 @@ > > if (ret) { > PMD_DRV_LOG(ERR, "Invalid message from VF %u, opcode %u, len %u", >- vf_id, opcode, msglen); >+ vf_id, opcode, msglen); > i40e_pf_host_send_msg_to_vf(vf, opcode, >- I40E_ERR_PARAM, NULL, 0); >- return; >+ I40E_ERR_PARAM, NULL, 0); >+ ret = I40E_ERR_PARAM; >+ goto err_cmd; > } > > /** >- * initialise structure to send to user application >+ * initialize structure to send to user application > * will return response from user in retval field > */ > ret_param.retval = RTE_PMD_I40E_MB_EVENT_PROCEED; >@@ -1373,78 +1388,84 @@ > break; > case VIRTCHNL_OP_GET_VF_RESOURCES: > PMD_DRV_LOG(INFO, "OP_GET_VF_RESOURCES received"); >- i40e_pf_host_process_cmd_get_vf_resource(vf, msg, b_op); >+ ret = i40e_pf_host_process_cmd_get_vf_resource(vf, msg, b_op); > break; > case VIRTCHNL_OP_CONFIG_VSI_QUEUES: > PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES received"); >- i40e_pf_host_process_cmd_config_vsi_queues(vf, msg, >+ ret = i40e_pf_host_process_cmd_config_vsi_queues(vf, msg, > msglen, b_op); > break; > case VIRTCHNL_OP_CONFIG_IRQ_MAP: > PMD_DRV_LOG(INFO, "OP_CONFIG_IRQ_MAP received"); >- i40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen, b_op); >+ ret = i40e_pf_host_process_cmd_config_irq_map(vf, msg, >+ msglen, b_op); > break; > case VIRTCHNL_OP_ENABLE_QUEUES: > PMD_DRV_LOG(INFO, "OP_ENABLE_QUEUES received"); > if (b_op) { >- i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen); >+ ret = i40e_pf_host_process_cmd_enable_queues(vf, >+ msg, msglen); > i40e_notify_vf_link_status(dev, vf); > } else { >- i40e_pf_host_send_msg_to_vf( >- vf, VIRTCHNL_OP_ENABLE_QUEUES, >- I40E_NOT_SUPPORTED, NULL, 0); >+ i40e_pf_host_send_msg_to_vf(vf, >+ VIRTCHNL_OP_ENABLE_QUEUES, >+ I40E_NOT_SUPPORTED, NULL, 0); >+ ret = I40E_NOT_SUPPORTED; > } > break; > case VIRTCHNL_OP_DISABLE_QUEUES: > PMD_DRV_LOG(INFO, "OP_DISABLE_QUEUE received"); >- i40e_pf_host_process_cmd_disable_queues(vf, msg, msglen, b_op); >+ ret = i40e_pf_host_process_cmd_disable_queues(vf, >+ msg, msglen, b_op); > break; > case VIRTCHNL_OP_ADD_ETH_ADDR: > PMD_DRV_LOG(INFO, "OP_ADD_ETHER_ADDRESS received"); >- i40e_pf_host_process_cmd_add_ether_address(vf, msg, >+ ret = i40e_pf_host_process_cmd_add_ether_address(vf, msg, > msglen, b_op); > break; > case VIRTCHNL_OP_DEL_ETH_ADDR: > PMD_DRV_LOG(INFO, "OP_DEL_ETHER_ADDRESS received"); >- i40e_pf_host_process_cmd_del_ether_address(vf, msg, >+ ret = i40e_pf_host_process_cmd_del_ether_address(vf, msg, > msglen, b_op); > break; > case VIRTCHNL_OP_ADD_VLAN: > PMD_DRV_LOG(INFO, "OP_ADD_VLAN received"); >- i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen, b_op); >+ ret = i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen, b_op); > break; > case VIRTCHNL_OP_DEL_VLAN: > PMD_DRV_LOG(INFO, "OP_DEL_VLAN received"); >- i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen, b_op); >+ ret = i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen, b_op); > break; > case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: > PMD_DRV_LOG(INFO, "OP_CONFIG_PROMISCUOUS_MODE received"); >- i40e_pf_host_process_cmd_config_promisc_mode(vf, msg, >+ ret = i40e_pf_host_process_cmd_config_promisc_mode(vf, msg, > msglen, b_op); > break; > case VIRTCHNL_OP_GET_STATS: > PMD_DRV_LOG(INFO, "OP_GET_STATS received"); >- i40e_pf_host_process_cmd_get_stats(vf, b_op); >+ ret = i40e_pf_host_process_cmd_get_stats(vf, b_op); > break; > case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING: > PMD_DRV_LOG(INFO, "OP_ENABLE_VLAN_STRIPPING received"); >- i40e_pf_host_process_cmd_enable_vlan_strip(vf, b_op); >+ ret = i40e_pf_host_process_cmd_enable_vlan_strip(vf, b_op); > break; > case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING: > PMD_DRV_LOG(INFO, "OP_DISABLE_VLAN_STRIPPING received"); >- i40e_pf_host_process_cmd_disable_vlan_strip(vf, b_op); >+ ret = i40e_pf_host_process_cmd_disable_vlan_strip(vf, b_op); > break; > case VIRTCHNL_OP_CONFIG_RSS_LUT: > PMD_DRV_LOG(INFO, "OP_CONFIG_RSS_LUT received"); >- i40e_pf_host_process_cmd_set_rss_lut(vf, msg, msglen, b_op); >+ ret = i40e_pf_host_process_cmd_set_rss_lut(vf, msg, >+ msglen, b_op); > break; > case VIRTCHNL_OP_CONFIG_RSS_KEY: > PMD_DRV_LOG(INFO, "OP_CONFIG_RSS_KEY received"); >- i40e_pf_host_process_cmd_set_rss_key(vf, msg, msglen, b_op); >+ ret = i40e_pf_host_process_cmd_set_rss_key(vf, msg, >+ msglen, b_op); > break; > case VIRTCHNL_OP_REQUEST_QUEUES: > PMD_DRV_LOG(INFO, "OP_REQUEST_QUEUES received"); >- i40e_pf_host_process_cmd_request_queues(vf, msg); >+ ret = i40e_pf_host_process_cmd_request_queues(vf, msg); > break; > > /* Don't add command supported below, which will >@@ -1452,10 +1473,86 @@ > */ > default: > PMD_DRV_LOG(ERR, "%u received, not supported", opcode); >- i40e_pf_host_send_msg_to_vf(vf, opcode, I40E_ERR_PARAM, >+ i40e_pf_host_send_msg_to_vf(vf, opcode, I40E_NOT_SUPPORTED, > NULL, 0); >+ ret = I40E_NOT_SUPPORTED; > break; > } >+ >+err_cmd: >+ /* If the amount of invalid or unsupported message been received >+ * from a VF exceed maximal limitation, PF will start a timer. >+ * Before the timer timed out, PF should ignore any message from >+ * that VF. >+ * Once the timer timed out, PF will accept a message from the VF, >+ * if this message is still invalid or unsupported, PF will >+ * restart the timer and enter another loop. >+ * If the last commond execute succeed and within 'silence_seconds' >+ * period of time, no invalid or unsupported message been >+ * received from same VF, the counter of 'invalid/unsupported' >+ * message for that VF will be reset to zero. >+ */ >+ vf->silence_end_cycle = 0; >+ switch (ret) { >+ case I40E_SUCCESS: >+ if ((vf->invalid_cmd_cnt || vf->unsupported_cmd_cnt) && >+ rte_get_timer_cycles() >= >+ vf->last_wrong_msg_cycle + >+ pf->wrong_vf_msg_conf.silence_seconds * >+ rte_get_timer_hz()) { >+ PMD_DRV_LOG(WARNING, "VF %u message, ignored %u, " >+ "invalid %u, unsupported %u", vf_id, >+ vf->ignored_cmd_cnt, vf->invalid_total, >+ vf->unsupported_total); >+ vf->unsupported_cmd_cnt = 0; >+ vf->invalid_cmd_cnt = 0; >+ } >+ break; >+ >+ case I40E_ERR_PARAM: >+ case I40E_ERR_NO_AVAILABLE_VSI: >+ vf->invalid_total++; >+ if (!pf->wrong_vf_msg_conf.max_invalid) >+ break; >+ vf->invalid_cmd_cnt++; >+ if (vf->invalid_cmd_cnt > >+ pf->wrong_vf_msg_conf.max_invalid) { >+ PMD_DRV_LOG(ERR, "VF %u too much continuous invalid" >+ " message(%u, maximum %u, total %u)!", >+ vf_id, vf->invalid_cmd_cnt, >+ pf->wrong_vf_msg_conf.max_invalid, >+ vf->invalid_total); >+ vf->silence_end_cycle = rte_get_timer_cycles() + >+ pf->wrong_vf_msg_conf.silence_seconds >+ * rte_get_timer_hz(); >+ } >+ >+ vf->last_wrong_msg_cycle = rte_get_timer_cycles(); >+ break; >+ >+ case I40E_NOT_SUPPORTED: >+ vf->unsupported_total++; >+ if (!pf->wrong_vf_msg_conf.max_unsupported) >+ break; >+ vf->unsupported_cmd_cnt++; >+ if (vf->unsupported_cmd_cnt > >+ pf->wrong_vf_msg_conf.max_unsupported) { >+ PMD_DRV_LOG(ERR, "VF %u too much continuous unsupported" >+ " message(%u, maximum %u, total %u)!", >+ vf_id, vf->unsupported_cmd_cnt, >+ pf->wrong_vf_msg_conf.max_unsupported, >+ vf->unsupported_total); >+ vf->silence_end_cycle = rte_get_timer_cycles() + >+ pf->wrong_vf_msg_conf.silence_seconds >+ * rte_get_timer_hz(); >+ } >+ >+ vf->last_wrong_msg_cycle = rte_get_timer_cycles(); >+ break; >+ default: >+ break; >+ } >+ return; > } > > int >@@ -1493,6 +1590,12 @@ > pf->vfs[i].pf = pf; > pf->vfs[i].state = I40E_VF_INACTIVE; > pf->vfs[i].vf_idx = i; >+ >+ pf->vfs[i].invalid_cmd_cnt = 0; >+ pf->vfs[i].unsupported_cmd_cnt = 0; >+ pf->vfs[i].silence_end_cycle = 0; >+ pf->vfs[i].last_wrong_msg_cycle = 0; >+ > ret = i40e_pf_host_vf_reset(&pf->vfs[i], 0); > if (ret != I40E_SUCCESS) > goto fail; >-- >1.8.3.1 >