@@ -31,7 +31,7 @@
#define IAVF_NUM_MACADDR_MAX 64
-#define IAVF_DEV_WATCHDOG_PERIOD 0
+#define IAVF_DEV_WATCHDOG_PERIOD 2000 /* microseconds, set 0 to disable*/
#define IAVF_DEFAULT_RX_PTHRESH 8
#define IAVF_DEFAULT_RX_HTHRESH 8
@@ -304,6 +304,7 @@ struct iavf_devargs {
uint8_t proto_xtr_dflt;
uint8_t proto_xtr[IAVF_MAX_QUEUE_NUM];
uint16_t quanta_size;
+ uint32_t watchdog_period;
};
struct iavf_security_ctx;
@@ -498,4 +499,6 @@ int iavf_flow_unsub(struct iavf_adapter *adapter,
struct iavf_fsub_conf *filter);
int iavf_flow_sub_check(struct iavf_adapter *adapter,
struct iavf_fsub_conf *filter);
+void iavf_dev_watchdog_enable(struct iavf_adapter *adapter);
+void iavf_dev_watchdog_disable(struct iavf_adapter *adapter);
#endif /* _IAVF_ETHDEV_H_ */
@@ -36,6 +36,7 @@
/* devargs */
#define IAVF_PROTO_XTR_ARG "proto_xtr"
#define IAVF_QUANTA_SIZE_ARG "quanta_size"
+#define IAVF_RESET_WATCHDOG_ARG "watchdog_period"
uint64_t iavf_timestamp_dynflag;
int iavf_timestamp_dynfield_offset = -1;
@@ -43,6 +44,7 @@ int iavf_timestamp_dynfield_offset = -1;
static const char * const iavf_valid_args[] = {
IAVF_PROTO_XTR_ARG,
IAVF_QUANTA_SIZE_ARG,
+ IAVF_RESET_WATCHDOG_ARG,
NULL
};
@@ -301,40 +303,46 @@ iavf_dev_watchdog(void *cb_arg)
/* enter reset state with VFLR event */
adapter->vf.vf_reset = true;
+ adapter->vf.link_up = false;
rte_eth_dev_callback_process(adapter->vf.eth_dev,
RTE_ETH_EVENT_INTR_RESET, NULL);
}
}
- /* re-alarm watchdog */
- rc = rte_eal_alarm_set(IAVF_DEV_WATCHDOG_PERIOD,
- &iavf_dev_watchdog, cb_arg);
+ if (adapter->devargs.watchdog_period) {
+ /* re-alarm watchdog */
+ rc = rte_eal_alarm_set(adapter->devargs.watchdog_period,
+ &iavf_dev_watchdog, cb_arg);
- if (rc)
- PMD_DRV_LOG(ERR, "Failed \"%s\" to reset device watchdog alarm",
- adapter->vf.eth_dev->data->name);
+ if (rc)
+ PMD_DRV_LOG(ERR, "Failed \"%s\" to reset device watchdog alarm",
+ adapter->vf.eth_dev->data->name);
+ }
}
-static void
-iavf_dev_watchdog_enable(struct iavf_adapter *adapter __rte_unused)
-{
-#if (IAVF_DEV_WATCHDOG_PERIOD > 0)
- PMD_DRV_LOG(INFO, "Enabling device watchdog");
- adapter->vf.watchdog_enabled = true;
- if (rte_eal_alarm_set(IAVF_DEV_WATCHDOG_PERIOD,
- &iavf_dev_watchdog, (void *)adapter))
- PMD_DRV_LOG(ERR, "Failed to enabled device watchdog");
-#endif
+void
+iavf_dev_watchdog_enable(struct iavf_adapter *adapter)
+{
+ if (adapter->devargs.watchdog_period && !adapter->vf.watchdog_enabled) {
+ PMD_DRV_LOG(INFO, "Enabling device watchdog, period is %dμs",
+ adapter->devargs.watchdog_period);
+ adapter->vf.watchdog_enabled = true;
+ if (rte_eal_alarm_set(adapter->devargs.watchdog_period,
+ &iavf_dev_watchdog, (void *)adapter))
+ PMD_DRV_LOG(ERR, "Failed to enabled device watchdog");
+ } else {
+ PMD_DRV_LOG(INFO, "Device watchdog is disabled");
+ }
}
-static void
-iavf_dev_watchdog_disable(struct iavf_adapter *adapter __rte_unused)
+void
+iavf_dev_watchdog_disable(struct iavf_adapter *adapter)
{
-#if (IAVF_DEV_WATCHDOG_PERIOD > 0)
- PMD_DRV_LOG(INFO, "Disabling device watchdog");
- adapter->vf.watchdog_enabled = false;
-#endif
+ if (adapter->devargs.watchdog_period && adapter->vf.watchdog_enabled) {
+ PMD_DRV_LOG(INFO, "Disabling device watchdog");
+ adapter->vf.watchdog_enabled = false;
+ }
}
static int
@@ -2201,6 +2209,25 @@ parse_u16(__rte_unused const char *key, const char *value, void *args)
return 0;
}
+static int
+iavf_parse_watchdog_period(__rte_unused const char *key, const char *value, void *args)
+{
+ int *num = (int *)args;
+ int tmp;
+
+ errno = 0;
+ tmp = atoi(value);
+ if (tmp < 0) {
+ PMD_DRV_LOG(WARNING, "%s: \"%s\" is not greater than or equal to zero",
+ key, value);
+ return -1;
+ }
+
+ *num = tmp;
+
+ return 0;
+}
+
static int iavf_parse_devargs(struct rte_eth_dev *dev)
{
struct iavf_adapter *ad =
@@ -2208,6 +2235,7 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev)
struct rte_devargs *devargs = dev->device->devargs;
struct rte_kvargs *kvlist;
int ret;
+ int watchdog_period = -1;
if (!devargs)
return 0;
@@ -2232,6 +2260,15 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev)
if (ret)
goto bail;
+ ret = rte_kvargs_process(kvlist, IAVF_RESET_WATCHDOG_ARG,
+ &iavf_parse_watchdog_period, &watchdog_period);
+ if (ret)
+ goto bail;
+ if (watchdog_period == -1)
+ ad->devargs.watchdog_period = IAVF_DEV_WATCHDOG_PERIOD;
+ else
+ ad->devargs.watchdog_period = watchdog_period;
+
if (ad->devargs.quanta_size != 0 &&
(ad->devargs.quanta_size < 256 || ad->devargs.quanta_size > 4096 ||
ad->devargs.quanta_size & 0x40)) {
@@ -256,6 +256,12 @@ iavf_read_msg_from_pf(struct iavf_adapter *adapter, uint16_t buf_len,
vf->link_speed = iavf_convert_link_speed(speed);
}
iavf_dev_link_update(vf->eth_dev, 0);
+ if (vf->link_up && !vf->vf_reset) {
+ iavf_dev_watchdog_disable(adapter);
+ } else {
+ if (!vf->link_up)
+ iavf_dev_watchdog_enable(adapter);
+ }
PMD_DRV_LOG(INFO, "Link status update:%s",
vf->link_up ? "up" : "down");
break;
@@ -433,9 +439,12 @@ iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg,
switch (pf_msg->event) {
case VIRTCHNL_EVENT_RESET_IMPENDING:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
- vf->vf_reset = true;
- iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_RESET,
- NULL, 0);
+ vf->link_up = false;
+ if (!vf->vf_reset) {
+ vf->vf_reset = true;
+ iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_RESET,
+ NULL, 0);
+ }
break;
case VIRTCHNL_EVENT_LINK_CHANGE:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
@@ -449,6 +458,12 @@ iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg,
vf->link_speed = iavf_convert_link_speed(speed);
}
iavf_dev_link_update(dev, 0);
+ if (vf->link_up && !vf->vf_reset) {
+ iavf_dev_watchdog_disable(adapter);
+ } else {
+ if (!vf->link_up)
+ iavf_dev_watchdog_enable(adapter);
+ }
iavf_dev_event_post(dev, RTE_ETH_EVENT_INTR_LSC, NULL, 0);
break;
case VIRTCHNL_EVENT_PF_DRIVER_CLOSE: