Intel-Wired-Lan Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-wired-lan] [PATCH iwl-next v3] ice: add E830 HW VF mailbox message limit support
@ 2024-08-12 22:15 Paul Greenwalt
  2024-08-14 14:51 ` kernel test robot
  2024-08-15  7:58 ` Paul Menzel
  0 siblings, 2 replies; 4+ messages in thread
From: Paul Greenwalt @ 2024-08-12 22:15 UTC (permalink / raw)
  To: intel-wired-lan; +Cc: aleksander.lobakin, Paul Greenwalt

E830 adds hardware support to prevent the VF from overflowing the PF
mailbox with VIRTCHNL messages. E830 will use the hardware feature
(ICE_F_MBX_LIMIT) instead of the software solution ice_is_malicious_vf().

To prevent a VF from overflowing the PF, the PF sets the number of
messages per VF that can be in the PF's mailbox queue
(ICE_MBX_OVERFLOW_WATERMARK). When the PF process a message from a VF,
the PF decrements the per VF message count using the E830_MBX_VF_DEC_TRIG
register.

Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
---
v1 -> v2:
- Update ice_mbx_vf_dec_trig_e830 and ice_mbx_vf_clear_cnt_e830 onstack
  variables to const
v2 -> v3:
- Fix indentation and remove unnessary paranthes in macro
- Replace ice_init_feature_support() E830 device id check with MAC
  check
- Remove use of const for scalars
---
 drivers/net/ethernet/intel/ice/ice.h          |  1 +
 .../net/ethernet/intel/ice/ice_hw_autogen.h   |  3 ++
 drivers/net/ethernet/intel/ice/ice_lib.c      | 15 +++++++++
 drivers/net/ethernet/intel/ice/ice_main.c     | 24 ++++++++++----
 drivers/net/ethernet/intel/ice/ice_sriov.c    |  3 +-
 drivers/net/ethernet/intel/ice/ice_vf_lib.c   | 26 +++++++++++++--
 drivers/net/ethernet/intel/ice/ice_vf_mbx.c   | 32 +++++++++++++++++++
 drivers/net/ethernet/intel/ice/ice_vf_mbx.h   |  3 ++
 drivers/net/ethernet/intel/ice/ice_virtchnl.c |  8 +++--
 9 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index d6f80da30dec..53082b619fc3 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -207,6 +207,7 @@ enum ice_feature {
 	ICE_F_GNSS,
 	ICE_F_ROCE_LAG,
 	ICE_F_SRIOV_LAG,
+	ICE_F_MBX_LIMIT,
 	ICE_F_MAX
 };
 
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
index 91cbae1eec89..8d31bfe28cc8 100644
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
@@ -539,5 +539,8 @@
 #define E830_PRTMAC_CL01_QNT_THR_CL0_M		GENMASK(15, 0)
 #define VFINT_DYN_CTLN(_i)			(0x00003800 + ((_i) * 4))
 #define VFINT_DYN_CTLN_CLEARPBA_M		BIT(1)
+#define E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH	0x00234000
+#define E830_MBX_VF_DEC_TRIG(_VF)		(0x00233800 + (_VF) * 4)
+#define E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(_VF)	(0x00233000 + (_VF) * 4)
 
 #endif /* _ICE_HW_AUTOGEN_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index d9c34d28c9cd..2c55209d3ce2 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -3877,9 +3877,24 @@ void ice_init_feature_support(struct ice_pf *pf)
 		if (ice_gnss_is_gps_present(&pf->hw))
 			ice_set_feature_support(pf, ICE_F_GNSS);
 		break;
+	case ICE_DEV_ID_E830CC_BACKPLANE:
+	case ICE_DEV_ID_E830CC_QSFP56:
+	case ICE_DEV_ID_E830CC_SFP:
+	case ICE_DEV_ID_E830CC_SFP_DD:
+	case ICE_DEV_ID_E830C_BACKPLANE:
+	case ICE_DEV_ID_E830C_QSFP:
+	case ICE_DEV_ID_E830C_SFP:
+	case ICE_DEV_ID_E830_XXV_BACKPLANE:
+	case ICE_DEV_ID_E830_XXV_QSFP:
+	case ICE_DEV_ID_E830_XXV_SFP:
+		ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
+		break;
 	default:
 		break;
 	}
+
+	if (pf->hw.mac_type == ICE_MAC_E830)
+		ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index fd27c7995d60..12ce5d2283d3 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -1542,12 +1542,20 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
 			ice_vf_lan_overflow_event(pf, &event);
 			break;
 		case ice_mbx_opc_send_msg_to_pf:
-			data.num_msg_proc = i;
-			data.num_pending_arq = pending;
-			data.max_num_msgs_mbx = hw->mailboxq.num_rq_entries;
-			data.async_watermark_val = ICE_MBX_OVERFLOW_WATERMARK;
+			if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) {
+				ice_vc_process_vf_msg(pf, &event, NULL);
+				ice_mbx_vf_dec_trig_e830(hw, &event);
+			} else {
+				u16 val = hw->mailboxq.num_rq_entries;
+
+				data.max_num_msgs_mbx = val;
+				val = ICE_MBX_OVERFLOW_WATERMARK;
+				data.async_watermark_val = val;
+				data.num_msg_proc = i;
+				data.num_pending_arq = pending;
 
-			ice_vc_process_vf_msg(pf, &event, &data);
+				ice_vc_process_vf_msg(pf, &event, &data);
+			}
 			break;
 		case ice_aqc_opc_fw_logs_event:
 			ice_get_fwlog_data(pf, &event);
@@ -4078,7 +4086,11 @@ static int ice_init_pf(struct ice_pf *pf)
 
 	mutex_init(&pf->vfs.table_lock);
 	hash_init(pf->vfs.table);
-	ice_mbx_init_snapshot(&pf->hw);
+	if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
+		wr32(&pf->hw, E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH,
+		     ICE_MBX_OVERFLOW_WATERMARK);
+	else
+		ice_mbx_init_snapshot(&pf->hw);
 
 	xa_init(&pf->dyn_ports);
 	xa_init(&pf->sf_nums);
diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c
index e34fe2516ccc..e7b5fe553d1f 100644
--- a/drivers/net/ethernet/intel/ice/ice_sriov.c
+++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
@@ -194,7 +194,8 @@ void ice_free_vfs(struct ice_pf *pf)
 		}
 
 		/* clear malicious info since the VF is getting released */
-		list_del(&vf->mbx_info.list_entry);
+		if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
+			list_del(&vf->mbx_info.list_entry);
 
 		mutex_unlock(&vf->cfg_lock);
 	}
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
index a69e91f88d81..d618292dfe27 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
@@ -709,6 +709,23 @@ ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
 	return 0;
 }
 
+/**
+ * ice_reset_vf_mbx_cnt - reset VF mailbox message count
+ * @vf: pointer to the VF structure
+ *
+ * This function clears the VF mailbox message count, and should be called on
+ * VF reset.
+ */
+static void ice_reset_vf_mbx_cnt(struct ice_vf *vf)
+{
+	struct ice_pf *pf = vf->pf;
+
+	if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
+		ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
+	else
+		ice_mbx_clear_malvf(&vf->mbx_info);
+}
+
 /**
  * ice_reset_all_vfs - reset all allocated VFs in one go
  * @pf: pointer to the PF structure
@@ -735,7 +752,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)
 
 	/* clear all malicious info if the VFs are getting reset */
 	ice_for_each_vf(pf, bkt, vf)
-		ice_mbx_clear_malvf(&vf->mbx_info);
+		ice_reset_vf_mbx_cnt(vf);
 
 	/* If VFs have been disabled, there is no need to reset */
 	if (test_and_set_bit(ICE_VF_DIS, pf->state)) {
@@ -951,7 +968,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
 	ice_eswitch_update_repr(&vf->repr_id, vsi);
 
 	/* if the VF has been reset allow it to come up again */
-	ice_mbx_clear_malvf(&vf->mbx_info);
+	ice_reset_vf_mbx_cnt(vf);
 
 out_unlock:
 	if (lag && lag->bonded && lag->primary &&
@@ -1004,7 +1021,10 @@ void ice_initialize_vf_entry(struct ice_vf *vf)
 	ice_vf_fdir_init(vf);
 
 	/* Initialize mailbox info for this VF */
-	ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
+	if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
+		ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
+	else
+		ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
 
 	mutex_init(&vf->cfg_lock);
 }
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
index 40cb4ba0789c..75c8113e58ee 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
+++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
@@ -210,6 +210,38 @@ ice_mbx_detect_malvf(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info,
 	return 0;
 }
 
+/**
+ * ice_mbx_vf_dec_trig_e830 - Decrements the VF mailbox queue counter
+ * @hw: pointer to the HW struct
+ * @event: pointer to the control queue receive event
+ *
+ * This function triggers to decrement the counter
+ * MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT when the driver replenishes
+ * the buffers at the PF mailbox queue.
+ */
+void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
+			      const struct ice_rq_event_info *event)
+{
+	u16 vfid = le16_to_cpu(event->desc.retval);
+
+	wr32(hw, E830_MBX_VF_DEC_TRIG(vfid), 1);
+}
+
+/**
+ * ice_mbx_vf_clear_cnt_e830 - Clear the VF mailbox queue count
+ * @hw: pointer to the HW struct
+ * @vf_id: VF ID in the PF space
+ *
+ * This function clears the counter MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT, and should
+ * be called when a VF is created and on VF reset.
+ */
+void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id)
+{
+	u32 reg = rd32(hw, E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(vf_id));
+
+	wr32(hw, E830_MBX_VF_DEC_TRIG(vf_id), reg);
+}
+
 /**
  * ice_mbx_vf_state_handler - Handle states of the overflow algorithm
  * @hw: pointer to the HW struct
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
index 44bc030d17e0..edcd9332368c 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
+++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
@@ -19,6 +19,9 @@ ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,
 		      u8 *msg, u16 msglen, struct ice_sq_cd *cd);
 
 u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed);
+void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
+			      const struct ice_rq_event_info *event);
+void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id);
 int
 ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data,
 			 struct ice_mbx_vf_info *vf_info, bool *report_malvf);
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
index 59f62306b9cb..3c86d0c2fe1f 100644
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
@@ -4009,8 +4009,10 @@ ice_is_malicious_vf(struct ice_vf *vf, struct ice_mbx_data *mbxdata)
  * @event: pointer to the AQ event
  * @mbxdata: information used to detect VF attempting mailbox overflow
  *
- * called from the common asq/arq handler to
- * process request from VF
+ * Called from the common asq/arq handler to process request from VF. When this
+ * flow is used for devices with hardware VF to PF message queue overflow
+ * support (ICE_F_MBX_LIMIT) mbxdata is set to NULL and ice_is_malicious_vf
+ * check is skipped.
  */
 void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event,
 			   struct ice_mbx_data *mbxdata)
@@ -4036,7 +4038,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event,
 	mutex_lock(&vf->cfg_lock);
 
 	/* Check if the VF is trying to overflow the mailbox */
-	if (ice_is_malicious_vf(vf, mbxdata))
+	if (mbxdata && ice_is_malicious_vf(vf, mbxdata))
 		goto finish;
 
 	/* Check if VF is disabled. */
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Intel-wired-lan] [PATCH iwl-next v3] ice: add E830 HW VF mailbox message limit support
  2024-08-12 22:15 [Intel-wired-lan] [PATCH iwl-next v3] ice: add E830 HW VF mailbox message limit support Paul Greenwalt
@ 2024-08-14 14:51 ` kernel test robot
  2024-08-15  7:58 ` Paul Menzel
  1 sibling, 0 replies; 4+ messages in thread
From: kernel test robot @ 2024-08-14 14:51 UTC (permalink / raw)
  To: Paul Greenwalt, intel-wired-lan
  Cc: aleksander.lobakin, llvm, Paul Greenwalt, oe-kbuild-all

Hi Paul,

kernel test robot noticed the following build errors:

[auto build test ERROR on tnguy-next-queue/dev-queue]

url:    https://github.com/intel-lab-lkp/linux/commits/Paul-Greenwalt/ice-add-E830-HW-VF-mailbox-message-limit-support/20240814-151255
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue.git dev-queue
patch link:    https://lore.kernel.org/r/20240812221501.1705162-1-paul.greenwalt%40intel.com
patch subject: [Intel-wired-lan] [PATCH iwl-next v3] ice: add E830 HW VF mailbox message limit support
config: i386-randconfig-006-20240814 (https://download.01.org/0day-ci/archive/20240814/202408142133.W175mlnf-lkp@intel.com/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240814/202408142133.W175mlnf-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408142133.W175mlnf-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/net/ethernet/intel/ice/ice_main.c:1546:5: error: call to undeclared function 'ice_mbx_vf_dec_trig_e830'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1546 |                                 ice_mbx_vf_dec_trig_e830(hw, &event);
         |                                 ^
   drivers/net/ethernet/intel/ice/ice_main.c:5269:39: warning: shift count >= width of type [-Wshift-count-overflow]
    5269 |         err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
         |                                              ^~~~~~~~~~~~~~~~
   include/linux/dma-mapping.h:77:54: note: expanded from macro 'DMA_BIT_MASK'
      77 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
         |                                                      ^ ~~~
   1 warning and 1 error generated.


vim +/ice_mbx_vf_dec_trig_e830 +1546 drivers/net/ethernet/intel/ice/ice_main.c

  1426	
  1427	/**
  1428	 * __ice_clean_ctrlq - helper function to clean controlq rings
  1429	 * @pf: ptr to struct ice_pf
  1430	 * @q_type: specific Control queue type
  1431	 */
  1432	static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
  1433	{
  1434		struct device *dev = ice_pf_to_dev(pf);
  1435		struct ice_rq_event_info event;
  1436		struct ice_hw *hw = &pf->hw;
  1437		struct ice_ctl_q_info *cq;
  1438		u16 pending, i = 0;
  1439		const char *qtype;
  1440		u32 oldval, val;
  1441	
  1442		/* Do not clean control queue if/when PF reset fails */
  1443		if (test_bit(ICE_RESET_FAILED, pf->state))
  1444			return 0;
  1445	
  1446		switch (q_type) {
  1447		case ICE_CTL_Q_ADMIN:
  1448			cq = &hw->adminq;
  1449			qtype = "Admin";
  1450			break;
  1451		case ICE_CTL_Q_SB:
  1452			cq = &hw->sbq;
  1453			qtype = "Sideband";
  1454			break;
  1455		case ICE_CTL_Q_MAILBOX:
  1456			cq = &hw->mailboxq;
  1457			qtype = "Mailbox";
  1458			/* we are going to try to detect a malicious VF, so set the
  1459			 * state to begin detection
  1460			 */
  1461			hw->mbx_snapshot.mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
  1462			break;
  1463		default:
  1464			dev_warn(dev, "Unknown control queue type 0x%x\n", q_type);
  1465			return 0;
  1466		}
  1467	
  1468		/* check for error indications - PF_xx_AxQLEN register layout for
  1469		 * FW/MBX/SB are identical so just use defines for PF_FW_AxQLEN.
  1470		 */
  1471		val = rd32(hw, cq->rq.len);
  1472		if (val & (PF_FW_ARQLEN_ARQVFE_M | PF_FW_ARQLEN_ARQOVFL_M |
  1473			   PF_FW_ARQLEN_ARQCRIT_M)) {
  1474			oldval = val;
  1475			if (val & PF_FW_ARQLEN_ARQVFE_M)
  1476				dev_dbg(dev, "%s Receive Queue VF Error detected\n",
  1477					qtype);
  1478			if (val & PF_FW_ARQLEN_ARQOVFL_M) {
  1479				dev_dbg(dev, "%s Receive Queue Overflow Error detected\n",
  1480					qtype);
  1481			}
  1482			if (val & PF_FW_ARQLEN_ARQCRIT_M)
  1483				dev_dbg(dev, "%s Receive Queue Critical Error detected\n",
  1484					qtype);
  1485			val &= ~(PF_FW_ARQLEN_ARQVFE_M | PF_FW_ARQLEN_ARQOVFL_M |
  1486				 PF_FW_ARQLEN_ARQCRIT_M);
  1487			if (oldval != val)
  1488				wr32(hw, cq->rq.len, val);
  1489		}
  1490	
  1491		val = rd32(hw, cq->sq.len);
  1492		if (val & (PF_FW_ATQLEN_ATQVFE_M | PF_FW_ATQLEN_ATQOVFL_M |
  1493			   PF_FW_ATQLEN_ATQCRIT_M)) {
  1494			oldval = val;
  1495			if (val & PF_FW_ATQLEN_ATQVFE_M)
  1496				dev_dbg(dev, "%s Send Queue VF Error detected\n",
  1497					qtype);
  1498			if (val & PF_FW_ATQLEN_ATQOVFL_M) {
  1499				dev_dbg(dev, "%s Send Queue Overflow Error detected\n",
  1500					qtype);
  1501			}
  1502			if (val & PF_FW_ATQLEN_ATQCRIT_M)
  1503				dev_dbg(dev, "%s Send Queue Critical Error detected\n",
  1504					qtype);
  1505			val &= ~(PF_FW_ATQLEN_ATQVFE_M | PF_FW_ATQLEN_ATQOVFL_M |
  1506				 PF_FW_ATQLEN_ATQCRIT_M);
  1507			if (oldval != val)
  1508				wr32(hw, cq->sq.len, val);
  1509		}
  1510	
  1511		event.buf_len = cq->rq_buf_size;
  1512		event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
  1513		if (!event.msg_buf)
  1514			return 0;
  1515	
  1516		do {
  1517			struct ice_mbx_data data = {};
  1518			u16 opcode;
  1519			int ret;
  1520	
  1521			ret = ice_clean_rq_elem(hw, cq, &event, &pending);
  1522			if (ret == -EALREADY)
  1523				break;
  1524			if (ret) {
  1525				dev_err(dev, "%s Receive Queue event error %d\n", qtype,
  1526					ret);
  1527				break;
  1528			}
  1529	
  1530			opcode = le16_to_cpu(event.desc.opcode);
  1531	
  1532			/* Notify any thread that might be waiting for this event */
  1533			ice_aq_check_events(pf, opcode, &event);
  1534	
  1535			switch (opcode) {
  1536			case ice_aqc_opc_get_link_status:
  1537				if (ice_handle_link_event(pf, &event))
  1538					dev_err(dev, "Could not handle link event\n");
  1539				break;
  1540			case ice_aqc_opc_event_lan_overflow:
  1541				ice_vf_lan_overflow_event(pf, &event);
  1542				break;
  1543			case ice_mbx_opc_send_msg_to_pf:
  1544				if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) {
  1545					ice_vc_process_vf_msg(pf, &event, NULL);
> 1546					ice_mbx_vf_dec_trig_e830(hw, &event);
  1547				} else {
  1548					u16 val = hw->mailboxq.num_rq_entries;
  1549	
  1550					data.max_num_msgs_mbx = val;
  1551					val = ICE_MBX_OVERFLOW_WATERMARK;
  1552					data.async_watermark_val = val;
  1553					data.num_msg_proc = i;
  1554					data.num_pending_arq = pending;
  1555	
  1556					ice_vc_process_vf_msg(pf, &event, &data);
  1557				}
  1558				break;
  1559			case ice_aqc_opc_fw_logs_event:
  1560				ice_get_fwlog_data(pf, &event);
  1561				break;
  1562			case ice_aqc_opc_lldp_set_mib_change:
  1563				ice_dcb_process_lldp_set_mib_change(pf, &event);
  1564				break;
  1565			default:
  1566				dev_dbg(dev, "%s Receive Queue unknown event 0x%04x ignored\n",
  1567					qtype, opcode);
  1568				break;
  1569			}
  1570		} while (pending && (i++ < ICE_DFLT_IRQ_WORK));
  1571	
  1572		kfree(event.msg_buf);
  1573	
  1574		return pending && (i == ICE_DFLT_IRQ_WORK);
  1575	}
  1576	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Intel-wired-lan] [PATCH iwl-next v3] ice: add E830 HW VF mailbox message limit support
  2024-08-12 22:15 [Intel-wired-lan] [PATCH iwl-next v3] ice: add E830 HW VF mailbox message limit support Paul Greenwalt
  2024-08-14 14:51 ` kernel test robot
@ 2024-08-15  7:58 ` Paul Menzel
  2024-08-19 20:59   ` Greenwalt, Paul
  1 sibling, 1 reply; 4+ messages in thread
From: Paul Menzel @ 2024-08-15  7:58 UTC (permalink / raw)
  To: Paul Greenwalt; +Cc: aleksander.lobakin, intel-wired-lan

Dear Paul,


Thank you for the patch.

Am 13.08.24 um 00:15 schrieb Paul Greenwalt:
> E830 adds hardware support to prevent the VF from overflowing the PF
> mailbox with VIRTCHNL messages. E830 will use the hardware feature
> (ICE_F_MBX_LIMIT) instead of the software solution ice_is_malicious_vf().

What is the benefit? Less CPU cycles used? Any measurements, how much 
CPU it uses?

> To prevent a VF from overflowing the PF, the PF sets the number of
> messages per VF that can be in the PF's mailbox queue
> (ICE_MBX_OVERFLOW_WATERMARK). When the PF process a message from a VF,

process*es*?

> the PF decrements the per VF message count using the E830_MBX_VF_DEC_TRIG
> register.

Is there an error shown, once such a malicious situation occurs?

It’d be great, if you could documents ways how to test this.


Kind regards,

Paul


> Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
> ---
> v1 -> v2:
> - Update ice_mbx_vf_dec_trig_e830 and ice_mbx_vf_clear_cnt_e830 onstack
>    variables to const
> v2 -> v3:
> - Fix indentation and remove unnessary paranthes in macro
> - Replace ice_init_feature_support() E830 device id check with MAC
>    check
> - Remove use of const for scalars
> ---
>   drivers/net/ethernet/intel/ice/ice.h          |  1 +
>   .../net/ethernet/intel/ice/ice_hw_autogen.h   |  3 ++
>   drivers/net/ethernet/intel/ice/ice_lib.c      | 15 +++++++++
>   drivers/net/ethernet/intel/ice/ice_main.c     | 24 ++++++++++----
>   drivers/net/ethernet/intel/ice/ice_sriov.c    |  3 +-
>   drivers/net/ethernet/intel/ice/ice_vf_lib.c   | 26 +++++++++++++--
>   drivers/net/ethernet/intel/ice/ice_vf_mbx.c   | 32 +++++++++++++++++++
>   drivers/net/ethernet/intel/ice/ice_vf_mbx.h   |  3 ++
>   drivers/net/ethernet/intel/ice/ice_virtchnl.c |  8 +++--
>   9 files changed, 102 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
> index d6f80da30dec..53082b619fc3 100644
> --- a/drivers/net/ethernet/intel/ice/ice.h
> +++ b/drivers/net/ethernet/intel/ice/ice.h
> @@ -207,6 +207,7 @@ enum ice_feature {
>   	ICE_F_GNSS,
>   	ICE_F_ROCE_LAG,
>   	ICE_F_SRIOV_LAG,
> +	ICE_F_MBX_LIMIT,
>   	ICE_F_MAX
>   };
>   
> diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
> index 91cbae1eec89..8d31bfe28cc8 100644
> --- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
> +++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
> @@ -539,5 +539,8 @@
>   #define E830_PRTMAC_CL01_QNT_THR_CL0_M		GENMASK(15, 0)
>   #define VFINT_DYN_CTLN(_i)			(0x00003800 + ((_i) * 4))
>   #define VFINT_DYN_CTLN_CLEARPBA_M		BIT(1)
> +#define E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH	0x00234000
> +#define E830_MBX_VF_DEC_TRIG(_VF)		(0x00233800 + (_VF) * 4)
> +#define E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(_VF)	(0x00233000 + (_VF) * 4)
>   
>   #endif /* _ICE_HW_AUTOGEN_H_ */
> diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
> index d9c34d28c9cd..2c55209d3ce2 100644
> --- a/drivers/net/ethernet/intel/ice/ice_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_lib.c
> @@ -3877,9 +3877,24 @@ void ice_init_feature_support(struct ice_pf *pf)
>   		if (ice_gnss_is_gps_present(&pf->hw))
>   			ice_set_feature_support(pf, ICE_F_GNSS);
>   		break;
> +	case ICE_DEV_ID_E830CC_BACKPLANE:
> +	case ICE_DEV_ID_E830CC_QSFP56:
> +	case ICE_DEV_ID_E830CC_SFP:
> +	case ICE_DEV_ID_E830CC_SFP_DD:
> +	case ICE_DEV_ID_E830C_BACKPLANE:
> +	case ICE_DEV_ID_E830C_QSFP:
> +	case ICE_DEV_ID_E830C_SFP:
> +	case ICE_DEV_ID_E830_XXV_BACKPLANE:
> +	case ICE_DEV_ID_E830_XXV_QSFP:
> +	case ICE_DEV_ID_E830_XXV_SFP:
> +		ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
> +		break;
>   	default:
>   		break;
>   	}
> +
> +	if (pf->hw.mac_type == ICE_MAC_E830)
> +		ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
>   }
>   
>   /**
> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
> index fd27c7995d60..12ce5d2283d3 100644
> --- a/drivers/net/ethernet/intel/ice/ice_main.c
> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
> @@ -1542,12 +1542,20 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
>   			ice_vf_lan_overflow_event(pf, &event);
>   			break;
>   		case ice_mbx_opc_send_msg_to_pf:
> -			data.num_msg_proc = i;
> -			data.num_pending_arq = pending;
> -			data.max_num_msgs_mbx = hw->mailboxq.num_rq_entries;
> -			data.async_watermark_val = ICE_MBX_OVERFLOW_WATERMARK;
> +			if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) {
> +				ice_vc_process_vf_msg(pf, &event, NULL);
> +				ice_mbx_vf_dec_trig_e830(hw, &event);
> +			} else {
> +				u16 val = hw->mailboxq.num_rq_entries;
> +
> +				data.max_num_msgs_mbx = val;
> +				val = ICE_MBX_OVERFLOW_WATERMARK;
> +				data.async_watermark_val = val;
> +				data.num_msg_proc = i;
> +				data.num_pending_arq = pending;
>   
> -			ice_vc_process_vf_msg(pf, &event, &data);
> +				ice_vc_process_vf_msg(pf, &event, &data);
> +			}
>   			break;
>   		case ice_aqc_opc_fw_logs_event:
>   			ice_get_fwlog_data(pf, &event);
> @@ -4078,7 +4086,11 @@ static int ice_init_pf(struct ice_pf *pf)
>   
>   	mutex_init(&pf->vfs.table_lock);
>   	hash_init(pf->vfs.table);
> -	ice_mbx_init_snapshot(&pf->hw);
> +	if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
> +		wr32(&pf->hw, E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH,
> +		     ICE_MBX_OVERFLOW_WATERMARK);
> +	else
> +		ice_mbx_init_snapshot(&pf->hw);
>   
>   	xa_init(&pf->dyn_ports);
>   	xa_init(&pf->sf_nums);
> diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c
> index e34fe2516ccc..e7b5fe553d1f 100644
> --- a/drivers/net/ethernet/intel/ice/ice_sriov.c
> +++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
> @@ -194,7 +194,8 @@ void ice_free_vfs(struct ice_pf *pf)
>   		}
>   
>   		/* clear malicious info since the VF is getting released */
> -		list_del(&vf->mbx_info.list_entry);
> +		if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
> +			list_del(&vf->mbx_info.list_entry);
>   
>   		mutex_unlock(&vf->cfg_lock);
>   	}
> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> index a69e91f88d81..d618292dfe27 100644
> --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> @@ -709,6 +709,23 @@ ice_vf_clear_vsi_promisc(struct ice_vf *vf, struct ice_vsi *vsi, u8 promisc_m)
>   	return 0;
>   }
>   
> +/**
> + * ice_reset_vf_mbx_cnt - reset VF mailbox message count
> + * @vf: pointer to the VF structure
> + *
> + * This function clears the VF mailbox message count, and should be called on
> + * VF reset.
> + */
> +static void ice_reset_vf_mbx_cnt(struct ice_vf *vf)
> +{
> +	struct ice_pf *pf = vf->pf;
> +
> +	if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
> +		ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
> +	else
> +		ice_mbx_clear_malvf(&vf->mbx_info);
> +}
> +
>   /**
>    * ice_reset_all_vfs - reset all allocated VFs in one go
>    * @pf: pointer to the PF structure
> @@ -735,7 +752,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)
>   
>   	/* clear all malicious info if the VFs are getting reset */
>   	ice_for_each_vf(pf, bkt, vf)
> -		ice_mbx_clear_malvf(&vf->mbx_info);
> +		ice_reset_vf_mbx_cnt(vf);
>   
>   	/* If VFs have been disabled, there is no need to reset */
>   	if (test_and_set_bit(ICE_VF_DIS, pf->state)) {
> @@ -951,7 +968,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
>   	ice_eswitch_update_repr(&vf->repr_id, vsi);
>   
>   	/* if the VF has been reset allow it to come up again */
> -	ice_mbx_clear_malvf(&vf->mbx_info);
> +	ice_reset_vf_mbx_cnt(vf);
>   
>   out_unlock:
>   	if (lag && lag->bonded && lag->primary &&
> @@ -1004,7 +1021,10 @@ void ice_initialize_vf_entry(struct ice_vf *vf)
>   	ice_vf_fdir_init(vf);
>   
>   	/* Initialize mailbox info for this VF */
> -	ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
> +	if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
> +		ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
> +	else
> +		ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
>   
>   	mutex_init(&vf->cfg_lock);
>   }
> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
> index 40cb4ba0789c..75c8113e58ee 100644
> --- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
> +++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
> @@ -210,6 +210,38 @@ ice_mbx_detect_malvf(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info,
>   	return 0;
>   }
>   
> +/**
> + * ice_mbx_vf_dec_trig_e830 - Decrements the VF mailbox queue counter
> + * @hw: pointer to the HW struct
> + * @event: pointer to the control queue receive event
> + *
> + * This function triggers to decrement the counter
> + * MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT when the driver replenishes
> + * the buffers at the PF mailbox queue.
> + */
> +void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
> +			      const struct ice_rq_event_info *event)
> +{
> +	u16 vfid = le16_to_cpu(event->desc.retval);
> +
> +	wr32(hw, E830_MBX_VF_DEC_TRIG(vfid), 1);
> +}
> +
> +/**
> + * ice_mbx_vf_clear_cnt_e830 - Clear the VF mailbox queue count
> + * @hw: pointer to the HW struct
> + * @vf_id: VF ID in the PF space
> + *
> + * This function clears the counter MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT, and should
> + * be called when a VF is created and on VF reset.
> + */
> +void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id)
> +{
> +	u32 reg = rd32(hw, E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(vf_id));
> +
> +	wr32(hw, E830_MBX_VF_DEC_TRIG(vf_id), reg);
> +}
> +
>   /**
>    * ice_mbx_vf_state_handler - Handle states of the overflow algorithm
>    * @hw: pointer to the HW struct
> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
> index 44bc030d17e0..edcd9332368c 100644
> --- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
> +++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
> @@ -19,6 +19,9 @@ ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,
>   		      u8 *msg, u16 msglen, struct ice_sq_cd *cd);
>   
>   u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed);
> +void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
> +			      const struct ice_rq_event_info *event);
> +void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id);
>   int
>   ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data,
>   			 struct ice_mbx_vf_info *vf_info, bool *report_malvf);
> diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> index 59f62306b9cb..3c86d0c2fe1f 100644
> --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
> @@ -4009,8 +4009,10 @@ ice_is_malicious_vf(struct ice_vf *vf, struct ice_mbx_data *mbxdata)
>    * @event: pointer to the AQ event
>    * @mbxdata: information used to detect VF attempting mailbox overflow
>    *
> - * called from the common asq/arq handler to
> - * process request from VF
> + * Called from the common asq/arq handler to process request from VF. When this
> + * flow is used for devices with hardware VF to PF message queue overflow
> + * support (ICE_F_MBX_LIMIT) mbxdata is set to NULL and ice_is_malicious_vf
> + * check is skipped.
>    */
>   void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event,
>   			   struct ice_mbx_data *mbxdata)
> @@ -4036,7 +4038,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event,
>   	mutex_lock(&vf->cfg_lock);
>   
>   	/* Check if the VF is trying to overflow the mailbox */
> -	if (ice_is_malicious_vf(vf, mbxdata))
> +	if (mbxdata && ice_is_malicious_vf(vf, mbxdata))
>   		goto finish;
>   
>   	/* Check if VF is disabled. */

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Intel-wired-lan] [PATCH iwl-next v3] ice: add E830 HW VF mailbox message limit support
  2024-08-15  7:58 ` Paul Menzel
@ 2024-08-19 20:59   ` Greenwalt, Paul
  0 siblings, 0 replies; 4+ messages in thread
From: Greenwalt, Paul @ 2024-08-19 20:59 UTC (permalink / raw)
  To: Paul Menzel; +Cc: aleksander.lobakin, intel-wired-lan



On 8/15/2024 12:58 AM, Paul Menzel wrote:
> Dear Paul,
> 
> 
> Thank you for the patch.
> 
> Am 13.08.24 um 00:15 schrieb Paul Greenwalt:
>> E830 adds hardware support to prevent the VF from overflowing the PF
>> mailbox with VIRTCHNL messages. E830 will use the hardware feature
>> (ICE_F_MBX_LIMIT) instead of the software solution ice_is_malicious_vf().
> 
> What is the benefit? Less CPU cycles used? Any measurements, how much
> CPU it uses?
> 

The hardware solution reduces complexity in the driver, and it’s more
robust than the software solution. The software solution will detect and
log when the VFs outstanding messages to a PF exceeds the threshold. The
hardware solution blocks the messages from the VF to the PF when the
threshold is exceeded.

>> To prevent a VF from overflowing the PF, the PF sets the number of
>> messages per VF that can be in the PF's mailbox queue
>> (ICE_MBX_OVERFLOW_WATERMARK). When the PF process a message from a VF,
> 
> process*es*?
> 

I will make this change in the commit message.

>> the PF decrements the per VF message count using the E830_MBX_VF_DEC_TRIG
>> register.
> 
> Is there an error shown, once such a malicious situation occurs?
> 

There is no PF error message when the hardware blocks the VF messages,
but the VF will generate messages related to the failed communication
with the PF.

> It’d be great, if you could documents ways how to test this.
> 

It’s difficult to reproduce this issue since this is unlikely to occur
under normal circumstances.

Thanks,
Paul

> 
> Kind regards,
> 
> Paul
> 
> 
>> Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
>> ---
>> v1 -> v2:
>> - Update ice_mbx_vf_dec_trig_e830 and ice_mbx_vf_clear_cnt_e830 onstack
>>    variables to const
>> v2 -> v3:
>> - Fix indentation and remove unnessary paranthes in macro
>> - Replace ice_init_feature_support() E830 device id check with MAC
>>    check
>> - Remove use of const for scalars
>> ---
>>   drivers/net/ethernet/intel/ice/ice.h          |  1 +
>>   .../net/ethernet/intel/ice/ice_hw_autogen.h   |  3 ++
>>   drivers/net/ethernet/intel/ice/ice_lib.c      | 15 +++++++++
>>   drivers/net/ethernet/intel/ice/ice_main.c     | 24 ++++++++++----
>>   drivers/net/ethernet/intel/ice/ice_sriov.c    |  3 +-
>>   drivers/net/ethernet/intel/ice/ice_vf_lib.c   | 26 +++++++++++++--
>>   drivers/net/ethernet/intel/ice/ice_vf_mbx.c   | 32 +++++++++++++++++++
>>   drivers/net/ethernet/intel/ice/ice_vf_mbx.h   |  3 ++
>>   drivers/net/ethernet/intel/ice/ice_virtchnl.c |  8 +++--
>>   9 files changed, 102 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/intel/ice/ice.h
>> b/drivers/net/ethernet/intel/ice/ice.h
>> index d6f80da30dec..53082b619fc3 100644
>> --- a/drivers/net/ethernet/intel/ice/ice.h
>> +++ b/drivers/net/ethernet/intel/ice/ice.h
>> @@ -207,6 +207,7 @@ enum ice_feature {
>>       ICE_F_GNSS,
>>       ICE_F_ROCE_LAG,
>>       ICE_F_SRIOV_LAG,
>> +    ICE_F_MBX_LIMIT,
>>       ICE_F_MAX
>>   };
>>   diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
>> b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
>> index 91cbae1eec89..8d31bfe28cc8 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
>> +++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
>> @@ -539,5 +539,8 @@
>>   #define E830_PRTMAC_CL01_QNT_THR_CL0_M        GENMASK(15, 0)
>>   #define VFINT_DYN_CTLN(_i)            (0x00003800 + ((_i) * 4))
>>   #define VFINT_DYN_CTLN_CLEARPBA_M        BIT(1)
>> +#define E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH    0x00234000
>> +#define E830_MBX_VF_DEC_TRIG(_VF)        (0x00233800 + (_VF) * 4)
>> +#define E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(_VF)    (0x00233000 +
>> (_VF) * 4)
>>     #endif /* _ICE_HW_AUTOGEN_H_ */
>> diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c
>> b/drivers/net/ethernet/intel/ice/ice_lib.c
>> index d9c34d28c9cd..2c55209d3ce2 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_lib.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_lib.c
>> @@ -3877,9 +3877,24 @@ void ice_init_feature_support(struct ice_pf *pf)
>>           if (ice_gnss_is_gps_present(&pf->hw))
>>               ice_set_feature_support(pf, ICE_F_GNSS);
>>           break;
>> +    case ICE_DEV_ID_E830CC_BACKPLANE:
>> +    case ICE_DEV_ID_E830CC_QSFP56:
>> +    case ICE_DEV_ID_E830CC_SFP:
>> +    case ICE_DEV_ID_E830CC_SFP_DD:
>> +    case ICE_DEV_ID_E830C_BACKPLANE:
>> +    case ICE_DEV_ID_E830C_QSFP:
>> +    case ICE_DEV_ID_E830C_SFP:
>> +    case ICE_DEV_ID_E830_XXV_BACKPLANE:
>> +    case ICE_DEV_ID_E830_XXV_QSFP:
>> +    case ICE_DEV_ID_E830_XXV_SFP:
>> +        ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
>> +        break;
>>       default:
>>           break;
>>       }
>> +
>> +    if (pf->hw.mac_type == ICE_MAC_E830)
>> +        ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
>>   }
>>     /**
>> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c
>> b/drivers/net/ethernet/intel/ice/ice_main.c
>> index fd27c7995d60..12ce5d2283d3 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_main.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
>> @@ -1542,12 +1542,20 @@ static int __ice_clean_ctrlq(struct ice_pf
>> *pf, enum ice_ctl_q q_type)
>>               ice_vf_lan_overflow_event(pf, &event);
>>               break;
>>           case ice_mbx_opc_send_msg_to_pf:
>> -            data.num_msg_proc = i;
>> -            data.num_pending_arq = pending;
>> -            data.max_num_msgs_mbx = hw->mailboxq.num_rq_entries;
>> -            data.async_watermark_val = ICE_MBX_OVERFLOW_WATERMARK;
>> +            if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT)) {
>> +                ice_vc_process_vf_msg(pf, &event, NULL);
>> +                ice_mbx_vf_dec_trig_e830(hw, &event);
>> +            } else {
>> +                u16 val = hw->mailboxq.num_rq_entries;
>> +
>> +                data.max_num_msgs_mbx = val;
>> +                val = ICE_MBX_OVERFLOW_WATERMARK;
>> +                data.async_watermark_val = val;
>> +                data.num_msg_proc = i;
>> +                data.num_pending_arq = pending;
>>   -            ice_vc_process_vf_msg(pf, &event, &data);
>> +                ice_vc_process_vf_msg(pf, &event, &data);
>> +            }
>>               break;
>>           case ice_aqc_opc_fw_logs_event:
>>               ice_get_fwlog_data(pf, &event);
>> @@ -4078,7 +4086,11 @@ static int ice_init_pf(struct ice_pf *pf)
>>         mutex_init(&pf->vfs.table_lock);
>>       hash_init(pf->vfs.table);
>> -    ice_mbx_init_snapshot(&pf->hw);
>> +    if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
>> +        wr32(&pf->hw, E830_MBX_PF_IN_FLIGHT_VF_MSGS_THRESH,
>> +             ICE_MBX_OVERFLOW_WATERMARK);
>> +    else
>> +        ice_mbx_init_snapshot(&pf->hw);
>>         xa_init(&pf->dyn_ports);
>>       xa_init(&pf->sf_nums);
>> diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c
>> b/drivers/net/ethernet/intel/ice/ice_sriov.c
>> index e34fe2516ccc..e7b5fe553d1f 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_sriov.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_sriov.c
>> @@ -194,7 +194,8 @@ void ice_free_vfs(struct ice_pf *pf)
>>           }
>>             /* clear malicious info since the VF is getting released */
>> -        list_del(&vf->mbx_info.list_entry);
>> +        if (!ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
>> +            list_del(&vf->mbx_info.list_entry);
>>             mutex_unlock(&vf->cfg_lock);
>>       }
>> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
>> b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
>> index a69e91f88d81..d618292dfe27 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
>> @@ -709,6 +709,23 @@ ice_vf_clear_vsi_promisc(struct ice_vf *vf,
>> struct ice_vsi *vsi, u8 promisc_m)
>>       return 0;
>>   }
>>   +/**
>> + * ice_reset_vf_mbx_cnt - reset VF mailbox message count
>> + * @vf: pointer to the VF structure
>> + *
>> + * This function clears the VF mailbox message count, and should be
>> called on
>> + * VF reset.
>> + */
>> +static void ice_reset_vf_mbx_cnt(struct ice_vf *vf)
>> +{
>> +    struct ice_pf *pf = vf->pf;
>> +
>> +    if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
>> +        ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
>> +    else
>> +        ice_mbx_clear_malvf(&vf->mbx_info);
>> +}
>> +
>>   /**
>>    * ice_reset_all_vfs - reset all allocated VFs in one go
>>    * @pf: pointer to the PF structure
>> @@ -735,7 +752,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)
>>         /* clear all malicious info if the VFs are getting reset */
>>       ice_for_each_vf(pf, bkt, vf)
>> -        ice_mbx_clear_malvf(&vf->mbx_info);
>> +        ice_reset_vf_mbx_cnt(vf);
>>         /* If VFs have been disabled, there is no need to reset */
>>       if (test_and_set_bit(ICE_VF_DIS, pf->state)) {
>> @@ -951,7 +968,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
>>       ice_eswitch_update_repr(&vf->repr_id, vsi);
>>         /* if the VF has been reset allow it to come up again */
>> -    ice_mbx_clear_malvf(&vf->mbx_info);
>> +    ice_reset_vf_mbx_cnt(vf);
>>     out_unlock:
>>       if (lag && lag->bonded && lag->primary &&
>> @@ -1004,7 +1021,10 @@ void ice_initialize_vf_entry(struct ice_vf *vf)
>>       ice_vf_fdir_init(vf);
>>         /* Initialize mailbox info for this VF */
>> -    ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
>> +    if (ice_is_feature_supported(pf, ICE_F_MBX_LIMIT))
>> +        ice_mbx_vf_clear_cnt_e830(&pf->hw, vf->vf_id);
>> +    else
>> +        ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
>>         mutex_init(&vf->cfg_lock);
>>   }
>> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
>> b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
>> index 40cb4ba0789c..75c8113e58ee 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.c
>> @@ -210,6 +210,38 @@ ice_mbx_detect_malvf(struct ice_hw *hw, struct
>> ice_mbx_vf_info *vf_info,
>>       return 0;
>>   }
>>   +/**
>> + * ice_mbx_vf_dec_trig_e830 - Decrements the VF mailbox queue counter
>> + * @hw: pointer to the HW struct
>> + * @event: pointer to the control queue receive event
>> + *
>> + * This function triggers to decrement the counter
>> + * MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT when the driver replenishes
>> + * the buffers at the PF mailbox queue.
>> + */
>> +void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
>> +                  const struct ice_rq_event_info *event)
>> +{
>> +    u16 vfid = le16_to_cpu(event->desc.retval);
>> +
>> +    wr32(hw, E830_MBX_VF_DEC_TRIG(vfid), 1);
>> +}
>> +
>> +/**
>> + * ice_mbx_vf_clear_cnt_e830 - Clear the VF mailbox queue count
>> + * @hw: pointer to the HW struct
>> + * @vf_id: VF ID in the PF space
>> + *
>> + * This function clears the counter MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT,
>> and should
>> + * be called when a VF is created and on VF reset.
>> + */
>> +void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id)
>> +{
>> +    u32 reg = rd32(hw, E830_MBX_VF_IN_FLIGHT_MSGS_AT_PF_CNT(vf_id));
>> +
>> +    wr32(hw, E830_MBX_VF_DEC_TRIG(vf_id), reg);
>> +}
>> +
>>   /**
>>    * ice_mbx_vf_state_handler - Handle states of the overflow algorithm
>>    * @hw: pointer to the HW struct
>> diff --git a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
>> b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
>> index 44bc030d17e0..edcd9332368c 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
>> +++ b/drivers/net/ethernet/intel/ice/ice_vf_mbx.h
>> @@ -19,6 +19,9 @@ ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid,
>> u32 v_opcode, u32 v_retval,
>>                 u8 *msg, u16 msglen, struct ice_sq_cd *cd);
>>     u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16
>> link_speed);
>> +void ice_mbx_vf_dec_trig_e830(const struct ice_hw *hw,
>> +                  const struct ice_rq_event_info *event);
>> +void ice_mbx_vf_clear_cnt_e830(const struct ice_hw *hw, u16 vf_id);
>>   int
>>   ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data
>> *mbx_data,
>>                struct ice_mbx_vf_info *vf_info, bool *report_malvf);
>> diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
>> b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
>> index 59f62306b9cb..3c86d0c2fe1f 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
>> @@ -4009,8 +4009,10 @@ ice_is_malicious_vf(struct ice_vf *vf, struct
>> ice_mbx_data *mbxdata)
>>    * @event: pointer to the AQ event
>>    * @mbxdata: information used to detect VF attempting mailbox overflow
>>    *
>> - * called from the common asq/arq handler to
>> - * process request from VF
>> + * Called from the common asq/arq handler to process request from VF.
>> When this
>> + * flow is used for devices with hardware VF to PF message queue
>> overflow
>> + * support (ICE_F_MBX_LIMIT) mbxdata is set to NULL and
>> ice_is_malicious_vf
>> + * check is skipped.
>>    */
>>   void ice_vc_process_vf_msg(struct ice_pf *pf, struct
>> ice_rq_event_info *event,
>>                  struct ice_mbx_data *mbxdata)
>> @@ -4036,7 +4038,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf,
>> struct ice_rq_event_info *event,
>>       mutex_lock(&vf->cfg_lock);
>>         /* Check if the VF is trying to overflow the mailbox */
>> -    if (ice_is_malicious_vf(vf, mbxdata))
>> +    if (mbxdata && ice_is_malicious_vf(vf, mbxdata))
>>           goto finish;
>>         /* Check if VF is disabled. */

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-08-19 20:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-12 22:15 [Intel-wired-lan] [PATCH iwl-next v3] ice: add E830 HW VF mailbox message limit support Paul Greenwalt
2024-08-14 14:51 ` kernel test robot
2024-08-15  7:58 ` Paul Menzel
2024-08-19 20:59   ` Greenwalt, Paul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox