* [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